Statistics
| Revision:

root / trunk / org.gvsig.dwg / org.gvsig.dwg.lib / src / main / java / org / gvsig / dwg / lib / readers / DwgFileV12Reader.java @ 5

History | View | Annotate | Download (57.7 KB)

1
/*
2
 * Created on 09-ene-2007
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. 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
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
package org.gvsig.dwg.lib.readers;
45

    
46
import java.awt.geom.Point2D;
47
import java.io.IOException;
48
import java.nio.ByteBuffer;
49
import java.nio.ByteOrder;
50
import java.util.ArrayList;
51
import java.util.List;
52

    
53
import org.gvsig.dwg.lib.CorruptedDwgEntityException;
54
import org.gvsig.dwg.lib.DwgFile;
55
import org.gvsig.dwg.lib.DwgHandleReference;
56
import org.gvsig.dwg.lib.DwgObject;
57
import org.gvsig.dwg.lib.DwgObjectFactory;
58
import org.gvsig.dwg.lib.IDwgBlockMember;
59
import org.gvsig.dwg.lib.IDwgPolyline;
60
import org.gvsig.dwg.lib.IDwgVertex;
61
import org.gvsig.dwg.lib.objects.DwgArc;
62
import org.gvsig.dwg.lib.objects.DwgBlockHeader;
63
import org.gvsig.dwg.lib.objects.DwgCircle;
64
import org.gvsig.dwg.lib.objects.DwgEndblk;
65
import org.gvsig.dwg.lib.objects.DwgInsert;
66
import org.gvsig.dwg.lib.objects.DwgLayer;
67
import org.gvsig.dwg.lib.objects.DwgLine;
68
import org.gvsig.dwg.lib.objects.DwgMeshPolyline;
69
import org.gvsig.dwg.lib.objects.DwgPFacePolyline;
70
import org.gvsig.dwg.lib.objects.DwgPoint;
71
import org.gvsig.dwg.lib.objects.DwgPolyline2D;
72
import org.gvsig.dwg.lib.objects.DwgPolyline3D;
73
import org.gvsig.dwg.lib.objects.DwgSeqend;
74
import org.gvsig.dwg.lib.objects.DwgSolid;
75
import org.gvsig.dwg.lib.objects.DwgText;
76
import org.gvsig.dwg.lib.objects.DwgVertex2D;
77
import org.gvsig.dwg.lib.objects.DwgVertex3D;
78
import org.gvsig.dwg.lib.objects.DwgVertexPFace;
79
import org.gvsig.dwg.lib.objects.DwgVertexPFaceFace;
80

    
81

    
82
/**
83
 * Reads version 12 dwg files.
84
 * 
85
 * DWG 13 and DWG 12 are very different formats (nor do DWG 13-14 and 2000).
86
 * Thats the reason why this IDwgFileReader is very different from the rest. 
87
 * 
88
 * Documentation of reverse engineering of the format:
89
 *         http://www.iwriteiam.nl/DWG12.html
90
 * 
91
 * @author azabala
92
 * 
93
 */
