Statistics
| Revision:

root / trunk / libraries / libDwg / src / com / iver / cit / jdwglib / dwg / DwgFile.java @ 10820

History | View | Annotate | Download (26 KB)

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

    
37
import java.awt.geom.Point2D;
38
import java.io.File;
39
import java.io.FileInputStream;
40
import java.io.IOException;
41
import java.nio.ByteBuffer;
42
import java.nio.channels.FileChannel;
43
import java.util.ArrayList;
44
import java.util.HashMap;
45
import java.util.Iterator;
46
import java.util.List;
47
import java.util.Map;
48
import java.util.Vector;
49

    
50
import org.apache.log4j.Logger;
51

    
52
import com.iver.cit.jdwglib.dwg.objects.DwgBlockHeader;
53
import com.iver.cit.jdwglib.dwg.objects.DwgInsert;
54
import com.iver.cit.jdwglib.dwg.objects.DwgLayer;
55
import com.iver.cit.jdwglib.dwg.readers.DwgFileV12Reader;
56
import com.iver.cit.jdwglib.dwg.readers.DwgFileV14Reader;
57
import com.iver.cit.jdwglib.dwg.readers.DwgFileV15Reader;
58
import com.iver.cit.jdwglib.dwg.readers.IDwgFileReader;
59

    
60
/**
61
 * The DwgFile class provides a revision-neutral interface for reading and handling
62
 * DWG files
63
 * Reading methods are useful for reading DWG files, and handling methods like
64
 * calculateDwgPolylines() are useful for handling more complex
65
 * objects in the DWG file
66
 * 
67
 * @author jmorell
68
 * @author azabala
69
 */
