Statistics
| Revision:

root / trunk / libraries / libDwg / src / com / iver / cit / jdwglib / dwg / readers / DwgFileV15Reader.java @ 9843

History | View | Annotate | Download (14.9 KB)

1
/* jdwglib. Java Library for reading Dwg files.
2
 * 
3
 * Author: Jose Morell Rama (jose.morell@gmail.com).
4
 * Port from the Pythoncad Dwg library by Art Haas.
5
 *
6
 * Copyright (C) 2005 Jose Morell, IVER TI S.A. and Generalitat Valenciana
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 * Jose Morell (jose.morell@gmail.com)
25
 * 
26
 * or
27
 *
28
 * IVER TI S.A.
29
 *  C/Salamanca, 50
30
 *  46005 Valencia
31
 *  Spain
32
 *  +34 963163400
33
 *  dac@iver.es
34
 */
35
package com.iver.cit.jdwglib.dwg.readers;
36

    
37
import java.io.IOException;
38
import java.nio.ByteBuffer;
39
import java.nio.ByteOrder;
40
import java.util.ArrayList;
41

    
42
import com.iver.cit.gvsig.fmap.drivers.dgn.ByteUtils;
43
import com.iver.cit.jdwglib.dwg.DwgFile;
44
import com.iver.cit.jdwglib.dwg.DwgObject;
45
import com.iver.cit.jdwglib.dwg.DwgObjectFactory;
46
import com.iver.cit.jdwglib.dwg.DwgObjectOffset;
47
import com.iver.cit.jdwglib.dwg.DwgUtil;
48
import com.iver.cit.jdwglib.dwg.objects.DwgArc;
49
import com.iver.cit.jdwglib.dwg.objects.DwgAttdef;
50
import com.iver.cit.jdwglib.dwg.objects.DwgAttrib;
51
import com.iver.cit.jdwglib.dwg.objects.DwgBlock;
52
import com.iver.cit.jdwglib.dwg.objects.DwgBlockControl;
53
import com.iver.cit.jdwglib.dwg.objects.DwgBlockHeader;
54
import com.iver.cit.jdwglib.dwg.objects.DwgCircle;
55
import com.iver.cit.jdwglib.dwg.objects.DwgEllipse;
56
import com.iver.cit.jdwglib.dwg.objects.DwgEndblk;
57
import com.iver.cit.jdwglib.dwg.objects.DwgInsert;
58
import com.iver.cit.jdwglib.dwg.objects.DwgLayer;
59
import com.iver.cit.jdwglib.dwg.objects.DwgLayerControl;
60
import com.iver.cit.jdwglib.dwg.objects.DwgLine;
61
import com.iver.cit.jdwglib.dwg.objects.DwgLwPolyline;
62
import com.iver.cit.jdwglib.dwg.objects.DwgMText;
63
import com.iver.cit.jdwglib.dwg.objects.DwgPoint;
64
import com.iver.cit.jdwglib.dwg.objects.DwgPolyline2D;
65
import com.iver.cit.jdwglib.dwg.objects.DwgPolyline3D;
66
import com.iver.cit.jdwglib.dwg.objects.DwgSeqend;
67
import com.iver.cit.jdwglib.dwg.objects.DwgSolid;
68
import com.iver.cit.jdwglib.dwg.objects.DwgSpline;
69
import com.iver.cit.jdwglib.dwg.objects.DwgText;
70
import com.iver.cit.jdwglib.dwg.objects.DwgVertex2D;
71
import com.iver.cit.jdwglib.dwg.objects.DwgVertex3D;
72

    
73
import freenet.support.HexUtil;
74

    
75
/**
76
 * The DwgFileV15Reader reads the DWG version 15 format
77
 * 
78
 * @author jmorell
79
 */