94
public class DwgFileV12Reader implements IDwgFileReader{
95

    
96
        private DwgFile dwgFile;
97
        private ByteBuffer bb;
98
        ArrayList readers = new ArrayList();
99
        private boolean r13 = false;
100
        int index = 0;
101
        
102
        ArrayList blocks = new ArrayList();
103
        
104
        
105
        /**
106
         * While DwgBlock is a DWG entity, readed from the DWG entities
107
         * section, a Block is an entry in the BLOCK Section of DWG 12 format.
108
         * 
109
         * Block has block name attribute (like DwgBlock), but its most
110
         * important attribute is its order in the Block section.
111
         * 
112
         * Inserts has a short number that we think is the order of its
113
         * referred block in the block table (the only approach to fech
114
         * the block of an insert)
115
         * */
116
        class Block {
117
                /*
118
        |----------|--------------------------------------------|
119
        | 1        | This is an anonymous Block generated by    |
120
        |          | hatching, associative dimensioning, other  |
121
        |          | internal operations, or an application     |
122
        |----------|--------------------------------------------|
123
        | 2        | This Block has Attributes                  |
124
        |----------|--------------------------------------------|
125
        | 4        | This Block is an external reference (Xref) |
126
        |----------|--------------------------------------------|
127
        | 8        | not used                                   |
128
        |----------|--------------------------------------------|
129
        | 16       | This Block is externally dependent         |
130
        |----------|--------------------------------------------|
131
        | 32       | This is a resolved external reference, or  |
132
        |          | dependent of an external reference         |
133
        |----------|--------------------------------------------|
134
        | 64       | This definition is referenced              |
135
        +-------------------------------------------------------+
136
        */
137
                byte flag;
138
                String name;
139
                short used;
140
                
141
                byte b1;
142
                short w1;
143
                byte b2;
144
                short w3;
145
                short crc;
146
        }
147
        
148
        public DwgFileV12Reader(boolean isR13){
149
                r13 = isR13;
150
                readers.add(null);//0
151
                readers.add(new LineReader());//1
152
                readers.add(new PointReader());//2
153
                readers.add(new CircleReader());//3
154
                readers.add(new ShapeReader());//4
155
                readers.add(null);//5
156
                readers.add(null);//6
157
                readers.add(new TextReader());//7
158
                readers.add(new ArcReader());//8
159
                readers.add(new TraceReader());//9
160
                readers.add(null);//10
161
                readers.add(new SolidReader());//11
162
                readers.add(new BlkReader());//12
163
                readers.add(new EndBlkReader());//13
164
                readers.add(new InsertReader());//14
165
                readers.add(new AttDefReader());//15
166
                readers.add(new AttribReader());//16
167
                readers.add(new SbEndReader());//17
168
                readers.add(null);//18
169
                readers.add(new PlineReader());//19
170
                readers.add(new VertexReader());//20
171
                readers.add(null);//21
172
                readers.add(new Face3DReader());//22
173
                readers.add(new DimReader());//23
174
                readers.add(new VPortReader());//24
175
        }
176
        
177
        
178

    
179
        /* (non-Javadoc)
180
         * @see com.iver.cit.jdwglib.dwg.readers.IDwgFileReader#read(com.iver.cit.jdwglib.dwg.DwgFile, java.nio.ByteBuffer)
181
         */
182
        public void read(DwgFile dwgFile, ByteBuffer bb) throws IOException {
183
                this.dwgFile = dwgFile;
184
                this.bb = bb;
185
                try {
186
////                        handle.seek(6, 1) # skip rest of version
187
//                        bb.position(12);
188
//                        bb.position(bb.position() + 6);
189
                        bb.position(0);
190
                        byte[] header = new byte[12];
191
                        bb.get(header);
192
                        String headerStr = new String(header);
193
                        
194
//                    (_b1, _w1, _w2, _w3, _b2) = struct.unpack("<BhhhB", handle.read(8))
195
                        bb.order(ByteOrder.LITTLE_ENDIAN);
196
                        byte b1 = bb.get();
197
                        short w1 = bb.getShort();
198
                        short w2 = bb.getShort();
199
                        short w3 = bb.getShort();
200
                        byte b2 = bb.get();
201
                        
202
                        
203
                        //To translate Python to Java, we must see the number
204
                        //of bytes of the reading
205
                        
206
//                         _estart, _eend = struct.unpack("<ll", handle.read(8))
207
                        bb.order(ByteOrder.LITTLE_ENDIAN);
208
                        int eStart = bb.getInt();
209
                        int eEnd = bb.getInt();
210
                        
211
//                        _bsstart, _l1, _bsend, _l2 = struct.unpack("<llll", handle.read(16))
212
                        int bsStart = bb.getInt();
213
                        int l1 = bb.getInt();
214
                        
215
                        int bsEnd = bb.getInt();
216
                        int l2 = bb.getInt();
217
                        
218
                        Dwg12Table blockTable = getTable();
219
                        
220
                        Dwg12Table layerTable = getTable();
221
                        
222
                        Dwg12Table styleTable = getTable();
223
                        
224
                        Dwg12Table lineTypeTable = getTable();
225
                        
226
                        Dwg12Table viewTable = getTable();
227
                        
228
                        readHeader();
229
                        
230
                        Dwg12Table ucsTable = getTable();
231
                        
232
                        bb.position(0x500);
233
                        
234
                        Dwg12Table vportTable = getTable();
235
                        
236
                        bb.position(bb.position() + 8);
237
                        
238
                        Dwg12Table appidTable = getTable();
239
                        
240
                        bb.position(bb.position() + 6);
241
                        
242
                        Dwg12Table dimStyleTable = getTable();
243
                        bb.position(0x69f);
244
                        
245
                        Dwg12Table p13table = getTable();
246
                        
247
                        bb.position(bb.position() + 38);
248
                        
249
                        int currentPosition = bb.position();
250
                        if(currentPosition != eStart){
251
                                //Se supone que deber?amos estar en eStart
252
                                throw new RuntimeException("Error: no se ha llegado al principio de las entidades de dibujo");
253
                        }
254
                        
255
                        //lee primero entidades normales?
256
                        readEntities(eStart, eEnd);
257
                        
258
                        bb.position(bb.position() + 19);
259
                        
260
                        readBlockTable(blockTable);
261
                        readLayerTable(layerTable);
262
                        
263
//de momento nos saltamos estas tablas
264
//                        readStyleTable(styleTable);
265
//                        readLTypeTable(lineTypeTable);
266
//                        readViewTable(viewTable);
267
//                        readUcsTable(ucsTable);
268
//                        readVportTable(vportTable);
269
//                        readAppidTable(appidTable);
270
//                        readDimStyleTable(dimStyleTable);
271
//                        readP13Table(p13table);
272
                        
273
                        //luego lee entidades de bloque
274
                        readEntities(bsStart, bsEnd);
275
                        
276
                        bb.position(bb.position() + 36);
277
                        
278
                        bb.order(ByteOrder.LITTLE_ENDIAN);
279
                        
280
                        int peStart, peEnd, pbStart, pbEnd;
281
                        
282
                        peStart = bb.getInt();
283
                        peEnd = bb.getInt();
284
                        pbStart = bb.getInt();
285
                        pbEnd = bb.getInt();
286
                        
287
                        if(peStart != eStart)
288
                                System.out.println("peStart="+peStart+" eStart="+eStart);
289
                        
290
                        if(peEnd != eEnd)
291
                                System.out.println("peStart="+peEnd+" eStart="+eEnd);
292
                        
293
                        if(pbStart != bsStart)
294
                                System.out.println("peStart="+pbStart+" eStart="+bsStart);
295
                        
296
                        if(bsEnd != pbEnd)
297
                                System.out.println("peStart="+pbStart+" eStart="+bsStart);
298
                   
299
                        bb.position(bb.position() + 12);
300
                        
301
                        Dwg12TableTest bts = getTableTest();
302
                        
303
                        Dwg12TableTest lyrTs = getTableTest();
304
                        
305
                        Dwg12TableTest sts = getTableTest();
306
                        
307
                        Dwg12TableTest ltts = getTableTest();
308
                        
309
                        Dwg12TableTest vts = getTableTest();
310
                        
311
                        Dwg12TableTest uts = getTableTest();
312
                        
313
                        Dwg12TableTest vpts = getTableTest();
314
                        
315
                        Dwg12TableTest ats = getTableTest();
316
                        
317
                        Dwg12TableTest dts = getTableTest();
318
                        
319
                        Dwg12TableTest pts = getTableTest();
320
                        
321
                        
322
                        
323
                        
324
                } catch (Exception e) {
325
                        e.printStackTrace();
326
//                        logger.error(e);
327
                }
328
        }
329
        
330
        
331
        private void readP13Table(Dwg12Table p13table) {
332
                // TODO Auto-generated method stub
333
        }
334

    
335

    
336

    
337
        private void readDimStyleTable(Dwg12Table dimStyleTable) {
338
                short size = dimStyleTable.s1;
339
                int numRecs = dimStyleTable.i1;
340
                int start = dimStyleTable.i2;
341
                int end = -1;
342
                bb.position(start);
343
                for(int i = 0; i < numRecs; i++){
344
                        end = bb.position() + size;
345
                        
346
                        byte flag = bb.get();
347
                        byte[] nameBytes = new byte[32];
348
                        bb.get(nameBytes);
349
                        String name = new String(nameBytes);
350
                        
351
                        bb.order(ByteOrder.LITTLE_ENDIAN);
352
                        short word = bb.getShort();
353
                        
354
                        double[] d4048 = new double[9];
355
                        for(int j = 0; j < 9; j++){
356
                                d4048[j] = bb.getDouble();
357
                        }
358
                        
359
                        double[] d40145 = new double[6];
360
                        for(int j = 0; j < 6; j++){
361
                                d40145[j] = bb.getDouble();
362
                        }
363
                        
364
                        byte[] b7078 = new byte[7];
365
                        for(int j = 0; j < 7; j++){
366
                                b7078[j] = bb.get();
367
                        }
368
                        
369
                        byte[] b170175 = new byte[6];
370
                        for(int j = 0; j < 6; j++){
371
                                b170175[j] = bb.get();
372
                        }
373
                        
374
                        bb.order(ByteOrder.nativeOrder());
375
                        byte[] s3 = new byte[16];
376
                        bb.get(s3);
377
                        
378
                        byte[] s4 = new byte[16];
379
                        bb.get(s4);
380
                        
381
                        byte[] s5 = new byte[32];
382
                        bb.get(s5);
383
                        
384
                        byte[] s6 = new byte[32];
385
                        bb.get(s6);
386
                        
387
                        byte[] s7 = new byte[32];
388
                        bb.get(s6);
389
                        
390
                        bb.position(bb.position() + 3);
391
                        
392
                        bb.order(ByteOrder.LITTLE_ENDIAN);
393
                        short w176 = bb.getShort();
394
                        short w177 = bb.getShort();
395
                        short w178 = bb.getShort();
396
                        
397
                        double d146 = bb.getDouble();
398
                        double d147 = bb.getDouble();
399
                        
400
                        
401
                        int offset = end - bb.position();
402
                        if(offset > 0)
403
                                bb.position(bb.position() + offset);
404
                        
405
                        bb.order(ByteOrder.LITTLE_ENDIAN);
406
                        short crc = bb.getShort();
407
                }
408
                byte[] crc32 = new byte[32];
409
                bb.get(crc32);
410
        }
411

    
412

    
413

    
414
        private void readAppidTable(Dwg12Table appidTable) {
415
                short size = appidTable.s1;
416
                int numRecs = appidTable.i1;
417
                int start = appidTable.i2;
418
                int end = -1;
419
                bb.position(start);
420
                for(int i = 0; i < numRecs; i++){
421
                        end = bb.position() + size;
422
                        
423
                        byte flag = bb.get();
424
                        byte[] nameBytes = new byte[32];
425
                        bb.get(nameBytes);
426
                        String name = new String(nameBytes);
427
                        
428
                        bb.order(ByteOrder.LITTLE_ENDIAN);
429
                        short word = bb.getShort();
430
                        
431
                        int offset = end - bb.position();
432
                        if(offset > 0)
433
                                bb.position(bb.position() + offset);
434
                        
435
                        bb.order(ByteOrder.LITTLE_ENDIAN);
436
                        short crc = bb.getShort();
437
                }
438
                byte[] crc32 = new byte[32];
439
                bb.get(crc32);
440
        }
441

    
442

    
443

    
444
        private void readVportTable(Dwg12Table vportTable) {
445
                short size = vportTable.s1;
446
                int numRecs = vportTable.i1;
447
                int start = vportTable.i2;
448
                int end = -1;
449
                bb.position(start);
450
                for(int i = 0; i < numRecs; i++){
451
                        end = bb.position() + size;
452
                        
453
                        byte flag = bb.get();
454
                        byte[] nameBytes = new byte[32];
455
                        bb.get(nameBytes);
456
                        String name = new String(nameBytes);
457
                        
458
                        bb.order(ByteOrder.LITTLE_ENDIAN);
459
                        short used = bb.getShort();
460
                        
461
                        double[] pt10 = getPoint(false);
462
                        double[] pt11 = getPoint(false);
463
                        double[] pt17 = getPoint(false);
464
                        double[] pt16 = getPoint(true);
465
                        
466
                        bb.order(ByteOrder.LITTLE_ENDIAN);
467
                        
468
                        double d50 = bb.getDouble();
469
                        double d40 = bb.getDouble();
470
                        
471
                        double[] pt12 = getPoint(false);
472
                        
473
                        bb.order(ByteOrder.LITTLE_ENDIAN);
474
                        double d41 = bb.getDouble();
475
                        double d42 = bb.getDouble();
476
                        double d43 = bb.getDouble();
477
                        double d44 = bb.getDouble();
478
                        
479
                        short[] w7178 = new short[8];
480
                        for(int j = 0; j < 8; j++){
481
                                w7178[j] = bb.getShort();
482
                        }
483
                        bb.order(ByteOrder.LITTLE_ENDIAN);
484
                        double d51 = bb.getDouble();
485
                        
486
                        double[] pt13 = getPoint(false);
487
                        double[] pt14 = getPoint(false);
488
                        double[] pt15 = getPoint(false);
489
                        
490
                        int offset = end - bb.position();
491
                        if(offset > 0)
492
                                bb.position(bb.position() + offset);
493
                        
494
                        bb.order(ByteOrder.LITTLE_ENDIAN);
495
                        short crc = bb.getShort();
496
                }
497
                byte[] crc32 = new byte[32];
498
                bb.get(crc32);
499
        }
500

    
501

    
502

    
503
        private void readUcsTable(Dwg12Table ucsTable) {
504
                short size = ucsTable.s1;
505
                int numRecs = ucsTable.i1;
506
                int start = ucsTable.i2;
507
                int end = -1;
508
                bb.position(start);
509
                for(int i = 0; i < numRecs; i++){
510
                        end = bb.position() + size;
511
                        
512
                        byte flag = bb.get();
513
                        byte[] nameBytes = new byte[32];
514
                        bb.get(nameBytes);
515
                        String name = new String(nameBytes);
516
                        
517
                        bb.order(ByteOrder.LITTLE_ENDIAN);
518
                        short used = bb.getShort();
519
                        
520
                        double[] pt10 = getPoint(true);
521
                        double[] pt11 = getPoint(true);
522
                        double[] pt12 = getPoint(true);
523
                        
524
                        
525
                        
526
                        int offset = end - bb.position();
527
                        if(offset > 0)
528
                                bb.position(bb.position() + offset);
529
                        
530
                        bb.order(ByteOrder.LITTLE_ENDIAN);
531
                        short crc = bb.getShort();
532
                }
533
                byte[] crc32 = new byte[32];
534
                bb.get(crc32);
535
                
536
                
537
        }
538

    
539

    
540

    
541
        private void readViewTable(Dwg12Table viewTable) {
542
                short size = viewTable.s1;
543
                int numRecs = viewTable.i1;
544
                int start = viewTable.i2;
545
                int end = -1;
546
                bb.position(start);
547
                for(int i = 0; i < numRecs; i++){
548
                        end = bb.position() + size;
549
                        
550
                        byte flag = bb.get();
551
                        byte[] nameBytes = new byte[32];
552
                        bb.get(nameBytes);
553
                        String name = new String(nameBytes);
554
                        
555
                        bb.order(ByteOrder.LITTLE_ENDIAN);
556
                        short used = bb.getShort();
557
                        double db40 = bb.getDouble();
558
                        
559
                        double[] pt10 = getPoint(false);
560
                        
561
                        bb.order(ByteOrder.LITTLE_ENDIAN);
562
                        double db41 = bb.getDouble();
563
                        
564
                        double[] pt11 = getPoint(true);
565
                        
566
                        double[] pt12 = getPoint(true);
567
                        
568
                        
569
                        bb.order(ByteOrder.LITTLE_ENDIAN);
570
                        short w71 = bb.getShort();
571
                        double db42 = bb.getDouble();
572
                        double db43 = bb.getDouble();
573
                        double db44 = bb.getDouble();
574
                        double db50 = bb.getDouble();
575
                        
576
                        int offset = end - bb.position();
577
                        if(offset > 0)
578
                                bb.position(bb.position() + offset);
579
                        
580
                        bb.order(ByteOrder.LITTLE_ENDIAN);
581
                        short crc = bb.getShort();
582
                        
583
                        
584
                }
585
                byte[] crc32 = new byte[32];
586
                bb.get(crc32);
587
        }
588

    
589

    
590

    
591
        private void readLTypeTable(Dwg12Table lineTypeTable) {
592
                short size = lineTypeTable.s1;
593
                int numRecs = lineTypeTable.i1;
594
                int start = lineTypeTable.i2;
595
                int end = -1;
596
                bb.position(start);
597
                for(int i = 0; i < numRecs; i++){
598
                        end = bb.position() + size;
599
                        byte flag = bb.get();
600
                        byte[] nameBytes = new byte[32];
601
                        bb.get(nameBytes);
602
                        String name = new String(nameBytes);
603
                        bb.order(ByteOrder.LITTLE_ENDIAN);
604
                        short w1 = bb.getShort();
605
                        
606
                        byte[] s1 = new byte[48];
607
                        bb.get(s1);
608
                        String s1name = new String(s1);
609
                        
610
                        bb.order(ByteOrder.nativeOrder());
611
                        byte b1 = bb.get();
612
                        byte b2 = bb.get();
613
                        
614
                        bb.order(ByteOrder.LITTLE_ENDIAN);
615
                        double[] doubles = new double[13];
616
                        for(int j = 0; j < 13; j++){
617
                                doubles[j] = bb.getDouble();
618
                        }
619
                        
620
                        short crc = bb.getShort();
621
                        
622
                        int offset = end - bb.position();
623
                        if(offset > 0)
624
                                bb.position(bb.position() + offset);
625
                }
626
                byte[] crc32 = new byte[32];
627
                bb.get(crc32);
628
        }
629

    
630

    
631

    
632
        /**
633
         * @param styleTable
634
         */
635
        private void readStyleTable(Dwg12Table styleTable) {
636
                short size = styleTable.s1;
637
                int numRecs = styleTable.i1;
638
                int start = styleTable.i2;
639
                int end = -1;
640
                bb.position(start);
641
                for(int i = 0; i < numRecs; i++){
642
                        end = bb.position() + size;
643
                        byte flag = bb.get();
644
                        byte[] nameBytes = new byte[32];
645
                        bb.get(nameBytes);
646
                        String name = new String(nameBytes);
647
                        bb.order(ByteOrder.LITTLE_ENDIAN);
648
                        short w1 = bb.getShort();
649
                        double d1 = bb.getDouble();
650
                        double d2 = bb.getDouble();
651
                        double d3 = bb.getDouble();
652
                        byte b1 = bb.get();
653
                        double d4 = bb.getDouble();
654
                        
655
                        byte[] s1 = new byte[128];
656
                        bb.get(s1);
657
                        
658
                        short crc = bb.getShort();
659
                        int offset = end - bb.position();
660
                        if(offset > 0)
661
                                bb.position(bb.position() + offset);
662
                }
663
                byte[] crc32 = new byte[32];
664
                bb.get(crc32);
665
        }
666

    
667

    
668

    
669
        /**
670
         * @param layerTable
671
         */
672
        private void readLayerTable(Dwg12Table layerTable) {
673
                short size = layerTable.s1;
674
                int numR = layerTable.i1;
675
                int start = layerTable.i2;
676
                
677
                int begin = -1;
678
                int end = -1;
679
                
680
                DwgLayer layer = null;
681
                for(int i = 0; i < numR; i++){
682
                        begin = start + i * size;
683
                        bb.position(begin);
684
                        end = begin + size - 2;
685
                        
686
                        layer = new DwgLayer(index);
687
                        index++;
688
                        
689
                        byte flag = bb.get();
690
                        /*
691
                         +=====================================================+
692
          | Flag bit | Meaning                                  |
693
          | value    |                                          |
694
          |----------|------------------------------------------|
695
          | 1        | If set, layer is frozen                  |
696
          |----------|------------------------------------------|
697
          | 2        | If set, layer is frozen by default in    |
698
          |          | new Viewports                            |
699
          |----------|------------------------------------------|
700
          | 4        | If set, layer is locked                  |
701
          +-----------------------------------------------------+
702
                         * */
703
                        if((flag & 0x1) > 0){
704
                                layer.setFrozen(true);
705
                        }
706
                        if((flag & 0x2) > 0){
707
                                layer.setFrozenInNew(true);
708
                        }
709
                        if((flag & 0x4) > 0){
710
                                layer.setLocked(true);
711
                        }
712
                        
713
                        byte[] nameByte = new byte[32];
714
                        bb.get(nameByte);
715
                        String name = new String(nameByte).trim();
716
                        layer.setName(name);
717
                        
718
                        bb.order(ByteOrder.LITTLE_ENDIAN);
719
                        short used = bb.getShort();
720
                        short color = bb.getShort();
721
                        layer.setColor(color);
722
                        short style = bb.getShort();
723
                        short crc = bb.getShort();
724

    
725
                        DwgHandleReference handle = new DwgHandleReference(0x5, i);
726
                        layer.setHandle(handle);
727
                        dwgFile.addDwgObject(layer);
728
                        
729
                        
730
                        int offset = end - bb.position();
731
                        if(offset > 0)
732
                                bb.position(bb.position() + offset);
733
                        
734
                }
735
                byte[] crc32 = new byte[32];
736
                bb.get(crc32);
737
        }
738

    
739

    
740
        interface EntityReader{
741
                void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj);
742
        }