70
public class DwgFile {
71
        /**
72
         * It has all known DWG version's header.
73
         * Extracted from Autodesk web.
74
         */
75
        private static HashMap acadVersions = new HashMap();
76
        static{
77
                acadVersions.put("AC1004", "Autocad R9");
78
                acadVersions.put("AC1006", "Autocad R10");
79
                acadVersions.put("AC1007", "Autocad pre-R11");
80
                acadVersions.put("AC1007", "Autocad pre-R11");
81
                acadVersions.put("AC1008", "Autocad pre-R11b");
82
                acadVersions.put("AC1009", "Autocad R12");
83
                acadVersions.put("AC1010", "Autocad pre-R13 a");
84
                acadVersions.put("AC1011", "Autocad pre-R13 b");
85
                acadVersions.put("AC1012", "Autocad R13");
86
                acadVersions.put("AC1013", "Autocad pre-R14");
87
                acadVersions.put("AC1014", "Autocad R14");
88
                acadVersions.put("AC1500", "Autocad pre-2000");
89
                acadVersions.put("AC1015", "Autocad R2000, R2000i, R2002");
90
                acadVersions.put("AC402a", "Autocad pre-2004a");
91
                acadVersions.put("AC402b", "Autocad pre-2004b");
92
                acadVersions.put("AC1018", "Autocad R2004, R2005, R2006");
93
                acadVersions.put("AC1021", "Autocad R2007");
94
        
95
        }
96
        
97
        private static Logger logger = Logger.getLogger(DwgFile.class
98
                        .getName());
99
        /**
100
         * Path and name of the dwg file
101
         * */
102
        private String fileName;
103
        /**
104
         * DWG version of the file (AC1013, AC1018, etc.)
105
         * */
106
        private String dwgVersion;
107
        
108
        /**
109
         * Offsets to the DWG sections
110
         */
111
        private ArrayList dwgSectionOffsets;
112
        /**
113
         * Header vars readed from the HEADER section of the DWG file
114
         * */
115
        private Map headerVars;
116
        
117
        /**
118
         * This list contains what in OpenDWG specification is called
119
         * the object map ( a collection of entries where each entry contains
120
         * the seek of each object, and its size)
121
         * */
122
        private ArrayList dwgObjectOffsets;
123
        
124
        /**
125
         * For each entry in dwgObjectOffsets, we have an instance of
126
         * DwgObject in the dwgObjects collection
127
         * 
128
         * */
129
        private List dwgObjects;
130
        private HashMap handle_objects;
131
        
132

    
133
        private ArrayList dwgClasses;
134
        
135
        
136
        /**
137
         * hash map that indexes all DwgLayer objects
138
         * by its handle property
139
         * */
140
        private HashMap layerTable; 
141
        
142
        /**
143
         * Specific reader of the DWG file version (12, 13, 14, 2000, etc., each
144
         * version will have an specific reader)
145
         * */
146
        private IDwgFileReader dwgReader;
147
        private boolean dwg3DFile;
148
        /**
149
         * Memory mapped byte buffer of the whole DWG file
150
         * */
151
        private ByteBuffer bb;
152
        
153
        /*
154
         * Optimizaciones para evitar leer el fichero completo en cada
155
         * pasada.
156
         * */
157
        /**
158
         * Contains all IDwgPolyline implementations
159
         * */
160
        private List dwgPolylines;
161
        /**
162
         * Contains all INSERT entities of the dwg file
163
         * (these entities must be processed in a second pass)
164
         * 
165
         * */
166
        private List insertList;
167
        
168
        private List blockList;
169
        
170

    
171
        /**
172
         * Constructor.
173
         * @param fileName an absolute path to the DWG file
174
         */
175
        public DwgFile(String fileName) {
176
                this.fileName = fileName;
177
                
178
                dwgSectionOffsets = new ArrayList();
179
                dwgObjectOffsets = new ArrayList();
180
                headerVars = new HashMap();
181
                
182
                dwgClasses = new ArrayList();
183
                
184
                dwgObjects = new ArrayList();
185
                handle_objects = new HashMap();
186
                
187
                layerTable = new HashMap();
188
                
189
                dwgPolylines = new ArrayList();
190
                insertList = new ArrayList();
191
                
192
                blockList = new ArrayList();
193
        }
194
        
195
        public String getDwgVersion() {
196
                return dwgVersion;
197
        }
198
        
199
        /**
200
         * Reads a DWG file and put its objects in the dwgObjects Vector
201
         * This method is version independent
202
         * 
203
         * @throws IOException If the file location is wrong
204
         */
205
        public void read() throws IOException, 
206
                                DwgVersionNotSupportedException
207
        {
208
                setDwgVersion();
209
                if (dwgVersion.equalsIgnoreCase("Autocad R2000, R2000i, R2002")) {
210
                        dwgReader = new DwgFileV15Reader();
211
                }else if (dwgVersion.equalsIgnoreCase("Autocad pre-R14")|| 
212
                                dwgVersion.equalsIgnoreCase("Autocad R14") ||
213
                                dwgVersion.equalsIgnoreCase("Autocad R13")) {
214
                        dwgReader = new DwgFileV14Reader();
215
                } else if (dwgVersion.equalsIgnoreCase("Autocad R12")|| 
216
                                dwgVersion.equalsIgnoreCase("Autocad pre-R13 a") ||
217
                                dwgVersion.equalsIgnoreCase("Autocad pre-R13 b")) {
218
                        
219
                        boolean isR13 = true;
220
                        if(dwgVersion.equalsIgnoreCase("Autocad R12"))
221
                                        isR13 = false;
222
                        dwgReader = new DwgFileV12Reader(isR13);
223
                }else {
224
                        DwgVersionNotSupportedException exception = 
225
                                new DwgVersionNotSupportedException("Version de DWG no soportada");
226
                        exception.setDwgVersion(dwgVersion);
227
                        throw exception;
228
                }
229
                try{
230
                dwgReader.read(this, bb);
231
                }catch(Throwable t){
232
                        t.printStackTrace();
233
                        throw new IOException("Error leyendo dwg");
234
                }
235
        }
236
        
237
        private void setDwgVersion() throws IOException {
238
                File file = new File(fileName);
239
                FileInputStream fileInputStream = new FileInputStream(file);
240
                FileChannel fileChannel = fileInputStream.getChannel();
241
                long channelSize = fileChannel.size();
242
                bb = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, channelSize);
243
                byte[] versionBytes = {bb.get(0), 
244
                                                                bb.get(1), 
245
                                                                bb.get(2),
246
                                                                bb.get(3),
247
                                                                bb.get(4), 
248
                                                                bb.get(5)};
249
                ByteBuffer versionByteBuffer = ByteBuffer.wrap(versionBytes);
250
                String[] bs = new String[versionByteBuffer.capacity()];
251
                String versionString = "";
252
                for (int i=0; i<versionByteBuffer.capacity(); i++) {
253
                        bs[i] = new String(new byte[]{(byte)(versionByteBuffer.get(i))});
254
                        versionString = versionString + bs[i];
255
                }
256
                String version = (String) acadVersions.get(versionString);
257
                if(version == null)
258
                        version = "Unknown Dwg format";
259
                this.dwgVersion = version;    
260
        }