80
public class DwgFileV15Reader implements DwgFileReader {
81
        protected DwgFile dwgFile;
82
        protected ByteBuffer bb;
83
        
84
        /**
85
         * Reads the DWG version 15 format
86
         * 
87
         * @param dwgFile Represents the DWG file that we want to read
88
     * @throws IOException When DWG file path is wrong
89
         */
90
        public void read(DwgFile dwgFile, ByteBuffer bb) throws IOException {
91
                this.dwgFile = dwgFile;
92
                this.bb = bb;
93
                
94
                readDwgSectionOffsets();
95
                try {
96
                        readDwgObjectOffsets();                
97
                        //readDwgClasses(bb);
98
                } catch (Exception e) {
99
//                    System.out.println("Error leyendo offsets y classes. Posible corrupci?n en" +
100
//                                    "el DWG file ...");
101
                }
102
                readDwgObjects();
103
        }
104
        
105
        
106
        /**
107
         * It read the SECTIONS from the header of the DWG file
108
         * */
109
        protected void readDwgSectionOffsets() {
110
                bb.position(19);
111
                bb.order(ByteOrder.LITTLE_ENDIAN);
112
                short codePage = bb.getShort();
113
                int count = bb.getInt();
114
                for (int i=0; i<count; i++) {
115
                        byte rec = bb.get();
116
                        int seek = bb.getInt();
117
                        int size = bb.getInt();
118
                        if (rec==0) {
119
                                dwgFile.addDwgSectionOffset("HEADERS", seek, size);
120
                        } else if (rec==1) {
121
                                dwgFile.addDwgSectionOffset("CLASSES", seek, size);
122
                        } else if (rec==2) {
123
                                dwgFile.addDwgSectionOffset("OBJECTS", seek, size);
124
                        } else if (rec==3) {
125
                                dwgFile.addDwgSectionOffset("UNKNOWN", seek, size);
126
                        } else if (rec==4) {
127
                                dwgFile.addDwgSectionOffset("R14DATA", seek, size);
128
                        } else if (rec==5) {
129
                                dwgFile.addDwgSectionOffset("R14REC5", seek, size);
130
                        } else {
131
//                                System.out.println("ERROR: C?digo de n?mero de registro no soportado: " + rec);
132
                        }
133
                }
134
        }
135
        
136
        /**
137
         * OpenDWG spec says:
138
         * This section -object map- is a table which gives the location of
139
         * each object in the DWG file.
140
         * This table is broken into sections. It is basically a list of
141
         * handle/file loc pairs. It could be readed with this pseudocode:
142
         * 
143
         *    Set lastHandle to all 0 and last loc to 0L.
144
         *    Repeat until section size == 2
145
         *                         section size = read short (in bigendian order)
146
         *                         Repeat until out of data for this section
147
         *                                 offset of this handle form last handle as modular char
148
         *                                 offset of location in file from last location as modular char
149
         *                         End repeat
150
         *           End repeat
151
         * 
152
         * */
153
        protected void readDwgObjectOffsets() throws Exception {
154
                int offset = dwgFile.getDwgSectionOffset("OBJECTS");
155
                bb.position(offset);
156
                while (true) {
157
                        bb.order(ByteOrder.BIG_ENDIAN);
158
                        /*
159
                         * We read the size of the next section.
160
                         * If size == 2, break (it is the last empty -except crc- section)
161
                         * */
162
                        short size = bb.getShort();
163
                        if (size==2) 
164
                                break;
165
                        bb.order(ByteOrder.LITTLE_ENDIAN);
166
                        byte[] dataBytes = new byte[size];
167
                        for (int i=0; i<dataBytes.length; i++) {
168
                                dataBytes[i] = bb.get();
169
                        }
170
                        int[] data = DwgUtil.bytesToMachineBytes(dataBytes);
171
                        int lastHandle=0;
172
                        int lastLoc=0;
173
                        int bitPos=0;
174
                        int bitMax= (size - 2) * 8;
175
                        while (bitPos < bitMax) {
176
                                ArrayList v = DwgUtil.getModularChar(data, bitPos);
177
                                bitPos = ((Integer)v.get(0)).intValue();
178
                                lastHandle = lastHandle + ((Integer)v.get(1)).intValue();
179
                                v = DwgUtil.getModularChar(data, bitPos);
180
                                bitPos = ((Integer)v.get(0)).intValue();
181
                                lastLoc = lastLoc + ((Integer)v.get(1)).intValue();
182
                                dwgFile.addDwgObjectOffset(lastHandle, lastLoc);
183
                        }//while
184
                }//while
185
        }
186
        
187
        /*
188
         * Unused.
189
         * 
190
         * Dwg spec says that drawing entities (objects) that has not
191
         * a fixed type must read its type from this section
192
         * 
193
         * 
194
         * */
195
        protected void readDwgClasses() throws Exception {
196
                int offset = dwgFile.getDwgSectionOffset("CLASSES");
197
                // Por ahora nos saltamos los 16 bytes de control
198
                bb.position(offset+16);
199
                bb.order(ByteOrder.LITTLE_ENDIAN);
200
                int size = bb.getInt();
201
                byte[] dataBytes = new byte[size];
202
                for (int i=0; i<dataBytes.length; i++) {
203
                        dataBytes[i] = bb.get();
204
                }
205
                int[] data = DwgUtil.bytesToMachineBytes(dataBytes);
206
                for (int i=0; i<data.length; i++) {
207
                        data[i] = (byte)ByteUtils.getUnsigned((byte)data[i]);
208
                }
209
                bb.position(bb.position()+2+16);
210
                int maxbit = size * 8;
211
                int bitPos = 0;
212
                while ((bitPos+8) < maxbit) {
213
                        ArrayList v = DwgUtil.getBitShort(data, bitPos);
214
                        bitPos = ((Integer)v.get(0)).intValue();
215
                        v = DwgUtil.getBitShort(data, bitPos);
216
                        bitPos = ((Integer)v.get(0)).intValue();
217
                        v = DwgUtil.getTextString(data, bitPos);
218
                        bitPos = ((Integer)v.get(0)).intValue();
219
                        v = DwgUtil.getTextString(data, bitPos);
220
                        bitPos = ((Integer)v.get(0)).intValue();
221
                        v = DwgUtil.getTextString(data, bitPos);
222
                        bitPos = ((Integer)v.get(0)).intValue();
223
                        v = DwgUtil.testBit(data, bitPos);
224
                        bitPos = ((Integer)v.get(0)).intValue();
225
                        v = DwgUtil.getBitShort(data, bitPos);
226
                        bitPos = ((Integer)v.get(0)).intValue();
227
                }
228
        }
229
        
230
        
231
        /**
232
         * Reads all the object referenced in the object map section of the
233
         * DWG file (using their object file obsets)
234
         * */
235
        protected void readDwgObjects() {
236
                for (int i=0; i<dwgFile.getDwgObjectOffsets().size(); i++) {
237
                        DwgObjectOffset doo = (DwgObjectOffset)dwgFile.getDwgObjectOffsets().get(i);
238
                        DwgObject obj = readDwgObject(doo.getOffset(), i);
239
                        /*
240
                        azabala: las entidades DWG no implementadas no nos aportan nada
241
                        (aunque la sigo leyendo por si aparecen problemas de puntero de fichero)
242
                        No considero por tanto los DwgObject
243
                        if (obj != null) {
244
                dwgFile.addDwgObject(obj);
245
            }
246
            */
247
                        if(obj != null && obj.getClass() != DwgObject.class){
248
                                dwgFile.addDwgObject(obj);
249
                        }
250
                }
251
        }
252
        
253
        /**
254
         * Return a dwg object from its index in the dwg file
255
         * @param index of the requested dwg object in the dwg file
256
         * 
257
         * */
258
        public DwgObject getDwgObjectByIndex(int index){
259
                DwgObjectOffset doo = (DwgObjectOffset)dwgFile.getDwgObjectOffsets().get(index);
260
                return readDwgObject(doo.getOffset(), index);
261
        }
262
        
263
        /**
264
         * Reads a dwg drawing entity (dwg object) given its offset in the file
265
         * */
266
        
267
        
268
        protected DwgObject readDwgObject(int offset, int index) {
269
            try {
270
                        bb.position(offset);
271
                        int size = DwgUtil.getModularShort(bb);
272
                        
273
                        bb.order(ByteOrder.LITTLE_ENDIAN);
274
                        byte[] dataBytes = new byte[size];
275
                        String[] dataMachValString = new String[size];
276
                        int[] data = new int[size];
277
                        for (int i=0; i < size; i++) {
278
                                dataBytes[i] = bb.get();
279
                                dataMachValString[i] = HexUtil.bytesToHex(new byte[]{dataBytes[i]});
280
                                Integer dataMachValShort = Integer.decode("0x" + dataMachValString[i]);
281
                                data[i] = dataMachValShort.byteValue();
282
                                data[i] = ByteUtils.getUnsigned((byte)data[i]);
283
                        }
284
                        
285
                        
286
                        int bitPos = 0;
287
                        ArrayList v = DwgUtil.getBitShort(data, bitPos);
288
                        bitPos = ((Integer)v.get(0)).intValue();
289
                        int type = ((Integer)v.get(1)).intValue();
290
                        
291
                        DwgObject obj = DwgObjectFactory.
292
                                                                getInstance().
293
                                                                create(type, index);
294
                   
295
                                    
296
                    v = DwgUtil.getRawLong(data, bitPos);
297
                    bitPos = ((Integer)v.get(0)).intValue();
298
                    int objBSize = ((Integer)v.get(1)).intValue();
299
                    obj.setSizeInBits(objBSize);
300
                    
301
          
302
                    ArrayList entityHandle = new ArrayList();
303
                    v = DwgUtil.getHandle(data, bitPos);
304
                    bitPos = ((Integer)v.get(0)).intValue();
305
                    for (int i=1;i<v.size();i++) {
306
                            entityHandle.add(v.get(i));
307
                    }
308
                    obj.setHandle(DwgUtil.
309
                                    handleBinToHandleInt(entityHandle));
310
                               
311
                    v = DwgUtil.readExtendedData(data, bitPos);
312
                    bitPos = ((Integer)v.get(0)).intValue();
313
                    ArrayList extData = (ArrayList)v.get(1);
314
                    obj.setExtendedData(extData);
315
                    
316
                                   
317
                    boolean gflag = false;
318
                    gflag = obj.isGraphicsFlag();           
319
                    if (gflag) {
320
                            //lee un flag boolean
321
                            v = DwgUtil.testBit(data, bitPos);
322
                            bitPos = ((Integer)v.get(0)).intValue();
323
                            boolean val = ((Boolean)v.get(1)).booleanValue();
324
                           //si hay imagen asociada, se lee por completo
325
                            if (val) {
326
                                    v = DwgUtil.getRawLong(data, bitPos);
327
                                    bitPos = ((Integer)v.get(0)).intValue();
328
                                    size = ((Integer)v.get(1)).intValue();
329
                                    int bgSize = size*8;
330
                                        Integer giData = (Integer)DwgUtil.getBits(data, bgSize, bitPos);
331
                                        obj.setGraphicData(giData.intValue());
332
                                        bitPos = bitPos + bgSize;
333
                            }
334
                    }
335
                    
336
                        readSpecificObject(obj, data, bitPos);
337
                    return obj;
338
            } catch (Exception e) {
339
//                System.out.println("Exception capturada. Probablemente se ha encontrado un" +
340
//                                "objeto con type non fixed");
341
                //e.printStackTrace();
342
                return null;
343
            }
344
        }
345
        
346
        /*
347
         * TODO Esto est? pesimamente dise?ado.
348
         * Cada objeto DwgObject debe tener un metodo
349
         * readSpecificObject(data,bitPos)
350
         * 
351
         * */
352
        protected void readSpecificObject(DwgObject obj, int[] data, int bitPos) throws Exception {
353
                if (obj.getType()==0x11) {
354
                        ((DwgArc)obj).readDwgArcV15(data, bitPos);
355
                } else if (obj.getType()==0x12) {
356
                        ((DwgCircle)obj).readDwgCircleV15(data, bitPos);
357
                } else if (obj.getType()==0x13) {
358
                        ((DwgLine)obj).readDwgLineV15(data, bitPos);
359
                } else if (obj.getType()==0x1B) {
360
                        ((DwgPoint)obj).readDwgPointV15(data, bitPos);
361
                } else if (obj.getType()==0x0F) {
362
                        ((DwgPolyline2D)obj).readDwgPolyline2DV15(data, bitPos);
363
                } else if (obj.getType()==0x10) {
364
                        ((DwgPolyline3D)obj).readDwgPolyline3DV15(data, bitPos);
365
                } else if (obj.getType()==0x0A) {
366
                        ((DwgVertex2D)obj).readDwgVertex2DV15(data, bitPos);
367
                } else if (obj.getType()==0x0B) {
368
                        ((DwgVertex3D)obj).readDwgVertex3DV15(data, bitPos);
369
                } else if (obj.getType()==0x6) {
370
                        ((DwgSeqend)obj).readDwgSeqendV15(data, bitPos);
371
                } else if (obj.getType()==0x1) {
372
                        ((DwgText)obj).readDwgTextV15(data, bitPos);
373
                } else if (obj.getType()==0x2) {
374
                        ((DwgAttrib)obj).readDwgAttribV15(data, bitPos);
375
                } else if (obj.getType()==0x3) {
376
                        ((DwgAttdef)obj).readDwgAttdefV15(data, bitPos);
377
                } else if (obj.getType()==0x4) {
378
                        ((DwgBlock)obj).readDwgBlockV15(data, bitPos);
379
                } else if (obj.getType()==0x5) {
380
                        ((DwgEndblk)obj).readDwgEndblkV15(data, bitPos);
381
                } else if (obj.getType()==0x30) {
382
                        ((DwgBlockControl)obj).readDwgBlockControlV15(data, bitPos);
383
                } else if (obj.getType()==0x31) {
384
                        ((DwgBlockHeader)obj).readDwgBlockHeaderV15(data, bitPos);
385
                } else if (obj.getType()==0x32) {
386
                        ((DwgLayerControl)obj).readDwgLayerControlV15(data, bitPos);
387
                } else if (obj.getType()==0x33) {
388
                        ((DwgLayer)obj).readDwgLayerV15(data, bitPos);
389
                } else if (obj.getType()==0x7) {
390
                        ((DwgInsert)obj).readDwgInsertV15(data, bitPos);
391
                } else if (obj.getType()==0x2C) {
392
                        ((DwgMText)obj).readDwgMTextV15(data, bitPos);
393
                } else if (obj.getType()==0x1F) {
394
                        ((DwgSolid)obj).readDwgSolidV15(data, bitPos);
395
                } else if (obj.getType()==0x23) {
396
                        ((DwgEllipse)obj).readDwgEllipseV15(data, bitPos);
397
                } else if (obj.getType()==0x24) {
398
                        ((DwgSpline)obj).readDwgSplineV15(data, bitPos);
399
                } else if (obj.getType()==0x14) {
400
                        //System.out.println("... detectado un dim del tipo 0x14 ...");
401
                } else if (obj.getType()==0x15) {
402
                        //System.out.println("... detectado un dim del tipo 0x15 ...");
403
                        //((DwgLinearDimension)obj).readDwgLinearDimensionV15(data, bitPos);
404
                } else if (obj.getType()==0x16) {
405
                        //System.out.println("... detectado un dim del tipo 0x16 ...");
406
                } else if (obj.getType()==0x17) {
407
                        //System.out.println("... detectado un dim del tipo 0x17 ...");
408
                } else if (obj.getType()==0x18) {
409
                        //System.out.println("... detectado un dim del tipo 0x18 ...");
410
                } else if (obj.getType()==0x19) {
411
                        //System.out.println("... detectado un dim del tipo 0x19 ...");
412
                } else if (obj.getType()==0x1A) {
413
                        //System.out.println("... detectado un dim del tipo 0x1A ...");
414
                } else if (obj.getType()==0x4D) {
415
                        ((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
416
                } else if (obj.getType()==0x4E) {
417
                        ((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
418
                } else if (obj.getType()==0x4F) {
419
                        ((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
420
                } else if (obj.getType()==0x50) {
421
                        ((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
422
                } else if (obj.getType()==0x51) {
423
                        ((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
424
                } else if (obj.getType()==0x52) {
425
                        ((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
426
                } else if (obj.getType()==0x53) {
427
                        ((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
428
                } else {
429
                        //System.out.println("Tipo de objeto pendiente de implementaci?n");
430
                }
431
        }
432
}