743
        
744
        /**
745
         * In DWG 12 version, some kind of objects (Polylines and Vertex) cannot be
746
         * instanciated until the EntityReader has readed some stuff (flags and so)
747
         * from the file.
748
         * 
749
         * DefferedEntityReader has the responsability to create DwgObject instances,
750
         * and it has the precondition that DwgObject parameter of its method read must
751
         * be null.
752
         * */
753
        abstract class DefferedEntityReader implements EntityReader{
754
                abstract DwgObject getDwgObject(int index);
755
                
756
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj){
757
                        if(dwgObj != null)
758
                                throw new RuntimeException("DefferedEntityReader es el encargado de construir los objetos, debe recibirlos a null");
759
                }
760
                
761
        }
762
        
763
        class LineReader implements EntityReader{
764
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
765
                        if(! (dwgObj instanceof DwgLine))
766
                                throw new RuntimeException("No es entidad LINE");
767
                        DwgLine line = (DwgLine) dwgObj;
768
                        
769
                        boolean zflag = true;
770
                        if( (flags & 0x4) > 0)
771
                                zflag = false;
772
                        
773
                        double[] pt10 = getPoint(zflag);
774
                        double[] pt11 = getPoint(zflag);
775
                        
776
                        line.setP1(pt10);
777
                        line.setP2(pt11);
778
                        
779
                        if((opts & 0x1) > 0){
780
                                double[] pt210 = getPoint(true);
781
                                line.setExtrusion(pt210);
782
                        }
783
                        
784
                        if((opts & 0x2) > 0){
785
                                /*
786
                                 * This field is only found in DWG12 prev
787
                                 * files. Since DWG 12, elevation is saved
788
                                 * in third coordinate of points.
789
                                 * 
790
                                 * */
791
                                bb.order(ByteOrder.LITTLE_ENDIAN);
792
                                double db38 = bb.getDouble();
793
                                line.getP1()[2] = db38;
794
                                line.getP2()[2] = db38;
795
                        }
796
                }
797
        }
798
        
799
        
800
        
801
        class PointReader implements EntityReader{
802
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
803
                        if(! (dwgObj instanceof DwgPoint))
804
                                throw new RuntimeException("No es entidad POINT");
805
                        DwgPoint point = (DwgPoint) dwgObj;
806
                        boolean zflag = true;
807
                        if((flags & 0x4) > 0)
808
                                zflag = false;
809
                        double[] pt10 = getPoint(zflag);
810
                        point.setPoint(pt10);
811
                        
812
                        if((opts & 0x1) > 0){
813
                                double[] pt210 = getPoint(true);
814
                                point.setExtrusion(pt210);
815
                        }
816
                        
817
                        if((opts & 0x2) > 0){
818
                                bb.order(ByteOrder.LITTLE_ENDIAN);
819
                                double db38 = bb.getDouble();
820
                                point.getPoint()[2] = db38;
821
                        }
822
                }
823
        }
824
        
825
        
826
        class CircleReader implements EntityReader{
827
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
828
                        if(! (dwgObj instanceof DwgCircle))
829
                                throw new RuntimeException("No es entidad CIRCLE");
830
                        DwgCircle circle = (DwgCircle) dwgObj;
831
                        
832
                        boolean zflag = true;
833
                        if((flags & 0x4) > 0)
834
                                zflag = false;
835
                        double[] pt10 = getPoint(zflag);
836
                        circle.setCenter(pt10);
837
                        
838
                        bb.order(ByteOrder.LITTLE_ENDIAN);
839
                        double d40 = bb.getDouble();
840
                        circle.setRadius(d40);
841
                        
842
                        double[] pt210 = null;
843
                        if((opts & 0x1) > 0){
844
                                pt210 = getPoint(true);
845
                                
846
                        }else{
847
                                pt210 = new double[]{0,0,1};
848
                        }
849
                        circle.setExtrusion(pt210);
850
                        if((opts & 0x2) > 0){
851
                                bb.order(ByteOrder.LITTLE_ENDIAN);
852
                                double db38 = bb.getDouble();
853
                                circle.getCenter()[2] = db38;
854
                        }
855
                }
856
        }
857
        
858
        
859
        
860
        class ShapeReader implements EntityReader{
861
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
862
                        
863
                        //TODO POR IMPLEMENTAR DwgShape (referencia a un
864
                        //fichero de texto)
865
                        
866
                        double[] pt10 = getPoint(false);
867
                        bb.order(ByteOrder.LITTLE_ENDIAN);
868
                        short w2 = bb.getShort();
869
                        if((opts & 0x1) > 0){
870
                                double[] pt210 = getPoint(true);
871
                        }
872
                        if((opts & 0x2) > 0){
873
                                bb.order(ByteOrder.LITTLE_ENDIAN);
874
                                double db38 = bb.getDouble();
875
                        }
876
                }