261
        
262
        public void setHeader(String key, Object value){
263
                headerVars.put(key, value);
264
        }
265
        
266
        public Object getHeader(String key){
267
                return headerVars.get(key);
268
        }
269
        
270
        /*
271
         * A DwgLayer is a DWG drawing entity, so all DwgLayer objects are
272
         * saved in dwgObjects collection.
273
         * Instead of iterate over the full collection, is faster check every object
274
         * and save all the DwgLayer instances in their own collection.
275
         *
276
         */
277
        protected void addDwgLayer(DwgLayer dwgLayer){
278
                layerTable.put(new Integer(dwgLayer.getHandle().getOffset()), 
279
                                dwgLayer);
280
        }
281
        
282
        private void printInfoOfAObject (DwgObject entity){
283
                logger.info("index = "+entity.getIndex() + " entity.type = " + entity.type + " entityClassName = "+ entity.getClass().getName());
284
                logger.info("handleCode = "+entity.getHandle().getCode());
285
                logger.info("entityLayerHandle = "+entity.getHandle().getOffset());
286
                if(entity.hasLayerHandle()){
287
                        logger.info("layerHandleCode = "+entity.getLayerHandle().getCode());
288
                        logger.info("layerHandle = "+entity.getLayerHandle().getOffset());
289
                }
290
                if(entity.hasSubEntityHandle()){
291
                        logger.info("subEntityHandleCode = "+entity.getSubEntityHandle().getCode());
292
                        logger.info("subEntityHandle = "+entity.getSubEntityHandle().getOffset());
293
                }
294
                if(entity.hasNextHandle()){
295
                        logger.info("nextHandleCode = "+entity.getNextHandle().getCode());
296
                        logger.info("nextHandle = "+entity.getNextHandle().getOffset());
297
                }
298
                if(entity.hasPreviousHandle()){
299
                        logger.info ("previousHandleCode = "+entity.getPreviousHandle().getCode());
300
                        logger.info ("previousHandle = "+entity.getPreviousHandle().getOffset());
301
                }
302
                if(entity.hasXDicObjHandle()){
303
                        logger.info ("xDicObjHandleCode = "+entity.getXDicObjHandle());
304
                        logger.info ("xDicObjHandle = "+entity.getXDicObjHandle());
305
                }
306
                if(entity.hasReactorsHandles()){
307
                        ArrayList reactorsHandles = entity.getReactorsHandles();
308
                        int size = reactorsHandles.size();
309
                        logger.info ("NUMERO DE reactors = "+size);
310
                        DwgHandleReference hr;
311
                        for(int i=0; i<size; i++){
312
                                hr=(DwgHandleReference)reactorsHandles.get(i);
313
                                logger.info ("reactorHandleCode = "+hr.getCode());
314
                                logger.info (" reactorHandle = "+hr.getOffset());
315
                        }
316
                }
317
                
318
        }
