Statistics
| Revision:

svn-gvsig-desktop / branches / v10 / libraries / libDwg / src / com / iver / cit / jdwglib / dwg / readers / DwgFileV12Reader.java @ 10847

History | View | Annotate | Download (55.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 com.iver.cit.jdwglib.dwg.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 com.iver.cit.jdwglib.dwg.CorruptedDwgEntityException;
54
import com.iver.cit.jdwglib.dwg.DwgFile;
55
import com.iver.cit.jdwglib.dwg.DwgHandleReference;
56
import com.iver.cit.jdwglib.dwg.DwgObject;
57
import com.iver.cit.jdwglib.dwg.DwgObjectFactory;
58
import com.iver.cit.jdwglib.dwg.IDwgBlockMember;
59
import com.iver.cit.jdwglib.dwg.IDwgPolyline;
60
import com.iver.cit.jdwglib.dwg.IDwgVertex;
61
import com.iver.cit.jdwglib.dwg.objects.DwgArc;
62
import com.iver.cit.jdwglib.dwg.objects.DwgBlockHeader;
63
import com.iver.cit.jdwglib.dwg.objects.DwgCircle;
64
import com.iver.cit.jdwglib.dwg.objects.DwgEndblk;
65
import com.iver.cit.jdwglib.dwg.objects.DwgInsert;
66
import com.iver.cit.jdwglib.dwg.objects.DwgLayer;
67
import com.iver.cit.jdwglib.dwg.objects.DwgLine;
68
import com.iver.cit.jdwglib.dwg.objects.DwgMeshPolyline;
69
import com.iver.cit.jdwglib.dwg.objects.DwgPFacePolyline;
70
import com.iver.cit.jdwglib.dwg.objects.DwgPoint;
71
import com.iver.cit.jdwglib.dwg.objects.DwgPolyline2D;
72
import com.iver.cit.jdwglib.dwg.objects.DwgPolyline3D;
73
import com.iver.cit.jdwglib.dwg.objects.DwgSeqend;
74
import com.iver.cit.jdwglib.dwg.objects.DwgSolid;
75
import com.iver.cit.jdwglib.dwg.objects.DwgText;
76
import com.iver.cit.jdwglib.dwg.objects.DwgVertex2D;
77
import com.iver.cit.jdwglib.dwg.objects.DwgVertex3D;
78
import com.iver.cit.jdwglib.dwg.objects.DwgVertexPFace;
79
import com.iver.cit.jdwglib.dwg.objects.DwgVertexPFaceFace;
80

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

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

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

    
334

    
335

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

    
411

    
412

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

    
441

    
442

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

    
500

    
501

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

    
538

    
539

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

    
588

    
589

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

    
629

    
630

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

    
666

    
667

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

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

    
738

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

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

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

    
1934

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

    
1950

    
1951

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

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

    
2041

    
2042

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

    
2058

    
2059

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

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

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

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

    
2231
}