877
        }
878
        
879
        public String getString(){
880
                bb.order(ByteOrder.LITTLE_ENDIAN);
881
                short len = bb.getShort();
882
                byte[] bytes = new byte[len];
883
                bb.order(ByteOrder.nativeOrder());
884
                bb.get(bytes);
885
                return new String(bytes);
886
        }
887
        
888
        
889
        class TextReader implements EntityReader{
890
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
891
                        
892
                        if(! (dwgObj instanceof DwgText))
893
                                throw new RuntimeException("No es entidad TEXT");
894
                        DwgText txt = (DwgText) dwgObj;
895
                        
896
                        
897
                        double[] pt10 = getPoint(false);
898
                        txt.setInsertionPoint(new Point2D.Double(pt10[0], pt10[1]));
899
                        
900
                        
901
                        bb.order(ByteOrder.LITTLE_ENDIAN);
902
                        double db40 = bb.getDouble();
903
                        txt.setHeight(db40);
904
                        
905
                        
906
                        
907
                        String text = getString();
908
                        txt.setText(text);
909
                        if((opts & 0x1) > 0){
910
                                bb.order(ByteOrder.LITTLE_ENDIAN);
911
                                double db50 = bb.getDouble();
912
                                txt.setRotationAngle(db50);
913
                        }
914
                        if((opts & 0x2) > 0){
915
                                double db41 = bb.getDouble();
916
                                txt.setWidthFactor(db41);//TODO 41 es width factor seguro?
917
                        }
918
                        if((opts & 0x4) > 0){
919
                                double db51 = bb.getDouble();
920
                                txt.setObliqueAngle(db51);
921
                        }
922
                        if((opts & 0x8) > 0){
923
                                byte b7 = bb.get();
924
                        }
925
                        if((opts & 0x10) > 0){
926
                                byte b71 = bb.get();
927
                                //parametros de mirroring
928
                                txt.setGeneration(b71);
929
                        }
930
                        if((opts & 0x20) > 0){
931
                                byte b72 = bb.get();
932
                                txt.setHalign(b72);
933
                        }
934
                        if((opts & 0x40) > 0){
935
                                double[] pt11 = getPoint(false);
936
                                txt.setAlignmentPoint(new Point2D.Double(pt11[0], pt11[1]));
937
                        }
938
                        if((opts & 0x100) > 0){
939
                                byte b73 = bb.get();
940
                                txt.setValign(b73);
941
                        }
942
                        
943
                        //TODO La especificaci?n DXF 12 dice que la extrusion 
944
                        //codigos DXF 210, 220, 230 se aplica sobre:
945
                        /*
946
                         Line, Point, Circle, Shape, Text, Arc, Trace,
947
                         Solid, Block Reference, Polyline, 
948
                          Dimension, Attribute, and Attribute Definition entity
949
                          
950
                          Pero aqu? no aparece por ningun lado la extrusion
951
                         * */
952
                        double[] ext = new double[]{0, 0, 1};
953
                        txt.setExtrusion(ext);
954
                }
955
        }
956
        
957
        
958
        class ArcReader implements EntityReader{
959
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
960
                        if(! (dwgObj instanceof DwgArc))
961
                                throw new RuntimeException("No es entidad ARC");
962
                        DwgArc arc = (DwgArc) dwgObj;
963
                        
964
                        double[] pt10 = getPoint(false);
965
                        arc.setCenter(pt10);
966
                        
967
                        bb.order(ByteOrder.LITTLE_ENDIAN);
968
                        double d40 = bb.getDouble();
969
                        arc.setRadius(d40);
970
                        
971
                        double d50 = bb.getDouble();
972
                        arc.setInitAngle(d50);
973
                        
974
                        double d51 = bb.getDouble();
975
                        arc.setEndAngle(51);
976
                        
977
                        double[] pt210 = null;
978
                        if((opts & 0x1) > 0){
979
                                pt210 = getPoint(true);
980
                                arc.setExtrusion(pt210);
981
                        }else{
982
                                pt210 = new double[]{1, 0, 0};
983
                        }
984
                        if((opts & 0x2) > 0){
985
                                bb.order(ByteOrder.LITTLE_ENDIAN);
986
                                double db38 = bb.getDouble();
987
                                arc.getCenter()[2] = db38;
988
                        }
989
                }
990
        }
991
        
992
        
993
        
994
        class TraceReader implements EntityReader{
995
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
996
                        //TODO Implementar DwgTrace
997
                        double[] pt10 = getPoint(false);
998
                        double[] pt11 = getPoint(false);
999
                        double[] pt12 = getPoint(false);
1000
                        double[] pt13 = getPoint(false);
1001
                        if((opts & 0x1) > 0){
1002
                                double[] pt210 = getPoint(true);
1003
                        }
1004
                        if((opts & 0x2) > 0){
1005
                                bb.order(ByteOrder.LITTLE_ENDIAN);
1006
                                double db38 = bb.getDouble();
1007
                        }
1008
                }
1009
        }
1010
        
1011
        class SolidReader implements EntityReader{
1012
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1013
                        if(! (dwgObj instanceof DwgSolid))
1014
                                throw new RuntimeException("No es entidad SOLID");
1015
                        DwgSolid solid = (DwgSolid) dwgObj;
1016
                        
1017
                        
1018
                        
1019
                        double[] pt11 = getPoint(false);
1020
                        solid.setCorner1(pt11);
1021
                        
1022
                        double[] pt12 = getPoint(false);
1023
                        solid.setCorner2(pt12);
1024
                        
1025
                        double[] pt13 = getPoint(false);
1026
                        solid.setCorner3(pt13);
1027
                        
1028
                        double[] pt14 = getPoint(false);
1029
                        solid.setCorner4(pt14);
1030
                        
1031
                        
1032
                        if((opts & 0x1) > 0){
1033
                                double[] pt210 = getPoint(true);
1034
                                solid.setExtrusion(pt210);
1035
                        }
1036
                        if((opts & 0x2) > 0){
1037
                                bb.order(ByteOrder.LITTLE_ENDIAN);
1038
                                double db38 = bb.getDouble();
1039
                                solid.getCorner1()[2] = db38;
1040
                                solid.getCorner2()[2] = db38;
1041
                                solid.getCorner3()[2] = db38;
1042
                                solid.getCorner4()[2] = db38;
1043
                        }
1044
                        
1045
                        solid.setExtrusion(new double[]{0, 0, 1});
1046
                }
1047
        }
1048
        
1049
        
1050
        private Block getBlock(String blockName){
1051
                for(int i = 0; i < blocks.size(); i++){
1052
                        Block block = (Block) blocks.get(i);
1053
                        if(block.name.equalsIgnoreCase(blockName)){
1054
                                return block;
1055
                        }
1056
                }
1057
                return null;
1058
        }
1059
        
1060
        
1061
        
1062
        class BlkReader implements EntityReader{
1063
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1064
                        if(! (dwgObj instanceof DwgBlockHeader))
1065
                                throw new RuntimeException("No es entidad BLOCK");
1066
                        DwgBlockHeader blk = (DwgBlockHeader) dwgObj;
1067
                        
1068
                        
1069
                        double[] pt10 = getPoint(false);
1070
                        blk.setBasePoint(pt10);
1071
                        String blockName = getString();
1072
                        blk.setName(blockName);
1073
                        Block block = getBlock(blockName);
1074
                        if(block == null){
1075
                                System.out.println(blockName+" no encontrado en la tabla de bloques");
1076
                        }
1077
                        
1078
                        if((opts & 0x2) > 0)
1079
                        {
1080
                                //puede ser que se trate de referencias
1081
                                //externas??
1082
                                String s3 = getString();
1083
                        }
1084
                        
1085
                        if((flags & 1) > 0){
1086
                                blk.setAnonymous(true);
1087
                        }
1088
                        
1089
                        if((flags & 2) > 0){
1090
                                blk.setHasAttrs(true);
1091
                        }
1092
                        
1093
                        if((flags & 4) > 0){
1094
                                blk.setBlkIsXRef(true);
1095
                        }
1096
                        
1097
                        if((flags & 16) > 0){
1098
                                blk.setXdep(true);
1099
                        }
1100
                        
1101
                        if((flags & 32) > 0){
1102
                                blk.setXRefOverLaid(true);
1103
                        }
1104
                        
1105
                        if((flags & 64) > 0){
1106
                                blk.setLoaded(true);
1107
                        }
1108
                        
1109
                        
1110
                        /*
1111
                        
1112
                           1        | This is an anonymous Block generated by    |
1113
                  |          | hatching, associative dimensioning, other  |
1114
                  |          | internal operations, or an application     |
1115
                  |----------|--------------------------------------------|
1116
                  | 2        | This Block has Attributes                  |
1117
                  |----------|--------------------------------------------|
1118
                  | 4        | This Block is an external reference (Xref) |
1119
                  |----------|--------------------------------------------|
1120
                  | 8        | not used                                   |
1121
                  |----------|--------------------------------------------|
1122
                  | 16       | This Block is externally dependent         |
1123
                  |----------|--------------------------------------------|
1124
                  | 32       | This is a resolved external reference, or  |
1125
                  |          | dependent of an external reference         |
1126
                  |----------|--------------------------------------------|
1127
                  | 64       | This definition is referenced       
1128
                        
1129
                        */
1130
                
1131
                }
1132
        }
1133
        class EndBlkReader implements EntityReader{
1134
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1135
                }
1136
        }
1137
        