319
        public DwgLayer getDwgLayer(DwgObject entity){
320
                DwgHandleReference handle = entity.getLayerHandle();
321
                if(handle == null){
322
                        return null;
323
                }
324
                int        handleCode = handle.getCode();
325
                int        entityLayerHandle = entity.getLayerHandle().getOffset();
326
                int layerHandle = -1;
327
                
328
                int entityRecord;
329
                DwgObject object;
330
                
331
                
332
                /*
333
                 * OpenDWG spec, v3, page 11. HANDLE REFERENCES
334
                 * 
335
                 * A handle is formed by this fields:
336
                 * a) CODE (4 bits)
337
                 * b) COUNTER (4 bits)
338
                 * c) OFFSET of the object (handle itself).
339
                 * 
340
                 * CODE could take these values:
341
                 * 1) 0x2, 0x3, 0x4, 0x5 -> offset is the handle of the layer
342
                 * 2) 0x6 -> offset is the next object handle
343
                 * 3) 0x8 -> offset is the previous object handle
344
                 * 4) 0xA -> result is reference handle plus offset
345
                  * 5) 0xC -> result is reference handle minus offset
346
                 * 
347
                 * */
348
                
349
                // FIXME: Esto no esta terminado. Falta considerar los codigo
350
                // 0x2, 0x3, 0x6, 0xA que no han aparecido en los archivos de prueba.
351
                switch(handleCode){
352
                case 0x4:
353
                        if (entity.hasNextHandle()){
354
                                int nextHandleCode = entity.getNextHandle().getCode();
355
                                if (nextHandleCode == 0x5) {
356
                                        layerHandle = entity.getNextHandle().getOffset();
357
                                } else {
358
                                        //TODO: No se han previsto nextHandleCode != 0x5
359
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
360
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
361
                                }
362
                        } else {
363
                                layerHandle = entity.getLayerHandle().getOffset();
364
                        }
365
                        break;
366
                case 0x5:
367
                        layerHandle = entity.getLayerHandle().getOffset();
368
                        break;
369
                case 0x8:
370
                        if (entity.hasNextHandle()){
371
                                int nextHandleCode = entity.getNextHandle().getCode();
372
                                if (nextHandleCode == 0x5) {
373
                                        layerHandle = entity.getNextHandle().getOffset();
374
                                } else {
375
                                        //TODO No se han previsto nextHandleCode != 0x5
376
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
377
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
378
                                }
379
                        } else {
380
                                layerHandle = entity.getHandle().getOffset() - 1;
381
                        }
382
                        break;
383
                case 0xC:
384
                        if (entity.hasNextHandle()){
385
                                int nextHandleCode = entity.getNextHandle().getCode();
386
                                if (nextHandleCode == 0x5) {
387
                                        layerHandle = entity.getNextHandle().getOffset();
388
                                } else {
389
                                        //TODO: No se han previsto nextHandleCode != 0x5
390
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
391
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
392
                                }
393
                        } else {
394
                                layerHandle = entity.getHandle().getOffset() - entity.getLayerHandle().getOffset() + 1;
395
                        }
396
                        break;
397
                default:
398
//                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+" no implementado. entityLayerHandle="+entityLayerHandle);
399
                }
400
                
401
                if(layerHandle != -1){
402
                        Iterator lyrIterator = layerTable.values().iterator();
403
                        while(lyrIterator.hasNext()){
404
                                DwgLayer lyr = (DwgLayer) lyrIterator.next();
405
                                int lyrHdl = lyr.getHandle().getOffset();
406
                                if (lyrHdl == layerHandle){
407
                                        return lyr;
408
                                }
409
                        }
410
                }
411
//                System.out.println("NO SE HA ENCONTRADO UNA CAPA CON HANDLE " + layerHandle);
412
//                printInfoOfAObject(entity);
413
                return null;
414
        }
415
        
416
        public DwgObject getDwgSuperEntity(DwgObject entity) {
417
                if(entity.hasSubEntityHandle()){
418
                        int handleCode = entity.subEntityHandle.getCode();
419
                        int offset = entity.subEntityHandle.getOffset();
420
                        int handle = -1;
421
                        
422
                        DwgObject object;
423

    
424
                        switch(handleCode){
425
                        // TODO: case 0x2:
426
                        // TODO: case 0x3:
427
                        case 0x4:
428
                        case 0x5:
429
                                handle = offset;
430
                                break;
431
                        // TODO: case 0x6:
432
                        case 0x8:
433
                                handle=entity.getHandle().getOffset() - 1;
434
                                break;
435
                        case 0xA:
436
                                handle = entity.getHandle().getOffset() + offset;
437
                                break;
438
                        case 0xC:
439
                                handle = entity.getHandle().getOffset() - offset;
440
                                break;
441
                        default:
442
                                logger.warn ("DwgObject.getDwgSuperEntity: handleCode "+handleCode+" no implementado. offset = "+offset);
443
                        }
444
                        if(handle != -1){
445
                                object = getDwgObjectFromHandle(handle);
446
                                if(object != null)
447
                                        return object;
448
                        }
449
                }
450
                return null;
451
        }
452
   
453
        public String getLayerName(DwgObject entity) {                
454
                DwgLayer dwgLayer = getDwgLayer(entity);
455
                if(dwgLayer == null){
456
                        return "";
457
                }else{
458
                        return dwgLayer.getName();
459
                }
460
        }