1138
        class InsertReader implements EntityReader{
1139
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1140
                        if(! (dwgObj instanceof DwgInsert))
1141
                                throw new RuntimeException("No es entidad INSERT");
1142
                        DwgInsert insert = (DwgInsert) dwgObj;
1143
                        
1144
                        bb.order(ByteOrder.nativeOrder());
1145
                        short w1 = bb.getShort();//Puede ser este el identificador de bloque???
1146
                        
1147
                        DwgHandleReference blockHandle = new 
1148
                                DwgHandleReference(0x5, w1);
1149
                        insert.setBlockHeaderHandle(blockHandle);
1150
                        
1151
                        double[] pt10 = getPoint(false);
1152
                        insert.setInsertionPoint(pt10);
1153
                        
1154
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1155
                        
1156
                        double x = 0d, y = 0d, z = 0d;
1157
                        
1158
                        if((opts & 0x1) > 0){
1159
                                double db41 = bb.getDouble();
1160
                                x = db41;
1161
                        }
1162
                        
1163
                        if((opts & 0x2) > 0){
1164
                                double db42 = bb.getDouble();
1165
                                y = db42;
1166
                        }
1167
                        
1168
                        if((opts & 0x4) > 0){
1169
                                double db43 = bb.getDouble();
1170
                                z = db43;
1171
                        }
1172
                        
1173
                        insert.setScale(new double[]{x, y, z});
1174
                        
1175
                        if((opts & 0x8) > 0){
1176
                                double db50 = bb.getDouble();
1177
                                insert.setRotation(db50);
1178
                        }
1179
                        
1180
                        if((opts & 0x10) > 0){
1181
                                short w70 = bb.getShort();
1182
                                //column counts
1183
                        }
1184
                        //creo que esto est? mal, y que debe poner 0x20
1185
                        if((opts & 0x10) > 0){
1186
                                short w71 = bb.getShort();
1187
                                //row counts
1188
                        }
1189
                        
1190
                        if((opts & 0x40) > 0){
1191
                                double db44 = bb.getDouble();
1192
                                //column spacing
1193
                        }
1194
                        
1195
                        if((opts & 0x80) > 0){
1196
                                double db45 = bb.getDouble();
1197
                                //row spacing
1198
                        }
1199
                        insert.setExtrusion(new double[]{0, 0, 1});
1200
                }
1201
        }
1202
        
1203
        class AttDefReader implements EntityReader{
1204
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1205
                        double[] p10 = getPoint(false);
1206
                        String s1 = getString();
1207
                        String s3 = getString();
1208
                        String s2 = getString();
1209
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1210
                        byte b70 = bb.get();
1211
                        
1212
                        if((opts & 0x1) > 0){
1213
                                byte b73 = bb.get();
1214
                        }
1215
                        
1216
                        if((opts & 0x2) > 0){
1217
                                double d50 = bb.getDouble();
1218
                        }
1219
                        
1220
                        if((opts & 0x4) > 0){
1221
                                double d41 = bb.getDouble();
1222
                        }
1223
                        
1224
                        if((opts & 0x8) > 0){
1225
                                double d42 = bb.getDouble();
1226
                        }
1227
                        
1228
                        if((opts & 0x10) > 0){
1229
                                byte b7 = bb.get();
1230
                        }
1231
                        
1232
                        if((opts & 0x20) > 0){
1233
                                byte b71 = bb.get();
1234
                        }
1235
                        
1236
                        if((opts & 0x40) > 0){
1237
                                byte b72 = bb.get();
1238
                        }
1239
                        
1240
                        if((opts & 0x80) > 0){
1241
                                double[] p11 = getPoint(false);
1242
                        }
1243
                        
1244
                        if((opts & 0x100) > 0){
1245
                                double[] p210 = getPoint(true);
1246
                        }
1247
                        
1248
                        if((opts & 0x200) > 0){
1249
                                bb.order(ByteOrder.LITTLE_ENDIAN);
1250
                                double d38 = bb.getDouble();
1251
                        }
1252
                }
1253
        }
1254
        
1255
        class AttribReader implements EntityReader{
1256
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1257
                        double[] p10 = getPoint(false);
1258
                        
1259
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1260
                        double d40 = bb.getDouble();
1261
                        
1262
                        String s1 = getString();
1263
                        String s2 = getString();
1264
                        
1265
                        if((opts & 0x1) > 0){
1266
                                byte b73 = bb.get();
1267
                        }
1268
                        
1269
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1270
                        if((opts & 0x2) > 0){
1271
                                double d50 = bb.getDouble();        
1272
                        }
1273
                        
1274
                        if((opts & 0x4) > 0){
1275
                                double d41 = bb.getDouble();        
1276
                        }
1277
                        
1278
                        if((opts & 0x8) > 0){
1279
                                double d42 = bb.getDouble();        
1280
                        }
1281
                        
1282
                        if((opts & 0x10) > 0){
1283
                                byte b7 = bb.get();
1284
                        }
1285
                        
1286
                        if((opts & 0x20) > 0){
1287
                                byte b71 = bb.get();
1288
                        }
1289
                        
1290
                        if((opts & 0x40) > 0){
1291
                                byte b72 = bb.get();
1292
                        }
1293
                        
1294
                        if((opts & 0x80) > 0){
1295
                                double[] p11 = getPoint(false);
1296
                        }
1297
                        double[] p210 = null;
1298
                        if((opts & 0x100) > 0){
1299
                                p210 = getPoint(true);
1300
                        }else{
1301
                                p210 = new double[]{0, 0, 1};
1302
                        }
1303
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1304
                        if((opts & 0x200) > 0){
1305
                                double d38 = bb.getDouble();
1306
                        }
1307
                }
1308
        }
1309
        
1310
        
1311
        class SbEndReader implements EntityReader{
1312
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1313
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1314
                        int l = bb.getInt();
1315
                }
1316
        }
1317
        
1318
        class PlineReader extends DefferedEntityReader{
1319
                
1320
                /*
1321
                 * CURVE TYPE CONSTANTS
1322
                 * */
1323
                final static int CLOSED       = 0x01;//if line is a mesh, curve closed in M direction
1324
                final static int CURVE_FIT    = 0x02;
1325
                final static int SPLINE_FIT     = 0x04;
1326
                final static int PLINE3D    = 0x08;
1327
                final static int MESH          = 0x10;
1328
                final static int MESH_CLOSED   = 0x20;//curve closed in N direction
1329
                final static int ANY_MESH = 0x30;  //MESH | MESH_CLOSED
1330
                final static int PFACE          = 0x40;
1331
                final static int CONT_LTYPE   = 0x80;
1332
                
1333
                /*
1334
                 * polyline attributes
1335
                 * */
1336
                /**
1337
                 * flag: curve type (CLOSED, MESH,PFACE, etc.)
1338
                 * */
1339
                byte flag70;
1340
                /**
1341
                 * Number of points in M direction for a Mesh,
1342
                 * number of vertices for a PFace polyline
1343
                 * */
1344
                byte meshM71;
1345
                /**
1346
                 * Number of points in N direction for a Mesh,
1347
                 * number of faces for a PFace polyline
1348
                 * */
1349
                byte meshN72;
1350
                double startW40;
1351
                byte smoothM73;
1352
                byte smoothN74;
1353
                byte curveType75;
1354
                
1355
                
1356
                private void reset(){
1357
                        flag70 = 0;
1358
                        meshM71 = 0;
1359
                        meshN72 = 0;
1360
                        startW40 = 0;
1361
                        smoothM73 = 0;
1362
                        smoothN74 = 0;
1363
                        curveType75 = 0;
1364
                }
1365
                
1366
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1367
                        super.read(bb, flags, opts, dwgObj);
1368
                        
1369
                        //TODO El byte 70 es el que determina el tipo de Polyline
1370
                        if( (opts & 0x1) > 0){
1371
                                flag70 = bb.get();
1372
                        }
1373
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1374
                        if( (opts & 0x2) > 0){
1375
                                startW40 = bb.getDouble();
1376
                        }
1377
                        
1378
                        if( (opts & 0x4) > 0){
1379
                                meshM71 = bb.get();
1380
                        }
1381
                        
1382
                        if( (opts & 0x8) > 0){
1383
                                meshN72 = bb.get();
1384
                        }
1385
                        
1386
                        if( (opts & 0x10) > 0){
1387
                                smoothM73 = bb.get();
1388
                        }
1389
                        
1390
                        if( (opts & 0x20) > 0){
1391
                                smoothN74 = bb.get();
1392
                        }
1393
                        
1394
                        if( (opts & 0x40) > 0){
1395
                                curveType75 = bb.get();
1396
                        }
1397
                }
1398

    
1399
                DwgObject getDwgObject(int index) {
1400
                        DwgObject solution = null;
1401
                        boolean isSpline = (flag70 & SPLINE_FIT) != 0 ? true: false;
1402
                        if( (flag70 & PFACE) != 0){
1403
                                //PFacePolyline
1404
                                solution = new DwgPFacePolyline(index);
1405
//        often made wrong, so we have to correct...TODO Revisar
1406
                                if(meshM71 <= 0)
1407
                                        meshM71 = 16;
1408
                                if(meshN72 <= 0)
1409
                                        meshN72 = 4;
1410
                                ((DwgPFacePolyline)solution).setVertexCount(meshM71);
1411
                                ((DwgPFacePolyline)solution).setFaceCount(meshN72);
1412
                        }else if((flag70 & ANY_MESH) != 0){
1413
                                //Mesh, closed or not
1414
                                solution = new DwgMeshPolyline(index);
1415
                                boolean isClosedM = (flag70 & CLOSED) != 0 ? true: false;
1416
                                boolean isClosedN = (flag70 & MESH_CLOSED) > 0 ? true: false;
1417
                                
1418
                                ((DwgMeshPolyline)solution).setClosedM(isClosedM);
1419
                                ((DwgMeshPolyline)solution).setClosedN(isClosedN);
1420
                                if(isSpline){
1421
                                        ((DwgMeshPolyline)solution).setMVerticies(smoothM73);
1422
                                        ((DwgMeshPolyline)solution).setNVerticies(smoothN74);
1423
                                }else{
1424
                                        ((DwgMeshPolyline)solution).setMVerticies(meshM71);
1425
                                        ((DwgMeshPolyline)solution).setNVerticies(meshN72);
1426
                                }
1427
                                ((DwgMeshPolyline)solution).setCurveType(curveType75);
1428
                        }else{
1429
                                //polyline
1430
                                boolean is3DPolyline = (flag70 & PLINE3D) != 0 ? true: false;
1431
                                if(is3DPolyline)
1432
                                {
1433
                                        solution = new DwgPolyline3D(index);
1434
                                        boolean isClosed = (flag70 & CLOSED) != 0 ? true: false;
1435
                                        //for compatibility with dwg 13 and later, we use a byte flag for
1436
                                        //closed and spline properties
1437
                                        ((DwgPolyline3D)solution).setClosedFlags(isClosed ? 0x1: 0x0);
1438
                                        ((DwgPolyline3D)solution).setSplineFlags(isSpline ? 0x1: 0x0);
1439
                                        
1440
                                }else{
1441
                                        solution = new DwgPolyline2D(index);
1442
                                        ((DwgPolyline2D)solution).setCurveType(curveType75);
1443
                                        ((DwgPolyline2D)solution).setInitWidth(startW40);
1444
                                }
1445
                        }
1446
                        
1447
                        reset();
1448
                        
1449
                        return solution;
1450
                }