461
        
462
        /**
463
     * Returns the color of the layer of a DWG object 
464
         * 
465
     * @param entity DWG object which we want to know its layer color
466
         * @return int Layer color of the DWG object in the Autocad color code
467
         */
468
        public int getColorByLayer(DwgObject entity) {
469
                int colorByLayer;
470
                DwgLayer dwgLyr = getDwgLayer(entity);
471
                if(dwgLyr == null)
472
                        colorByLayer = 0;
473
                else
474
                        colorByLayer = dwgLyr.getColor();
475
                return colorByLayer;
476
        }
477
        /**
478
         * Configure the geometry of the polylines in a DWG file from the vertex list in
479
         * this DWG file. This geometry is given by an array of Points.
480
         * Besides, manage closed polylines and polylines with bulges in a GIS Data model.
481
     * It means that the arcs of the polylines will be done through a set of points and
482
     * a distance between these points.
483
         */
484
        public void calculateGisModelDwgPolylines() {
485
                /*
486
                 * In Dwg 12 format, all vertices of a polyline are between polyline entity
487
                 * and endsec entity. Also, polylines dont save any handle of their vertices (first and last).
488
                 * 
489
                 * After Dwg 12 version, we have the opposite case: polylines have handles/pointers to their
490
                 * first and last vertices.
491
                 * 
492
                 * If dwg file is not V12, we must look for all polyline vertices (and we must to wait until
493
                 * all entities are readed).
494
                 * If dwg file is V12, all polylines already have their vertices.
495
                 * */
496
                if(! (dwgReader instanceof DwgFileV12Reader)){
497
                        for (int i = 0; i < dwgPolylines.size(); i++){
498
                                DwgObject pol = (DwgObject)dwgPolylines.get(i);
499
                                if (pol instanceof IDwgPolyline) {
500
                                        ((IDwgPolyline)pol).calculateGisModel(this);
501
                                }//if 
502
                        }//for
503
                }
504
        }
505
        
506
    /**
507
     * Configure the geometry of the polylines in a DWG file from the vertex list in
508
     * this DWG file. This geometry is given by an array of Points
509
     * Besides, manage closed polylines and polylines with bulges in a GIS Data model.
510
     * It means that the arcs of the polylines will be done through a curvature
511
     * parameter called bulge associated with the points of the polyline.
512
     */
513
        //TODO Refactorizar para que solo se aplique a las Polilineas
514
        