1451
        }
1452
        
1453
        class VertexReader extends DefferedEntityReader{
1454
                final static int FIT_POINT    = 0x01;
1455
                final static int TANGENT      = 0x02;
1456
                final static int SPLINE_LINE_FIT     = 0x08;
1457
            final static int SPLINE_CONTROL_POINT      = 0x10;
1458
            final static int POLYLINE_3D      = 0x20;
1459
                final static int MESH_3D       = 0x40;
1460
                final static int PFACE_MESH  = 0x80;
1461
                
1462
                /**
1463
                 * Coordinates of the vertex
1464
                 * */
1465
                double[] pt10;
1466
                
1467
                /**
1468
                 * Start width of the vertex. If 0, it will
1469
                 * use the start with of the owner polyline.
1470
                 * */
1471
                double startWidth40;
1472
                /**
1473
                 * End width of the vertex. If 0, it will
1474
                 * use the end with of the owner polyline.
1475
                 * */
1476
                double endWidth41;
1477
                
1478
                /**
1479
                 * Bulge of the vertex
1480
                 * */
1481
                double tangentDir50;
1482
                
1483
                /**
1484
                 * Flag that maks what kind of vertex is:
1485
          1        | Extra vertex created by curve-fitting       |
1486
          2        | Curve-fit tangent defined for this vertex.  |
1487
          |          | A curve-fit tangent direction of 0 may be   |
1488
          |          | omitted from the DXF output, but is         |
1489
          |          | significant if this bit is set              |
1490
          |----------|---------------------------------------------|
1491
          | 4        | Unused (never set in DXF files)             |
1492
          |----------|---------------------------------------------|
1493
          | 8        | Spline vertex created by spline-fitting     |
1494
          |----------|---------------------------------------------|
1495
          | 16       | Spline frame control point                  |
1496
          |----------|---------------------------------------------|
1497
          | 32       | 3D Polyline vertex                          |
1498
          |----------|---------------------------------------------|
1499
          | 64       | 3D polygon mesh vertex                      |
1500
          |----------|---------------------------------------------|
1501
          | 128      | Polyface mesh vertex                        |
1502
          +--------------------------------------------------------+
1503
                 * */
1504
                byte vertexFlag70;
1505
                
1506
                /**
1507
                 * If the vertex is a pfaceface vertex it hasnt real coordinates.
1508
                 * Instead it has an index for each vertex of the mesh's face
1509
                 * */
1510
                int[] pfacefaceIndex;
1511
                
1512
                void reset(){
1513
                        pt10 = null;
1514
                        startWidth40 = 0;
1515
                        endWidth41 = 0;
1516
                        tangentDir50 = 0;
1517
                        vertexFlag70 = 0;
1518
                        pfacefaceIndex = null;
1519
                
1520
                }
1521
                
1522
                /*
1523
                 * azabala
1524
                 * Nos estabamos encontrando con vertices muy raros
1525
                 * (e incluso con valores NaN) cuando el valor de opts
1526
                 * es 16872, si seguiamos al pie de la letra la especificaci?n
1527
                 * de http://www.iwriteiam.nl/DWG12.html o Pythoncad.
1528
                 * 
1529
                 * Haciendo un poco de ingenieria inversa hemos visto que
1530
                 * si opts==16872, hay que modificar el algoritmo 
1531
                 * */
1532
                
1533
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1534
                        super.read(bb, flags, opts, dwgObj);
1535
                        if(opts != 16872){
1536
                                int position = bb.position();
1537
                                pt10 = getPoint(false);
1538
if(pt10[0] < 0 || pt10[0] < 600000 || pt10[0] > 800000){
1539
System.currentTimeMillis();
1540
}
1541
                                bb.order(ByteOrder.LITTLE_ENDIAN);
1542
                                if((opts & 0x1) > 0){
1543
                                        startWidth40 = bb.getDouble();
1544
                                }
1545
                                if((opts & 0x2) > 0){
1546
                                        endWidth41 = bb.getDouble();
1547
                                }
1548
                                if((opts & 0x4) > 0){
1549
                                        tangentDir50 = bb.getDouble();
1550
                                }
1551
                                if((opts & 0x8) > 0){
1552
                                        vertexFlag70 = bb.get();
1553
                                }
1554
                        }else{
1555
                                //if opts == 16872 (decimal) we invert the
1556
                                //order of the reading
1557
                                bb.order(ByteOrder.LITTLE_ENDIAN);
1558
                                if((opts & 0x1) > 0){
1559
                                        startWidth40 = bb.getDouble();
1560
                                }
1561
                                if((opts & 0x2) > 0){
1562
                                        endWidth41 = bb.getDouble();
1563
                                }
1564
                                if((opts & 0x4) > 0){
1565
                                        tangentDir50 = bb.getDouble();
1566
                                }
1567
                                if((opts & 0x8) > 0){
1568
                                        vertexFlag70 = bb.get();
1569
                                }
1570
                                int p1 = bb.getShort();
1571
                                int p2 = bb.getShort();
1572
                                int p3 = bb.getShort();
1573
                                int p4 = bb.getShort();
1574
                                
1575
                                pfacefaceIndex = new int[]{p1,p2,p3,p4};
1576
                        }
1577
                        
1578
                        
1579
                        
1580
                }
1581

    
1582
                DwgObject getDwgObject(int index) {
1583
                        DwgObject solution = null;
1584
                        if( (vertexFlag70 & PFACE_MESH) != 0){
1585
                                //It is a PFace Mesh Vertex
1586
                                if( (vertexFlag70 & MESH_3D) != 0){
1587
                                        solution = new DwgVertexPFace(index);
1588
                                        ((DwgVertexPFace)solution).setPoint(pt10);
1589
                                        ((DwgVertexPFace)solution).setFlags(vertexFlag70);
1590
                                }else{
1591
                                        /*
1592
                                        azabala
1593
                                         DXF 12 spec says:
1594
                                                 "If the Vertex defines a face of the mesh, 
1595
                                                 its Vertex flags (70) group has the 128 bit 
1596
                                                 set but not the 64 bit. The 10, 
1597
                                                 20, and 30 (location) groups of the face entity are 
1598
                                                 irrelevant and are always written as zero in a DXF file. 
1599
                                                 The vertex indexes that define the mesh are given by 71, 
1600
                                                 72, 73, and 74 groups, the values of which are integers 
1601
                                                 specifying one of the previously defined vertices by 
1602
                                                 index. 
1603
                                                 If the index is negative, the edge that begins with 
1604
                                                 that vertex is invisible. 
1605
                                                 
1606
                                                 The first zero vertex marks the 
1607
                                                 end of the vertices of the face. 
1608
                                                 
1609
                                                 Since the 71 through 74 
1610
                                                 groups are optional fields with default values of zero, 
1611
                                                 they are present in DXF only if nonzero."
1612
                                                 
1613
                                         But DWG 12 spec doesnt say anything about 71,72,73 and
1614
                                         74 fields for VERTEX.        
1615
                                         * */
1616
                                        solution = new DwgVertexPFaceFace(index);
1617
                                        ((DwgVertexPFaceFace)solution).setVerticesidx(pfacefaceIndex);
1618
                                }
1619
                        }else if( (vertexFlag70 & POLYLINE_3D) != 0){
1620
                                solution = new DwgVertex3D(index);
1621
                                ((DwgVertex3D)solution).setPoint(pt10);
1622
                                ((DwgVertex3D)solution).setFlags(vertexFlag70);
1623
                        }else{
1624
                                solution = new DwgVertex2D(index);
1625
                                ((DwgVertex2D)solution).setPoint(pt10);
1626
                                ((DwgVertex2D)solution).setFlags(vertexFlag70);
1627
                        }
1628
                        
1629
                        reset();
1630
                        return solution;
1631
                }
1632
        }
1633
        
1634
        class Face3DReader implements EntityReader{
1635
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1636
                        boolean zflag = false;
1637
                        if((flags & 0x4) > 0){
1638
                                zflag = true;
1639
                        }
1640
                        double[] pt10 = getPoint(zflag);
1641
                        double[] pt11 = getPoint(zflag);
1642
                        double[] pt12 = getPoint(zflag);
1643
                        double[] pt13 = getPoint(zflag);
1644
                
1645
                }
1646
        }
1647
        
1648
        class DimReader implements EntityReader{
1649
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1650
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1651
                        short w1 = bb.getShort();
1652
                        double[] pt10 = getPoint(true);
1653
                        double[] pt11 = getPoint(false);
1654
                        
1655
                        if((opts & 0x2) > 0){
1656
                                byte b70 = bb.get();
1657
                        }
1658
                        
1659
                        if((opts & 0x1) > 0){
1660
                                double[] pt12 = getPoint(true);
1661
                        }
1662
                        
1663
                        if((opts & 0x4) > 0){
1664
                                String s1 = getString();
1665
                        }
1666
                        
1667
                        if((opts & 0x8) > 0){
1668
                                double[] pt13 = getPoint(true);
1669
                        }
1670
                        
1671
                        if((opts & 0x10) > 0){
1672
                                double[] pt13 = getPoint(true);
1673
                        }
1674
                        
1675
                        if((opts & 0x20) > 0){
1676
                                double[] pt15 = getPoint(true);
1677
                        }
1678
                        
1679
                        if((opts & 0x40) > 0){
1680
                                double[] pt16 = getPoint(true);
1681
                        }
1682
                        
1683
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1684
                        if((opts & 0x80) > 0){
1685
                                double d40 = bb.getDouble();
1686
                        }
1687
                        
1688
                        if((opts & 0x100) > 0){
1689
                                double d50 = bb.getDouble();
1690
                        }
1691
                        
1692
                        if((opts & 0x200) > 0){
1693
                                double d51 = bb.getDouble();
1694
                        }
1695
                        if((opts & 0x400) > 0){
1696
                                double d52 = bb.getDouble();
1697
                        }
1698
                        if((opts & 0x800) > 0){
1699
                                double d53 = bb.getDouble();
1700
                        }
1701
                }
1702
        }
1703
        
1704
        class VPortReader implements EntityReader{
1705
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1706
                        double[] pt10 = getPoint(true);
1707
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1708
                        double d40 = bb.getDouble();
1709
                        double d41 = bb.getDouble();
1710
                        short w68 = bb.getShort();
1711
                }
1712
        }
1713
        
1714
        /**
1715
         * @param start
1716
         * @param end
1717
         */
1718
        private void readEntities(int start, int end) {
1719
                bb.position(start);
1720
                int ant = bb.position();
1721
                int emax = readers.size();
1722
                EntityReader reader = null;
1723
                
1724
                /*
1725
                 * it isnt null until well finish to read the vertices
1726
                 * of a given polyline (seqend found)
1727
                 * 
1728
                 */
1729
                IDwgPolyline currentPolyline = null;
1730
                
1731
                /*
1732
                 * Not null when a DwgBlock is found, it will be null
1733
                 * when a DwgEndBlk found. While this, all entities readed
1734
                 * will be added to currentBlock
1735
                 * */
1736
                DwgBlockHeader currentBlock = null;
1737
                
1738
                while(ant < (end - 32)){
1739
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1740
                        
1741
                        byte kind = bb.get();
1742
                        if(kind < emax){
1743
                                reader = (EntityReader) readers.get(kind);
1744
                        }//if
1745
                        
1746
                        
1747
                        //PROPERTIES COMMON TO ALL DWG 12 ENTITIES
1748
                        byte flag = bb.get();
1749
                        short lenght = bb.getShort();
1750
                        
1751
                        //segun esto los dos ultimos bytes son el CRC
1752
                        int crcpos = ant + (lenght - 2);
1753
                        
1754
                        
1755
                        short layer = bb.getShort();
1756
                        short opts = bb.getShort();
1757
                        
1758
                        byte color = 0;
1759
                        if ((flag & 0x1) > 0){
1760
                                color = bb.get();
1761
                        }
1762
                        
1763
                        byte extra = 0;
1764
                        if ((flag & 0x40) > 0)
1765
                                extra = bb.get();
1766
                        
1767
                        
1768
                        String xdata = null;
1769
                        if((extra & 0x2) > 0)
1770
                                xdata = readXdata();
1771
                        
1772
                        
1773
                        short type = 0;
1774
                        if((flag & 0x2) > 0)
1775
                                type = bb.getShort();
1776
                        
1777
                        
1778
                        double z = 0d;
1779
                        if( (flag & 0x4) > 0 && (kind > 2) && (kind != 22)){
1780
                                z = bb.getDouble();
1781
                        }
1782
                        
1783
                        double th = 0d;
1784
                        if((flag & 0x8) > 0){
1785
                                th = bb.getDouble();
1786
                        }
1787
                        
1788
                        byte[] handle = null;
1789
                        if((flag & 0x20) > 0)
1790
                                handle = getHandle();
1791
                        
1792
                        short paper = 0;
1793
                        if((extra & 0x4) > 0){
1794
                                paper = bb.getShort();
1795
                        }
1796
                        
1797
                        if(reader != null){
1798
                                DwgObject entity = null;
1799
                                
1800
                                entity = DwgObjectFactory.
1801
                                                        getInstance().
1802
                                                        create(kind, index);
1803
                                
1804
                                //TODO Idem con el espacio papel o el espacio modelo
1805
                                boolean paperSpace = false;
1806
                                if(paper != 0){
1807
                                        paperSpace = true;
1808
                                }
1809
                                reader.read(bb, flag, opts, entity);
1810
                                if(reader instanceof DefferedEntityReader){
1811
                                        entity = ((DefferedEntityReader)reader).getDwgObject(index);        
1812
                                }
1813
                                
1814
                                if(entity instanceof IDwgPolyline){
1815
                                        currentPolyline = (IDwgPolyline) entity;
1816
                                }
1817
                                else if(entity instanceof DwgSeqend){
1818
                                        currentPolyline = null;
1819
                                }else if(entity instanceof DwgBlockHeader){
1820
                                        currentBlock = (DwgBlockHeader) entity;
1821
                                }else if(entity instanceof DwgEndblk){
1822
                                        currentBlock = null;
1823
                                }
1824
                                
1825
                                DwgHandleReference hdl = null;
1826
                                /*
1827
                                In V12 format a handle has 2 bytes, while
1828
                                in later formats a hande has 4 bytes. To avoid
1829
                                rewriting a lot of code we are going to do some "tricks"
1830
                                with handles.
1831
                                */
1832
                                if(entity instanceof DwgBlockHeader){
1833
                                        /*
1834
                                         * If entity is a block, in a later step we'll match
1835
                                         * an insert with its block by handle.
1836
                                     * In dwg 12 format, association insert-blocks is not
1837
                                     * by handle (is from the order of the block in block table)
1838
                                     * So here we use a little trick to avoid rewriting of
1839
                                     * block and inserts management logic.
1840
                                         * */
1841
                                        int order = -1;
1842
                                        DwgBlockHeader blk = (DwgBlockHeader) entity;
1843
                                        String blockName = blk.getName();
1844
                                        Block block = getBlock(blockName);
1845
                                        if(block != null){
1846
                                                order = blocks.indexOf(block);
1847
                                                hdl = new DwgHandleReference(0, order);
1848
                                        }else{
1849
                                                System.out.println("BLOQUE "+blockName+" NO EST? EN LA TABLA DE BLOQUES");
1850
                                                bb.position(crcpos);
1851
                                                short crc = bb.getShort();
1852
                                                continue;
1853
                                        }
1854
                                }else{
1855
                                        if(handle != null){
1856
                                                int offset = handle.hashCode();
1857
                                                hdl = new DwgHandleReference(0, offset);
1858
                                        }else{
1859
                                                System.out.println("HANDLE A NULL");
1860
                                                bb.position(crcpos);
1861
                                                short crc = bb.getShort();
1862
                                                continue;
1863
                                        }
1864
                                }
1865
                                
1866
                                entity.setColor(color);
1867
                                entity.setType(type);//TODO Este type es el mismo que para DWG 13-14-2000?
1868
                                entity.setSizeInBits(lenght);//TODO Este size es el mismo que para DWG 13-14-2000?
1869
                                entity.setHandle(hdl);
1870
                                /*
1871
                                 * TODO
1872
                                 * Parece ser que DWG 12 no gestiona las layers al igual que las
1873
                                 * versiones sucesivas (hay que descifrar si 'layer' significa
1874
                                 * un orden en la tabla de layers
1875
                                 * 
1876
                                 * De ser as?, y si indexamos las layers de esta forma
1877
                                 * (con un HandleReference de code 0x5) ser? todo homogeneo
1878
                                 * 
1879
                                 * TODO Construir instancias de DwgLayer a partir de las entradas
1880
                                 * de la tabla de layers, e indexarlas con un handle igual a su orden
1881
                                 * */
1882
                                
1883
                                entity.setLayerHandle(new DwgHandleReference(0x5, layer));
1884
                                
1885
                                //TODO El valor de elevation en 12 es comun a todas, en 13 y ulteriores
1886
                                //no. ver que se hace
1887
//                                entity.setZ(z);
1888
                                
1889
                                List xdataAsList = new ArrayList();
1890
                                xdataAsList.add(xdata);
1891
                                entity.setExtendedData(xdataAsList);
1892
                                
1893
                                //TODO con thickness tenemos el mismo problema que con
1894
                                //elevation. En dwg 12 es comun a todos
1895
//                                entity.setThickness(th);
1896
                                
1897
                                ant = bb.position();
1898
//                                if(ant < crcpos){
1899
                                if(ant != crcpos){
1900
                                        bb.position(bb.position() + (crcpos - ant));
1901
                                }
1902
                                short crc = bb.getShort();
1903
                                
1904
                                if( (entity instanceof IDwgVertex) && (currentPolyline != null)){
1905
                                        currentPolyline.addVertex((IDwgVertex) entity);
1906
                                        
1907
                                }else if( (entity instanceof IDwgBlockMember) && 
1908
                                                !(entity instanceof IDwgVertex) &&
1909
                                                (currentBlock != null)){
1910
                                        //In DWG 12 vertex is not part of Block.
1911
                                        //its part of a polyline (which is part of a block)
1912
                                        currentBlock.addObject(entity);
1913
                                } else{
1914
//                                        if(! paperSpace)//TODO solo a?adimos las entidades en espacio modelo????
1915
                                        dwgFile.addDwgObject(entity);
1916
                                }
1917
                        }//if reader
1918
                        else{
1919
                                System.out.println("Reader a NULL. DWG 12 MAL LEIDO");
1920
                                System.out.println("kind = " + kind);
1921
                                bb.position(crcpos);
1922
                                short crc = bb.getShort();
1923
                                continue;
1924
                                
1925
                        }
1926
                        ant = bb.position();
1927
//                        byte[] crc32 = new byte[32];
1928
//                        bb.get(crc32);
1929
                        index++;
1930
                }//while
1931
                byte[] crc32 = new byte[32];//TODO va dentro o fuera del while??
1932
                bb.get(crc32);
1933
        }
1934

    
1935

    
1936
        /**
1937
         * @return
1938
         */
1939
        private byte[] getHandle() {
1940
                 byte[] bytes = null;
1941
                 bb.order(ByteOrder.nativeOrder());
1942
                 byte len = bb.get();
1943
                 bytes = new byte[len];
1944
                 bb.get(bytes);
1945
                 return bytes;
1946
//Ver si los handles de DWG 12 concurdan con nuestra clase
1947
//DwgHandleReference
1948
//             return (5, _len) + tuple(_bytes)
1949
        }