515
//        public void calculateCadModelDwgPolylines() {
516
//                for (int i=0;i<dwgObjects.size();i++) {
517
//                        DwgObject pol = (DwgObject)dwgObjects.get(i);
518
//                        if (pol instanceof DwgPolyline2D) {
519
//                                int flags = ((DwgPolyline2D)pol).getFlags();
520
//                                int firstHandle = ((DwgPolyline2D)pol).getFirstVertexHandle().getOffset();
521
//                                int lastHandle = ((DwgPolyline2D)pol).getLastVertexHandle().getOffset();
522
//                                ArrayList pts = new ArrayList();
523
//                                ArrayList bulges = new ArrayList();
524
//                                double[] pt = new double[3];
525
//                                for (int j=0;j<dwgObjects.size();j++) {
526
//                                        DwgObject firstVertex = (DwgObject)dwgObjects.get(j);
527
//                                        if (firstVertex instanceof DwgVertex2D) {
528
//                                                int vertexHandle = firstVertex.getHandle().getOffset();
529
//                                                if (vertexHandle==firstHandle) {
530
//                                                        int k=0;
531
//                                                        while (true) {
532
//                                                                DwgObject vertex = (DwgObject)dwgObjects.get(j+k);
533
//                                                                int vHandle = vertex.getHandle().getOffset();
534
//                                                                if (vertex instanceof DwgVertex2D) {
535
//                                                                        pt = ((DwgVertex2D)vertex).getPoint();
536
//                                                                        pts.add(new Point2D.Double(pt[0], pt[1]));
537
//                                                                        double bulge = ((DwgVertex2D)vertex).getBulge();
538
//                                                                        bulges.add(new Double(bulge));
539
//                                                                        k++;
540
//                                                                        if (vHandle==lastHandle && vertex instanceof DwgVertex2D) {
541
//                                                                                break;
542
//                                                                        }
543
//                                                                } else if (vertex instanceof DwgSeqend) {
544
//                                                                        break;
545
//                                                                }
546
//                                                        }
547
//                                                }
548
//                                        }
549
//                                }
550
//                                if (pts.size()>0) {
551
//                                        /*Point2D[] newPts = new Point2D[pts.size()];
552
//                                        if ((flags & 0x1)==0x1) {
553
//                                                newPts = new Point2D[pts.size()+1];
554
//                                                for (int j=0;j<pts.size();j++) {
555
//                                                        newPts[j] = (Point2D)pts.get(j);
556
//                                                }
557
//                                                newPts[pts.size()] = (Point2D)pts.get(0);
558
//                                                bulges.add(new Double(0));
559
//                                        } else {
560
//                                                for (int j=0;j<pts.size();j++) {
561
//                                                        newPts[j] = (Point2D)pts.get(j);
562
//                                                }
563
//                                        }*/
564
//                                        double[] bs = new double[bulges.size()];
565
//                                        for (int j=0;j<bulges.size();j++) {
566
//                                                bs[j] = ((Double)bulges.get(j)).doubleValue();
567
//                                        }
568
//                                        ((DwgPolyline2D)pol).setBulges(bs);
569
//                                        //Point2D[] points = GisModelCurveCalculator.calculateGisModelBulge(newPts, bs);
570
//                                        Point2D[] points = new Point2D[pts.size()];
571
//                                        for (int j=0;j<pts.size();j++) {
572
//                                            points[j] = (Point2D)pts.get(j);
573
//                                        }
574
//                                        ((DwgPolyline2D)pol).setPts(points);
575
//                                } else {
576
////                                        System.out.println("Encontrada polil?nea sin puntos ...");
577
//                                        // TODO: No se debe mandar nunca una polil?nea sin puntos, si esto
578
//                                        // ocurre es porque existe un error que hay que corregir ...
579
//                                }
580
//                        } else if (pol instanceof DwgPolyline3D) {
581
//                        } else if (pol instanceof DwgLwPolyline && ((DwgLwPolyline)pol).getVertices()!=null) {
582
//                        }
583
//                }
584
//        }
585
        
586
        /*
587
         * TODO Revisar los bloques que son XREF
588
         * */
589
        public void blockManagement2(){
590
                Iterator it = null;
591
                
592
                
593
                //dwg v12 blocks already has their entities added
594
                //for the rest of versions, we add block entities to their owner block
595
                if(! (dwgReader instanceof DwgFileV12Reader)){
596
                        //once we have read all dwg entities, we look for all of them
597
                        //that has a superentity that is a block (to fill in the entity list
598
                        //of each block
599
                        it = dwgObjects.iterator();
600
                        int i = 0;
601
                        while(it.hasNext()){
602
                                DwgObject entity = (DwgObject)it.next();
603
                                DwgObject superEnt = getDwgSuperEntity(entity);
604
                                if(superEnt instanceof DwgBlockHeader){
605
                                        DwgBlockHeader blk = (DwgBlockHeader)superEnt;
606
                                        blk.addObject(entity);
607
                                        it.remove();//TODO Creo que esto es lento, mejor
608
                                        //el metodo original (en java solo se duplican las referencias)
609
                                        i++;
610
                                }
611
                        }//while
612
                }//if dwgfilev12
613
                
614
                //after that, we process the INSERTs
615
                it = insertList.iterator();
616
                while(it.hasNext()){
617
                        DwgInsert insert = (DwgInsert) it.next();
618
                        if(insert.isProcessed()){
619
                                //It has been processed nexted to other insert
620
                                continue;
621
                        }
622
                        insert.setProcessed(true);
623
                        double[] p = insert.getInsertionPoint();
624
                        Point2D point = new Point2D.Double(p[0], p[1]);
625
                        double[] scale = insert.getScale();
626
                        double rot = insert.getRotation();
627
                        int blockHandle = insert.getBlockHeaderHandle().getOffset();
628
                        manageInsert2(point, scale,
629
                                        rot, blockHandle, 
630
                                        dwgObjects, handle_objects);
631
                }        
632

    
633
}
634

    
635
   
636
        
637
        public void manageInsert2(Point2D insPoint, double[] scale,
638
                        double rot, int bHandle, 
639
                        List dwgObjectsWithoutBlocks, 
640
                        Map handleObjectsWithoutBlocks) {
641
                
642
                DwgObject object = (DwgObject) handle_objects.get(new Integer(bHandle));
643
                if(object == null){
644
                        logger.error("No hemos encontrado el BlockHeader cuyo handle es "+bHandle);
645
                        return;
646
                }else if(! (object instanceof DwgBlockHeader)){
647
                        //Hay un problema con la asignaci?n de handle
648
                        //Un INSERT tiene como handle de Block una entidad que no es block
649
                        logger.error("handle incorrecto." + object.getClass().getName() + " no es un blockheader");
650
                        return;
651
                }
652
                
653
                DwgBlockHeader blockHeader = (DwgBlockHeader)object;
654
                double[] bPoint = blockHeader.getBasePoint();
655
                String bname = blockHeader.getName();
656
                if (bname.startsWith("*")) 
657
                        return;
658
                
659
                //TODO Cambiar por List
660
                Vector entities = blockHeader.getObjects();
661
                if(entities.size() == 0){
662
                        logger.warn("El bloque "+blockHeader.getName()+" no tiene ninguna entidad");
663
                }
664
                Iterator blkEntIt = entities.iterator();
665
                while(blkEntIt.hasNext()){
666
                        DwgObject obj = (DwgObject) blkEntIt.next();
667
                         manageBlockEntity(obj, bPoint, 
668
                                           insPoint, scale, 
669
                                           rot, dwgObjectsWithoutBlocks,
670
                                           handleObjectsWithoutBlocks);        
671
                }//while
672
        }
673
        
674
   
675
        public int getIndexOf(DwgObject dwgObject){
676
                return dwgObjects.indexOf(dwgObject);        
677
        }
678
        
679
        
680
        
681
    /**
682
     * Changes the location of an object extracted from a block. This location will be
683
     * obtained through the insertion parameters from the block and the corresponding
684
     * insert.
685
     * @param entity, the entity extracted from the block.
686
     * @param bPoint, offset for the coordinates of the entity.
687
     * @param insPoint, coordinates of the insertion point for the entity.
688
     * @param scale, scale for the entity.
689
     * @param rot, rotation angle for the entity.
690
     * @param id, a count as a id.
691
     * @param dwgObjectsWithoutBlocks, a object list with the elements extracted from
692
     * the blocks.
693
     */
694
        private void manageBlockEntity(DwgObject entity, 
695
                                                                        double[] bPoint, 
696
                                                                        Point2D insPoint, 
697
                                                                        double[] scale, 
698
                                                                        double rot, 
699
                                                                        List dwgObjectsWithoutBlocks,
700
                                                                        Map handleObjectsWithoutBlocks) {
701
                
702
                if(entity instanceof IDwgBlockMember){
703
                        IDwgBlockMember blockMember = (IDwgBlockMember)entity;
704
                        blockMember.transform2Block(bPoint, insPoint, scale, rot, 
705
                                        dwgObjectsWithoutBlocks,
706
                                        handleObjectsWithoutBlocks,this);
707
                }
708
                
709
        }
710
        
711
        
712
        /**
713
         * Add a DWG section offset to the dwgSectionOffsets vector
714
         * 
715
         * @param key Define the DWG section
716
         * @param seek Offset of the section
717
         * @param size Size of the section
718
         */
719
        public void addDwgSectionOffset(String key, int seek, int size) {
720
                DwgSectionOffset dso = new DwgSectionOffset(key, seek, size);
721
                dwgSectionOffsets.add(dso);
722
        }
723
        
724
        /**
725
     * Returns the offset of DWG section given by its key 
726
         * 
727
     * @param key Define the DWG section
728
         * @return int Offset of the section in the DWG file
729
         */
730
        public int getDwgSectionOffset(String key) {
731
                int offset = 0;
732
                for (int i=0; i<dwgSectionOffsets.size(); i++) {
733
                        DwgSectionOffset dso = (DwgSectionOffset)dwgSectionOffsets.get(i);
734
                        String ikey = dso.getKey();
735
                        if (key.equals(ikey)) {
736
                                offset = dso.getSeek();
737
                                break;
738
                        }
739
                }
740
                return offset;
741
        }