1950

    
1951

    
1952

    
1953
        /**
1954
         * @return
1955
         */
1956
        private String readXdata() {
1957
                String extData = "";
1958
                short xlen = bb.getShort();
1959
                while (xlen > 0){
1960
                        byte xval = bb.get();
1961
                        xlen--;
1962
                        if(xval == 0){
1963
                                if(xlen < 1)
1964
                                        break;
1965
                                byte val = bb.get();
1966
                                xlen--;
1967
                                if(r13){
1968
                                        if(xlen < 1)
1969
                                                break;
1970
                                        byte codePage = bb.get();
1971
                                        xlen--;
1972
                                }//if r13
1973
                                if(xlen < val)
1974
                                        break;
1975
                                byte[] strByte = new byte[val];
1976
                                bb.get(strByte);
1977
                                xlen -= val;
1978
                                extData += new String(strByte);
1979
                        }//if xval == 0
1980
                        else if(xval == 1 || xval == 3 || xval == 70){
1981
                                if(xlen < 2)
1982
                                        break;
1983
                                short val = bb.getShort();
1984
                                extData += val;
1985
                                xlen += 2;
1986
                        }else if(xval == 2){
1987
                                if(xlen < 1)
1988
                                        break;
1989
                                byte val = bb.get();
1990
                                if(val == 0)
1991
                                        extData += "{";
1992
                                else if(val == 1)
1993
                                        extData += "}";
1994
                                else
1995
                                        System.out.println("Byte no esperado:"+val);
1996
                        }else if(xval == 5){
1997
                                if(xlen < 8)
1998
                                        break;
1999
                                long val = bb.getLong();
2000
                                //probably it is an entity handle
2001
                                xlen -= 8;
2002
                        }else if (xval == 40 || xval == 41 || xval == 42){
2003
                                if (xlen < 8)
2004
                                        break;
2005
                                double val = bb.getDouble();
2006
                                xlen -= 8;
2007
                                extData += val;
2008
                                
2009
                        }else if (xval == 10 || xval == 11 || xval == 12 || xval == 13){
2010
                                //13 not in R12 spec, is in R13/R14
2011
                                if(xlen < 24)
2012
                                        break;
2013
                                Object point = getPoint(true);
2014
                                extData += point.toString();
2015
                                xlen -= 24;
2016
                        }else if(xval == 71){
2017
                                if (xlen < 4)
2018
                                        break;
2019
                                int val = bb.getInt();
2020
                                extData += val;
2021
                                xlen -= 4;
2022
                        }else
2023
                                xlen = 0;
2024
                        return extData;
2025
                }
2026
                /*
2027

2028
           
2029
       
2030
        elif _xval == 71:
2031
            if _xlen < 4: break
2032
            _val = struct.unpack('<l', handle.read(4))[0]
2033
            _data.append(_val)
2034
            _xlen = _xlen - 4
2035
        else:
2036
            _xlen = 0
2037
    return _data
2038
                 * */
2039
                return null;
2040
        }
2041

    
2042

    
2043

    
2044
        /**
2045
         * @param b
2046
         * @return
2047
         */
2048
        private double[] getPoint(boolean b) {
2049
                bb.order(ByteOrder.LITTLE_ENDIAN);
2050
                double x = bb.getDouble();
2051
                double y = bb.getDouble();
2052
                double z = 0d;
2053
                if(b){
2054
                        z = bb.getDouble();
2055
                }
2056
                return new double[]{x, y, z};
2057
        }
2058

    
2059

    
2060

    
2061
        //TODO Que se hacen con los registros que se leen???
2062
        private void readBlockTable(Dwg12Table blockTable) {
2063
                short size = blockTable.s1;
2064
                int numRecords =  blockTable.i1;
2065
                int start = blockTable.i2;
2066
                
2067
                int begin = -1;
2068
                int end = -1;
2069
                
2070
                for(int i = 0; i < numRecords; i++){
2071
                        
2072
                        begin = start + i * size;
2073
                        bb.position(begin);
2074
                        
2075
                        end = begin + size - 2;
2076
        
2077
                        byte flag = bb.get();
2078
                        byte[] nameByte = new byte[32];
2079
                        bb.get(nameByte);
2080
                        String name = new String(nameByte).trim();
2081
                        
2082
                        bb.order(ByteOrder.LITTLE_ENDIAN);
2083
                        
2084
                        short used = bb.getShort();
2085
                        byte b1 = bb.get();
2086
                        short w1 = bb.getShort();
2087
                        byte b2 = bb.get();
2088
                        
2089
                        short w3 = bb.getShort();
2090
                        short crc = bb.getShort();
2091
                
2092
                        int offset = end - bb.position();
2093
                        if(offset > 0)
2094
                                bb.position(bb.position() + end);
2095
                        
2096
                        Block block = new Block();
2097
                        block.flag = flag;
2098
                        block.name = name;
2099
                        block.used = used;
2100
                        block.b1 = b1;
2101
                        block.w1 = w1;
2102
                        block.b2 = b2;
2103
                        block.w3 = w3;
2104
                        block.crc = crc;
2105
                        blocks.add(block);
2106
                }//for
2107
                byte[] crc32 = new byte[32];
2108
                bb.get(crc32);
2109
        }
2110

    
2111
        public void readHeader(){
2112
                bb.order(ByteOrder.LITTLE_ENDIAN);
2113
                short w1 = bb.getShort();
2114
                double[] inBase = getPoint(true);
2115
                double[] extMin = getPoint(true);
2116
                dwgFile.setHeader("MSPACE_EXTMIN", extMin);
2117
                double[] extMax = getPoint(true);
2118
                dwgFile.setHeader("MSPACE_EXTMAX", extMax);
2119
                double[] limMin = getPoint(false);
2120
                double[] limMax = getPoint(false);
2121
                
2122
                bb.order(ByteOrder.LITTLE_ENDIAN);
2123
                double vcx = bb.getDouble();
2124
                double vcy = bb.getDouble();
2125
                double d3 = bb.getDouble();
2126
                double d4 = bb.getDouble();
2127
                
2128
                byte b1 = bb.get();
2129
                byte b2 = bb.get();
2130
                
2131
                double sx = bb.getDouble();
2132
                double sy = bb.getDouble();
2133
                
2134
                bb.order(ByteOrder.nativeOrder());
2135
                byte[] b56 = new byte[56];
2136
                bb.get(b56);
2137
                
2138
                bb.order(ByteOrder.LITTLE_ENDIAN);
2139
                double d7 = bb.getDouble();
2140
                double d8 = bb.getDouble();
2141
                double d9 = bb.getDouble();
2142
                
2143
                bb.order(ByteOrder.nativeOrder());
2144
                byte[] b18 = new byte[18];
2145
                bb.get(b18);
2146
                
2147
                bb.order(ByteOrder.LITTLE_ENDIAN);
2148
                double d10 = bb.getDouble();
2149
                
2150
                int at = bb.position();
2151
                
2152
                bb.order(ByteOrder.LITTLE_ENDIAN);
2153
                short w2 = bb.getShort();
2154
                short w3 = bb.getShort();
2155
                
2156
                bb.order(ByteOrder.nativeOrder());
2157
                byte[] b44 = new byte[44];
2158
                bb.get(b44);
2159
                
2160
                at = bb.position();
2161
                
2162
                bb.order(ByteOrder.nativeOrder());
2163
                byte[] b354 = new byte[354];
2164
                bb.get(b354);
2165
                
2166
                if( (b354[0] == 0x61) && (b354[1] == 0x63) && (b354[2] == 0x61 ) && (b354[2] == 0x64 ))
2167
                        System.out.println("Encontrada la cadena 'acad' al comienzo del bloque de 354 bytes");
2168
        
2169
                bb.position(0x3ef);
2170
        }
2171
        
2172
        class Dwg12Table{
2173
                short s1;
2174
                int i1;
2175
                int i2;
2176
        }
2177
        
2178
        public Dwg12Table getTable(){
2179
                
2180
                Dwg12Table solution = null;
2181
                bb.order(ByteOrder.LITTLE_ENDIAN);
2182
                
2183
                short s1 = bb.getShort();
2184
                int i1 = bb.getInt();
2185
                int i2 = bb.getInt();
2186
                
2187
                solution = new Dwg12Table();
2188
                solution.s1 = s1;
2189
                solution.i1 = i1;
2190
                solution.i2 = i2;
2191
                return solution;
2192
        }
2193
        
2194
        
2195
        class Dwg12TableTest{
2196
                short s1, s2, s3;
2197
                int i1;
2198
        }
2199
        public Dwg12TableTest getTableTest(){
2200
                Dwg12TableTest solution = null;
2201
                
2202
                
2203
                bb.order(ByteOrder.LITTLE_ENDIAN);
2204
                short s1 = bb.getShort();
2205
                short s2 = bb.getShort();
2206
                short s3 = bb.getShort();
2207
                int i1 = bb.getInt();
2208
                
2209
                solution = new Dwg12TableTest();
2210
                solution.s1 = s1;
2211
                solution.s2 = s2;
2212
                solution.s3 = s3;
2213
                solution.i1 = i1;
2214
                
2215
                return solution;
2216
        }
2217

    
2218
        /* (non-Javadoc)
2219
         * @see com.iver.cit.jdwglib.dwg.readers.IDwgFileReader#readObjectHeader(int[], int, com.iver.cit.jdwglib.dwg.DwgObject)
2220
         */
2221
        public int readObjectHeader(int[] data, int offset, DwgObject dwgObject) throws RuntimeException, CorruptedDwgEntityException {
2222
                return 0;
2223
        }
2224

    
2225
        /* (non-Javadoc)
2226
         * @see com.iver.cit.jdwglib.dwg.readers.IDwgFileReader#readObjectTailer(int[], int, com.iver.cit.jdwglib.dwg.DwgObject)
2227
         */
2228
        public int readObjectTailer(int[] data, int offset, DwgObject dwgObject) throws RuntimeException, CorruptedDwgEntityException {
2229
                return 0;
2230
        }
2231

    
2232
}