742
        
743
        /**
744
         * Add a DWG object offset to the dwgObjectOffsets vector
745
         * 
746
         * @param handle Object handle
747
         * @param offset Offset of the object data in the DWG file
748
         */
749
        public void addDwgObjectOffset(int handle, int offset) {
750
                DwgObjectOffset doo = new DwgObjectOffset(handle, offset);
751
                dwgObjectOffsets.add(doo);
752
        }
753
        
754
        /**
755
         * 
756
         * Add a DWG object to the dwgObject vector
757
         * 
758
         * @param dwgObject DWG object
759
         */
760
        public void addDwgObject(DwgObject dwgObject){
761
                //TODO Ver si puedo inicializar las listas especificas
762
                //(IDwgPolyline, etc) aqu? 
763
                dwgObjects.add(dwgObject);
764
                handle_objects.put(new Integer(dwgObject.getHandle().getOffset()), dwgObject);
765
                
766
                /*
767
                 * TODO Quitar todos estos if-then y sustituirlos por un metodo callback
768
                 * 
769
                 * 
770
                 * (dwgObject.init(this), y que cada objeto haga lo que tenga que hacer
771
                 * */
772
                if(dwgObject instanceof DwgLayer){
773
                        this.addDwgLayer((DwgLayer) dwgObject);
774
                }
775
                
776
                //Probamos a no aplicar las extrusiones
777
                
778
                if(dwgObject instanceof IDwgExtrusionable){
779
                        ((IDwgExtrusionable)dwgObject).applyExtrussion();
780
                                
781
                }
782
                
783
                if(dwgObject instanceof IDwgPolyline){
784
                        dwgPolylines.add(dwgObject);
785
                }
786
                if(dwgObject instanceof IDwg3DTestable){
787
                        if(! dwg3DFile){//if its true, we dont check again
788
                                dwg3DFile = ((IDwg3DTestable)dwgObject).has3DData();
789
                        }
790
                }
791
                if(dwgObject instanceof DwgInsert){
792
                        insertList.add(dwgObject);
793
                }
794
                
795
                if(dwgObject instanceof DwgBlockHeader){
796
                        blockList.add(dwgObject);
797
                }
798
        }
799
        
800
        /**
801
         * Returns dwgObjects from its insertion order (position
802
         * in the dwg file)
803
         * 
804
         * @param index order in the dwg file
805
         * @return position
806
         * */
807
        public DwgObject getDwgObject(int index){
808
                return (DwgObject) dwgObjects.get(index);
809
        }
810
        
811
        public DwgObject getDwgObjectFromHandle(int handle){
812
                return (DwgObject) handle_objects.get(new Integer(handle));
813
        }
814
        
815
        /**
816
         * Add a DWG class to the dwgClasses vector
817
         * 
818
         * @param dwgClass DWG class
819
         */
820
        public void addDwgClass(DwgClass dwgClass){
821
                dwgClasses.add(dwgClass);
822
        }
823
        
824
        public void printClasses(){
825
                logger.info("#### CLASSES ####");
826
                for(int i = 0; i < dwgClasses.size(); i++){
827
                        DwgClass clazz = (DwgClass) dwgClasses.get(i);
828
                        logger.info(clazz.toString());
829
                }
830
                logger.info("#############");
831
        }
832
        
833
        public List getDwgClasses(){
834
                return dwgClasses;
835
        }
836
        
837
    /**
838
     * @return Returns the dwgObjectOffsets.
839
     */
840
    public ArrayList getDwgObjectOffsets() {
841
        return dwgObjectOffsets;
842
    }
843
    /**
844
     * @return Returns the dwgObjects.
845
     */
846
    public List getDwgObjects() {
847
        return dwgObjects;
848
    }
849
    /**
850
     * @return Returns the fileName.
851
     */
852
    public String getFileName() {
853
        return fileName;
854
    }
855
    /**
856
     * @return Returns the dwg3DFile.
857
     */
858
    public boolean isDwg3DFile() {
859
        return dwg3DFile;
860
    }
861
    /**
862
     * @param dwg3DFile The dwg3DFile to set.
863
     */
864
    public void setDwg3DFile(boolean dwg3DFile) {
865
        this.dwg3DFile = dwg3DFile;
866
    }
867
}