Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libDwg / src / com / iver / cit / jdwglib / dwg / DwgFile.java @ 10386

History | View | Annotate | Download (34.8 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.LinkedList;
47
import java.util.List;
48
import java.util.Map;
49

    
50
import com.iver.cit.jdwglib.dwg.objects.DwgArc;
51
import com.iver.cit.jdwglib.dwg.objects.DwgAttdef;
52
import com.iver.cit.jdwglib.dwg.objects.DwgAttrib;
53
import com.iver.cit.jdwglib.dwg.objects.DwgBlock;
54
import com.iver.cit.jdwglib.dwg.objects.DwgBlockHeader;
55
import com.iver.cit.jdwglib.dwg.objects.DwgCircle;
56
import com.iver.cit.jdwglib.dwg.objects.DwgEllipse;
57
import com.iver.cit.jdwglib.dwg.objects.DwgEndblk;
58
import com.iver.cit.jdwglib.dwg.objects.DwgInsert;
59
import com.iver.cit.jdwglib.dwg.objects.DwgLayer;
60
import com.iver.cit.jdwglib.dwg.objects.DwgLine;
61
import com.iver.cit.jdwglib.dwg.objects.DwgLwPolyline;
62
import com.iver.cit.jdwglib.dwg.objects.DwgMText;
63
import com.iver.cit.jdwglib.dwg.objects.DwgPoint;
64
import com.iver.cit.jdwglib.dwg.objects.DwgPolyline2D;
65
import com.iver.cit.jdwglib.dwg.objects.DwgPolyline3D;
66
import com.iver.cit.jdwglib.dwg.objects.DwgSeqend;
67
import com.iver.cit.jdwglib.dwg.objects.DwgSolid;
68
import com.iver.cit.jdwglib.dwg.objects.DwgText;
69
import com.iver.cit.jdwglib.dwg.objects.DwgVertex2D;
70
import com.iver.cit.jdwglib.dwg.readers.DwgFileV14Reader;
71
import com.iver.cit.jdwglib.dwg.readers.IDwgFileReader;
72
import com.iver.cit.jdwglib.dwg.readers.DwgFileV15Reader;
73

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

    
144
        private ArrayList dwgClasses;
145
        
146
        
147
        /**
148
         * hash map that indexes all DwgLayer objects
149
         * by its handle property
150
         * */
151
        private HashMap layerTable; 
152
        
153
        /**
154
         * Specific reader of the DWG file version (12, 13, 14, 2000, etc., each
155
         * version will have an specific reader)
156
         * */
157
        private IDwgFileReader dwgReader;
158
        private boolean dwg3DFile;
159
        /**
160
         * Memory mapped byte buffer of the whole DWG file
161
         * */
162
        private ByteBuffer bb;
163
        
164
        /*
165
         * Optimizaciones para evitar leer el fichero completo en cada
166
         * pasada.
167
         * */
168
        /**
169
         * Contains all IDwgPolyline implementations
170
         * */
171
        private List dwgPolylines;
172
        /**
173
         * Contains all INSERT entities of the dwg file
174
         * (these entities must be processed in a second pass)
175
         * 
176
         * */
177
        private List insertList;
178
        
179
        /**
180
         * Constructor.
181
         * @param fileName an absolute path to the DWG file
182
         */
183
        public DwgFile(String fileName) {
184
                this.fileName = fileName;
185
                
186
                dwgSectionOffsets = new ArrayList();
187
                dwgObjectOffsets = new ArrayList();
188
                headerVars = new HashMap();
189
                
190
                dwgClasses = new ArrayList();
191
                
192
                dwgObjects = new ArrayList();
193
                handle_objects = new HashMap();
194
                
195
                layerTable = new HashMap();
196
                
197
                dwgPolylines = new ArrayList();
198
                insertList = new ArrayList();
199
        }
200
        
201
        public String getDwgVersion() {
202
                return dwgVersion;
203
        }
204
        
205
        /**
206
         * Reads a DWG file and put its objects in the dwgObjects Vector
207
         * This method is version independent
208
         * 
209
         * @throws IOException If the file location is wrong
210
         */
211
        public void read() throws IOException, 
212
                                DwgVersionNotSupportedException
213
        {
214
                setDwgVersion();
215
                //System.out.println("VERSION = "+dwgVersion);
216
                if (dwgVersion.equalsIgnoreCase("Autocad R2000, R2000i, R2002")) {
217
                        dwgReader = new DwgFileV15Reader();
218
                }else if (dwgVersion.equalsIgnoreCase("Autocad pre-R14")|| 
219
                                dwgVersion.equalsIgnoreCase("Autocad R14") ||
220
                                dwgVersion.equalsIgnoreCase("Autocad R13")) {
221
                        dwgReader = new DwgFileV14Reader();
222
                } else {
223
                        DwgVersionNotSupportedException exception = 
224
                                new DwgVersionNotSupportedException("Version de DWG no soportada");
225
                        exception.setDwgVersion(dwgVersion);
226
                        throw exception;
227
                }
228
                dwgReader.read(this, bb);
229
        }
230
        
231
        private void setDwgVersion() throws IOException {
232
                File file = new File(fileName);
233
                FileInputStream fileInputStream = new FileInputStream(file);
234
                FileChannel fileChannel = fileInputStream.getChannel();
235
                long channelSize = fileChannel.size();
236
                bb = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, channelSize);
237
                byte[] versionBytes = {bb.get(0), 
238
                                                                bb.get(1), 
239
                                                                bb.get(2),
240
                                                                bb.get(3),
241
                                                                bb.get(4), 
242
                                                                bb.get(5)};
243
                ByteBuffer versionByteBuffer = ByteBuffer.wrap(versionBytes);
244
                String[] bs = new String[versionByteBuffer.capacity()];
245
                String versionString = "";
246
                for (int i=0; i<versionByteBuffer.capacity(); i++) {
247
                        bs[i] = new String(new byte[]{(byte)(versionByteBuffer.get(i))});
248
                        versionString = versionString + bs[i];
249
                }
250
                String version = (String) acadVersions.get(versionString);
251
                if(version == null)
252
                        version = "Unknown Dwg format";
253
                this.dwgVersion = version;    
254
        }
255
        
256
        public void setHeader(String key, Object value){
257
                headerVars.put(key, value);
258
        }
259
        
260
        /*
261
         * A DwgLayer is a DWG drawing entity, so all DwgLayer objects are
262
         * saved in dwgObjects collection.
263
         * Instead of iterate over the full collection, is faster check every object
264
         * and save all the DwgLayer instances in their own collection.
265
         *
266
         */
267
        public void addDwgLayer(DwgLayer dwgLayer){
268
                layerTable.put(new Integer(dwgLayer.getHandle().getOffset()), 
269
                                dwgLayer);
270
        }
271
        
272
        private void printInfoOfAObject (DwgObject entity){
273
                // TODO: Eliminar este metodo cuando terminemos de depurar
274
                System.out.println("index = "+entity.getIndex() + " entity.type = " + entity.type + " entityClassName = "+ entity.getClass().getName());
275

    
276
                System.out.println ("handleCode = "+entity.getHandle().getCode());
277
                System.out.println ("entityLayerHandle = "+entity.getHandle().getOffset());
278
                if(entity.hasLayerHandle()){
279
                        System.out.println ("layerHandleCode = "+entity.getLayerHandle().getCode());
280
                        System.out.println ("layerHandle = "+entity.getLayerHandle().getOffset());
281
                }
282
                if(entity.hasSubEntityHandle()){
283
                        System.out.println ("subEntityHandleCode = "+entity.getSubEntityHandle().getCode());
284
                        System.out.println ("subEntityHandle = "+entity.getSubEntityHandle().getOffset());
285
                }
286
                if(entity.hasNextHandle()){
287
                        System.out.println ("nextHandleCode = "+entity.getNextHandle().getCode());
288
                        System.out.println ("nextHandle = "+entity.getNextHandle().getOffset());
289
                }
290
                if(entity.hasPreviousHandle()){
291
                        System.out.println ("previousHandleCode = "+entity.getPreviousHandle().getCode());
292
                        System.out.println ("previousHandle = "+entity.getPreviousHandle().getOffset());
293
                }
294
                if(entity.hasXDicObjHandle()){
295
                        System.out.println ("xDicObjHandleCode = "+entity.getXDicObjHandle());
296
                        System.out.println ("xDicObjHandle = "+entity.getXDicObjHandle());
297
                }
298
                if(entity.hasReactorsHandles()){
299
                        ArrayList reactorsHandles = entity.getReactorsHandles();
300
                        int size = reactorsHandles.size();
301
                        System.out.print ("NUMERO DE reactors = "+size);
302
                        DwgHandleReference hr;
303
                        for(int i=0; i<size; i++){
304
                                hr=(DwgHandleReference)reactorsHandles.get(i);
305
                                System.out.print ("reactorHandleCode = "+hr.getCode());
306
                                System.out.println (" reactorHandle = "+hr.getOffset());
307
                        }
308
                }
309
                
310
        }
311
        public DwgLayer getDwgLayer(DwgObject entity){
312
                DwgHandleReference handle = entity.getLayerHandle();
313
                if(handle == null){
314
//                        System.out.print("Entidad con layer handle a null (debe ser una LwPolyline) ==> ");
315
//                        System.out.println(entity.getClass().getName());
316
                        //TODO Ver que hacemos con estas entidades (lanzan excepcion antes de hacer readTailer)
317
                        return null;
318
                }
319
                int        handleCode = handle.getCode();
320
                int        entityLayerHandle = entity.getLayerHandle().getOffset();
321
                int layerHandle = -1;
322
                
323
                int entityRecord;
324
                DwgObject object;
325
                
326
                
327
                /*
328
                 * OpenDWG spec, v3, page 11. HANDLE REFERENCES
329
                 * 
330
                 * A handle is formed by this fields:
331
                 * a) CODE (4 bits)
332
                 * b) COUNTER (4 bits)
333
                 * c) OFFSET of the object (handle itself).
334
                 * 
335
                 * CODE could take these values:
336
                 * 1) 0x2, 0x3, 0x4, 0x5 -> offset is the handle of the layer
337
                 * 2) 0x6 -> offset is the next object handle
338
                 * 3) 0x8 -> offset is the previous object handle
339
                 * 4) 0xA -> result is reference handle plus offset
340
                  * 5) 0xC -> result is reference handle minus offset
341
                 * 
342
                 * */
343
                
344
                // FIXME: Esto no esta terminado. Falta considerar los codigo
345
                // 0x2, 0x3, 0x6, 0xA que no han aparecido en los archivos de prueba.
346
                switch(handleCode){
347
                case 0x4:
348
                        if (entity.hasNextHandle()){
349
                                int nextHandleCode = entity.getNextHandle().getCode();
350
                                if (nextHandleCode == 0x5) {
351
                                        layerHandle = entity.getNextHandle().getOffset();
352
                                } else {
353
                                        //TODO: No se han previsto nextHandleCode != 0x5
354
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
355
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
356
                                }
357
                        } else {
358
                                layerHandle = entity.getLayerHandle().getOffset();
359
                        }
360
                        break;
361
                case 0x5:
362
                        layerHandle = entity.getLayerHandle().getOffset();
363
                        break;
364
                case 0x8:
365
                        if (entity.hasNextHandle()){
366
                                int nextHandleCode = entity.getNextHandle().getCode();
367
                                if (nextHandleCode == 0x5) {
368
                                        layerHandle = entity.getNextHandle().getOffset();
369
                                } else {
370
                                        //TODO No se han previsto nextHandleCode != 0x5
371
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
372
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
373
                                }
374
                        } else {
375
                                layerHandle = entity.getHandle().getOffset() - 1;
376
                        }
377
                        break;
378
                case 0xC:
379
                        if (entity.hasNextHandle()){
380
                                int nextHandleCode = entity.getNextHandle().getCode();
381
                                if (nextHandleCode == 0x5) {
382
                                        layerHandle = entity.getNextHandle().getOffset();
383
                                } else {
384
                                        //TODO: No se han previsto nextHandleCode != 0x5
385
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
386
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
387
                                }
388
                        } else {
389
                                layerHandle = entity.getHandle().getOffset() - entity.getLayerHandle().getOffset() + 1;
390
                        }
391
                        break;
392
                default:
393
//                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+" no implementado. entityLayerHandle="+entityLayerHandle);
394
                }
395
                
396
                if(layerHandle != -1){
397
                        Iterator lyrIterator = layerTable.values().iterator();
398
                        while(lyrIterator.hasNext()){
399
                                DwgLayer lyr = (DwgLayer) lyrIterator.next();
400
                                int lyrHdl = lyr.getHandle().getOffset();
401
                                if (lyrHdl == layerHandle){
402
                                        return lyr;
403
                                }
404
                        }
405
                }
406
//                System.out.println("NO SE HA ENCONTRADO UNA CAPA CON HANDLE " + layerHandle);
407
//                printInfoOfAObject(entity);
408
                return null;
409
        }
410
        
411
        public DwgObject getDwgSuperEntity(DwgObject entity) {
412
                if(entity.hasSubEntityHandle()){
413
                        int handleCode = entity.subEntityHandle.getCode();
414
                        int offset = entity.subEntityHandle.getOffset();
415
                        int handle = -1;
416
                        
417
                        DwgObject object;
418

    
419
                        switch(handleCode){
420
                        // TODO: case 0x2:
421
                        // TODO: case 0x3:
422
                        case 0x4:
423
                        case 0x5:
424
                                handle = offset;
425
                                break;
426
                        // TODO: case 0x6:
427
                        case 0x8:
428
                                handle=entity.getHandle().getOffset() - 1;
429
                                break;
430
                        case 0xA:
431
                                handle = entity.getHandle().getOffset() + offset;
432
                                break;
433
                        case 0xC:
434
                                handle = entity.getHandle().getOffset() - offset;
435
                                break;
436
                        default:
437
                                System.out.println ("DwgObject.getDwgSuperEntity: handleCode "+handleCode+" no implementado. offset = "+offset);
438
                        }
439
                        if(handle != -1){
440
                                object = getDwgObjectFromHandle(handle);
441
                                if(object != null)
442
                                        return object;
443
                        }
444
//                        System.out.println(" NO SE HA ENCONTRADO UN OBJETO CON HANDLE " + handle + ". handleCode = " + handleCode + " dwgObject.index = "+entity.index +" dwgObject.type = " + entity.type + " dwgObjectClassName = "+ entity.getClass().getName());
445
                }
446
                return null;
447
        }
448
   
449
        public String getLayerName(DwgObject entity) {                
450
                DwgLayer dwgLayer = getDwgLayer(entity);
451
                if(dwgLayer == null){//TODO Puede haber entidades sin layer???
452
                        return "";
453
                }else{
454
                        return dwgLayer.getName();
455
                }
456
        }
457
        
458
        /**
459
     * Returns the color of the layer of a DWG object 
460
         * 
461
     * @param entity DWG object which we want to know its layer color
462
         * @return int Layer color of the DWG object in the Autocad color code
463
         */
464
        public int getColorByLayer(DwgObject entity) {
465
                int colorByLayer;
466
                DwgLayer dwgLyr = getDwgLayer(entity);
467
                if(dwgLyr == null)
468
                        colorByLayer = 0;
469
                else
470
                        colorByLayer = dwgLyr.getColor();
471
                return colorByLayer;
472
        }
473
        /**
474
         * Configure the geometry of the polylines in a DWG file from the vertex list in
475
         * this DWG file. This geometry is given by an array of Points.
476
         * Besides, manage closed polylines and polylines with bulges in a GIS Data model.
477
     * It means that the arcs of the polylines will be done through a set of points and
478
     * a distance between these points.
479
         */
480
        public void calculateGisModelDwgPolylines() {
481
                /*
482
                 * Ahora mismo esto se est? haciendo al final (en una segunda pasada)
483
                 * porque posiblemente una Linea requiera de vertices que vengan
484
                 * despues, lo que complicar?a bastante todo....
485
                 * */
486

    
487
                for (int i = 0; i < dwgPolylines.size(); i++){
488
                        DwgObject pol = (DwgObject)dwgPolylines.get(i);
489
                        if (pol instanceof IDwgPolyline) {
490
                                ((IDwgPolyline)pol).calculateGisModel(this);
491
                        } 
492
                }
493
        }
494
        
495
    /**
496
     * Configure the geometry of the polylines in a DWG file from the vertex list in
497
     * this DWG file. This geometry is given by an array of Points
498
     * Besides, manage closed polylines and polylines with bulges in a GIS Data model.
499
     * It means that the arcs of the polylines will be done through a curvature
500
     * parameter called bulge associated with the points of the polyline.
501
     */
502
        //TODO Refactorizar para que solo se aplique a las Polilineas
503
        public void calculateCadModelDwgPolylines() {
504
                for (int i=0;i<dwgObjects.size();i++) {
505
                        DwgObject pol = (DwgObject)dwgObjects.get(i);
506
                        if (pol instanceof DwgPolyline2D) {
507
                                int flags = ((DwgPolyline2D)pol).getFlags();
508
                                int firstHandle = ((DwgPolyline2D)pol).getFirstVertexHandle().getOffset();
509
                                int lastHandle = ((DwgPolyline2D)pol).getLastVertexHandle().getOffset();
510
                                ArrayList pts = new ArrayList();
511
                                ArrayList bulges = new ArrayList();
512
                                double[] pt = new double[3];
513
                                for (int j=0;j<dwgObjects.size();j++) {
514
                                        DwgObject firstVertex = (DwgObject)dwgObjects.get(j);
515
                                        if (firstVertex instanceof DwgVertex2D) {
516
                                                int vertexHandle = firstVertex.getHandle().getOffset();
517
                                                if (vertexHandle==firstHandle) {
518
                                                        int k=0;
519
                                                        while (true) {
520
                                                                DwgObject vertex = (DwgObject)dwgObjects.get(j+k);
521
                                                                int vHandle = vertex.getHandle().getOffset();
522
                                                                if (vertex instanceof DwgVertex2D) {
523
                                                                        pt = ((DwgVertex2D)vertex).getPoint();
524
                                                                        pts.add(new Point2D.Double(pt[0], pt[1]));
525
                                                                        double bulge = ((DwgVertex2D)vertex).getBulge();
526
                                                                        bulges.add(new Double(bulge));
527
                                                                        k++;
528
                                                                        if (vHandle==lastHandle && vertex instanceof DwgVertex2D) {
529
                                                                                break;
530
                                                                        }
531
                                                                } else if (vertex instanceof DwgSeqend) {
532
                                                                        break;
533
                                                                }
534
                                                        }
535
                                                }
536
                                        }
537
                                }
538
                                if (pts.size()>0) {
539
                                        /*Point2D[] newPts = new Point2D[pts.size()];
540
                                        if ((flags & 0x1)==0x1) {
541
                                                newPts = new Point2D[pts.size()+1];
542
                                                for (int j=0;j<pts.size();j++) {
543
                                                        newPts[j] = (Point2D)pts.get(j);
544
                                                }
545
                                                newPts[pts.size()] = (Point2D)pts.get(0);
546
                                                bulges.add(new Double(0));
547
                                        } else {
548
                                                for (int j=0;j<pts.size();j++) {
549
                                                        newPts[j] = (Point2D)pts.get(j);
550
                                                }
551
                                        }*/
552
                                        double[] bs = new double[bulges.size()];
553
                                        for (int j=0;j<bulges.size();j++) {
554
                                                bs[j] = ((Double)bulges.get(j)).doubleValue();
555
                                        }
556
                                        ((DwgPolyline2D)pol).setBulges(bs);
557
                                        //Point2D[] points = GisModelCurveCalculator.calculateGisModelBulge(newPts, bs);
558
                                        Point2D[] points = new Point2D[pts.size()];
559
                                        for (int j=0;j<pts.size();j++) {
560
                                            points[j] = (Point2D)pts.get(j);
561
                                        }
562
                                        ((DwgPolyline2D)pol).setPts(points);
563
                                } else {
564
//                                        System.out.println("Encontrada polil?nea sin puntos ...");
565
                                        // TODO: No se debe mandar nunca una polil?nea sin puntos, si esto
566
                                        // ocurre es porque existe un error que hay que corregir ...
567
                                }
568
                        } else if (pol instanceof DwgPolyline3D) {
569
                        } else if (pol instanceof DwgLwPolyline && ((DwgLwPolyline)pol).getVertices()!=null) {
570
                        }
571
                }
572
        }
573
        
574
        public void blockManagement2(){
575
                //once we have read all dwg entities, we look for all of them
576
                //that has a superentity that is a block (to fill in the entity list
577
                //of each block
578
                Iterator it = dwgObjects.iterator();
579
                int i = 0;
580
                while(it.hasNext()){
581
                        DwgObject entity = (DwgObject)it.next();
582
                        DwgObject superEnt = getDwgSuperEntity(entity);
583
                        if(superEnt instanceof DwgBlockHeader){
584
                                DwgBlockHeader blk = (DwgBlockHeader)superEnt;
585
//                                System.out.println("Entidad "+
586
//                                                                                        i+
587
//                                                                " pertenece al bloque "+
588
//                                                                blk.getName());
589
                                blk.addObject(entity);
590
                                it.remove();//TODO Creo que esto es lento, mejor
591
                                //el metodo original (en java solo se duplican las referencias)
592
                                i++;
593
                        }
594
                }//while
595
                
596
                //after that, we process the INSERTs
597
                it = insertList.iterator();
598
                while(it.hasNext()){
599
                        DwgInsert insert = (DwgInsert) it.next();
600
                        if(insert.isProcessed()){
601
                                //It has been processed nexted to other insert
602
                                continue;
603
                        }
604
                        insert.setProcessed(true);
605
                        double[] p = insert.getInsertionPoint();
606
                        Point2D point = new Point2D.Double(p[0], p[1]);
607
                        double[] scale = insert.getScale();
608
                        double rot = insert.getRotation();
609
                        int blockHandle = insert.getBlockHeaderHandle().getOffset();
610
                        manageInsert2(point, scale,
611
                                        rot, blockHandle, 
612
                                        dwgObjects, handle_objects);
613
                }        
614
        }
615

    
616
    /**
617
     * Modify the geometry of the objects contained in the blocks of a DWG file and
618
     * add these objects to the DWG object list.
619
     * 
620
     * TODO Revisar los bloques que son XREF
621
     */
622
        public void blockManagement() {
623
                LinkedList dwgObjectsWithoutBlocks = new LinkedList();
624
                HashMap handle_objectsWithoutBlocks = new HashMap();
625
            boolean addingToBlock = false;
626
            try{
627
                        for (int i=0; i < dwgObjects.size(); i++) {
628
                                DwgObject entity = (DwgObject)dwgObjects.get(i);
629
                                if (entity instanceof DwgArc && !addingToBlock) {
630
                                        dwgObjectsWithoutBlocks.add(entity);
631
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
632
                                } else if (entity instanceof DwgEllipse && !addingToBlock) {
633
                                        dwgObjectsWithoutBlocks.add(entity);
634
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
635
                                } else if (entity instanceof DwgCircle && !addingToBlock) {
636
                                        dwgObjectsWithoutBlocks.add(entity);
637
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
638
                                } else if (entity instanceof DwgPolyline2D && !addingToBlock) {
639
                                        dwgObjectsWithoutBlocks.add(entity);
640
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
641
                                } else if (entity instanceof DwgPolyline3D && !addingToBlock) {
642
                                        dwgObjectsWithoutBlocks.add(entity);
643
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
644
                                } else if (entity instanceof DwgLwPolyline && !addingToBlock) {
645
                                        dwgObjectsWithoutBlocks.add(entity);
646
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
647
                                } else if (entity instanceof DwgSolid && !addingToBlock) {
648
                                        dwgObjectsWithoutBlocks.add(entity);
649
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
650
                                } else if (entity instanceof DwgLine && !addingToBlock) {
651
                                        dwgObjectsWithoutBlocks.add(entity);
652
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
653
                                } else if (entity instanceof DwgPoint && !addingToBlock) {
654
                                        dwgObjectsWithoutBlocks.add(entity);
655
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
656
                                } else if (entity instanceof DwgMText && !addingToBlock) {
657
                                        dwgObjectsWithoutBlocks.add(entity);
658
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
659
                                } else if (entity instanceof DwgText && !addingToBlock) {
660
                                        dwgObjectsWithoutBlocks.add(entity);
661
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
662
                                } else if (entity instanceof DwgAttrib && !addingToBlock) {
663
                                        dwgObjectsWithoutBlocks.add(entity);
664
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
665
                                } else if (entity instanceof DwgAttdef && !addingToBlock) {
666
                                        dwgObjectsWithoutBlocks.add(entity);
667
                                        handle_objectsWithoutBlocks.put(new Integer(entity.getHandle().getOffset()), entity);
668
                                } else if (entity instanceof DwgBlock) {
669
                                        addingToBlock = true;
670
                                } else if (entity instanceof DwgEndblk) {
671
                                        addingToBlock = false;
672
                                } else if (entity instanceof DwgBlockHeader) {
673
                                        addingToBlock = true;
674
                                } 
675
                                //Segun esto, un insert solo se procesa dentro de un Block (o BlockHeader)
676
                                //?Puede haber INSERT fuera de BLOCK-ENDBLK?
677
                                else if (entity instanceof DwgInsert && !addingToBlock) {
678
                                        double[] p = ((DwgInsert)entity).getInsertionPoint();
679
                                        Point2D point = new Point2D.Double(p[0], p[1]);
680
                                        double[] scale = ((DwgInsert)entity).getScale();
681
                                        double rot = ((DwgInsert)entity).getRotation();
682
                                        int blockHandle = ((DwgInsert)entity).getBlockHeaderHandle().getOffset();
683
                                        manageInsert(point, scale, rot, blockHandle, dwgObjectsWithoutBlocks, handle_objectsWithoutBlocks);
684
                                } else {
685
        //                                System.out.println(entity.getClass().getName() +" en un bloque");
686
                                        //Se ha encontrado una entidad rara, o forma parte de un bloque
687
                                        //y ser? procesada despu?s (con los punteros del propio bloque)
688
                                        
689
                                        //TODO No se podr?a hacer mas rapido, quitando de la lista original
690
                                        //las entidades que forman parte de bloque??
691
                                }
692
                        }
693
            }catch(RuntimeException re){
694
                    re.printStackTrace();
695
            }
696
                dwgObjects = dwgObjectsWithoutBlocks;
697
                this.handle_objects = (HashMap) handle_objectsWithoutBlocks;
698
        }
699
        
700
        public void manageInsert2(Point2D insPoint, double[] scale,
701
                        double rot, int bHandle, 
702
                        List dwgObjectsWithoutBlocks, 
703
                        Map handleObjectsWithoutBlocks) {
704
                
705
                DwgObject object = (DwgObject) handle_objects.get(new Integer(bHandle));
706
                if(object == null){
707
                        System.out.println("No hemos encontrado el BlockHeader cuyo handle es "+bHandle);
708
                        return;
709
                }else if(! (object instanceof DwgBlockHeader)){
710
                        //Hay un problema con la asignaci?n de handle
711
                        //Un INSERT tiene como handle de Block una entidad que no es block
712
//                        System.out.println("handle incorrecto." + object.getClass().getName() + " no es un blockheader");
713
                        return;
714
                }
715
                
716
                DwgBlockHeader blockHeader = (DwgBlockHeader)object;
717
                double[] bPoint = blockHeader.getBasePoint();
718
                String bname = blockHeader.getName();
719
                if (bname.startsWith("*")) 
720
                        return;
721
                
722
                //TODO Cambiar por List
723
                Iterator blkEntIt = blockHeader.getObjects().iterator();
724
                while(blkEntIt.hasNext()){
725
                        DwgObject obj = (DwgObject) blkEntIt.next();
726
                         manageBlockEntity(obj, bPoint, 
727
                                           insPoint, scale, 
728
                                           rot, dwgObjectsWithoutBlocks,
729
                                           handleObjectsWithoutBlocks);        
730
                }//while
731
        }
732
        
733
    /**
734
     * Manages an INSERT of a DWG file. This object is the insertion point of a DWG
735
     * block. 
736
     * 
737
     * @param insPoint, coordinates of the insertion point.
738
     * @param scale, scale of the elements of the block that will be inserted.
739
     * @param rot, rotation angle of the elements of the block.
740
     * 
741
     * @param bHandle, offset for the coordinates of the elements of the block.
742
     * @param id, count that serves as a id.
743
     * @param dwgObjectsWithoutBlocks, a object list with the elements extracted from
744
     * the blocks.
745
     */
746
        public void manageInsert(Point2D insPoint, double[] scale,
747
                                                        double rot, int bHandle, 
748
                                                        List dwgObjectsWithoutBlocks, 
749
                                                        Map handleObjectsWithoutBlocks) {
750
                
751
                DwgObject object = (DwgObject) handle_objects.get(new Integer(bHandle));
752
                if(object == null){
753
//                        System.out.println("No hemos encontrado el BlockHeader cuyo handle es "+bHandle);
754
                        return;
755
                }else if(! (object instanceof DwgBlockHeader)){
756
                        //Hay un problema con la asignaci?n de handle
757
                        //Un INSERT tiene como handle de Block una entidad que no es block
758
//                        System.out.println("handle incorrecto." + object.getClass().getName() + " no es un blockheader");
759
                        return;
760
                }
761
                
762
                DwgBlockHeader blockHeader = (DwgBlockHeader)object;
763
                double[] bPoint = blockHeader.getBasePoint();
764
                String bname = blockHeader.getName();
765
                if (bname.startsWith("*")) 
766
                        return;
767
                
768
                DwgHandleReference firstHdl = blockHeader.getFirstEntityHandle();
769
                DwgHandleReference lastHdl = blockHeader.getLastEntityHandle();
770
                if(firstHdl == null || lastHdl == null){
771
//                        System.out.println("Problemas en el bloque "+bname);
772
//                        System.out.println("1er obj="+firstHdl+" 2o obj="+lastHdl);
773
                        return;
774
                }        
775
                
776
                
777
                
778
                int firstObjectHandle = firstHdl.getOffset();   
779
                int lastObjectHandle = lastHdl.getOffset();
780
                
781
                //TODO Ver que hacia el metodo antiguo cuando llegaban handles a 0
782
                //como extremos de un bloque (sera bloque vacio, supongo)
783
                if(firstObjectHandle == 0 || lastObjectHandle == 0){
784
//                        System.out.println("Problemas en el bloque "+bname);
785
//                        System.out.println("1er obj="+firstObjectHandle+" 2o obj="+lastObjectHandle);
786
                        return;
787
                }        
788
                
789
                /*
790
                 * Ahora localiza la primera entidad del bloque, 
791
                 * y a partir de ah?, a?ade
792
                 * al bloque todas las entidades que encuentre hasta la 
793
                 * ?ltima entidad del bloque
794
                 * 
795
                 * */
796
                 DwgObject firstObj = (DwgObject) handle_objects.
797
                                                 get(new Integer(firstObjectHandle));
798
                 DwgObject lastObj =  (DwgObject) handle_objects.
799
                                                 get(new Integer(lastObjectHandle));
800
                 
801
                 int firstObjIdx = dwgObjects.indexOf(firstObj);
802
                 int lastObjIdx = dwgObjects.indexOf(lastObj);
803
                 if(firstObjIdx == -1){
804
//                         System.out.println("El primer objeto del bloque "+
805
//                                                         blockHeader.getName()+
806
//                                                 " no ha sido localizado a partir del handle "+
807
//                                                 firstObjectHandle);
808
                         return;
809
                 }
810
                         
811
                 if(lastObjIdx == -1){
812
//                         System.out.println("El ultimo objeto del bloque "+
813
//                                                         blockHeader.getName()+
814
//                                                 " no ha sido localizado a partir del handle "+
815
//                                                 lastObjectHandle);
816
                         
817
                         //Intentamos ver si como delimitador final de bloque aparece EndBlk
818
                         LinkedList tempDwgObj = new LinkedList();
819
                         HashMap tempHdlObj = new HashMap();
820
                         DwgObject scannedEntity = (DwgObject) dwgObjects.get(firstObjIdx);
821
                         while(! (scannedEntity instanceof DwgEndblk)){
822
                                 manageBlockEntity(scannedEntity, bPoint, 
823
                                                 insPoint, scale, rot, 
824
                                                 tempDwgObj,
825
                                                 tempHdlObj);
826
                                 firstObjIdx++;
827
                                 scannedEntity = (DwgObject) dwgObjects.get(firstObjIdx);
828
                                 if( (scannedEntity instanceof DwgBlock) ||
829
                                        (scannedEntity instanceof DwgBlockHeader)){
830
                                         //No puede haber bloques anidados
831
                                         //Descartar 
832
//                                         System.out.println("Error, aparecen bloques anidados");
833
                         return;
834
                 }
835
                         }//while
836
                         if(tempDwgObj.size() > 0){
837
                                 dwgObjectsWithoutBlocks.addAll(tempDwgObj);
838
                                 handleObjectsWithoutBlocks.putAll(tempHdlObj);
839
                         }         
840
                         return;
841
                         
842
                 }//if
843
                 for(int i = firstObjIdx; i <= lastObjIdx; i++){
844
                         DwgObject obj = (DwgObject) dwgObjects.get(i);
845
                         manageBlockEntity(obj, bPoint, 
846
                                                           insPoint, scale, 
847
                                                           rot, dwgObjectsWithoutBlocks, handleObjectsWithoutBlocks);
848
                 }//for
849
        }
850
        
851
        public int getIndexOf(DwgObject dwgObject){
852
                return dwgObjects.indexOf(dwgObject);
853
                
854
                
855
        }
856
        
857
        
858
        
859
    /**
860
     * Changes the location of an object extracted from a block. This location will be
861
     * obtained through the insertion parameters from the block and the corresponding
862
     * insert.
863
     * @param entity, the entity extracted from the block.
864
     * @param bPoint, offset for the coordinates of the entity.
865
     * @param insPoint, coordinates of the insertion point for the entity.
866
     * @param scale, scale for the entity.
867
     * @param rot, rotation angle for the entity.
868
     * @param id, a count as a id.
869
     * @param dwgObjectsWithoutBlocks, a object list with the elements extracted from
870
     * the blocks.
871
     */
872
        private void manageBlockEntity(DwgObject entity, 
873
                                                                        double[] bPoint, 
874
                                                                        Point2D insPoint, 
875
                                                                        double[] scale, 
876
                                                                        double rot, 
877
                                                                        List dwgObjectsWithoutBlocks,
878
                                                                        Map handleObjectsWithoutBlocks) {
879
                
880
                if(entity instanceof IDwgBlockMember){
881
                        IDwgBlockMember blockMember = (IDwgBlockMember)entity;
882
                        blockMember.transform2Block(bPoint, insPoint, scale, rot, 
883
                                        dwgObjectsWithoutBlocks,
884
                                        handleObjectsWithoutBlocks,this);
885
                }else{
886
                        //TODO REIMPLEMENTAR ENTIDADES QUE PUEDEN FORMAR PARTE DE BLOQUES.
887
                        //POR EJEMPLO: DwgText y DwgMText pueden formar parte 
888
                        //de bloques, y de hecho, est?n apareciendo
889
                        
890
//                        System.out.println(entity.getClass().getName()+" dentro de un bloque");
891
                }
892
        }
893
        
894
        
895
        /**
896
         * Add a DWG section offset to the dwgSectionOffsets vector
897
         * 
898
         * @param key Define the DWG section
899
         * @param seek Offset of the section
900
         * @param size Size of the section
901
         */
902
        public void addDwgSectionOffset(String key, int seek, int size) {
903
                DwgSectionOffset dso = new DwgSectionOffset(key, seek, size);
904
                dwgSectionOffsets.add(dso);
905
        }
906
        
907
        /**
908
     * Returns the offset of DWG section given by its key 
909
         * 
910
     * @param key Define the DWG section
911
         * @return int Offset of the section in the DWG file
912
         */
913
        public int getDwgSectionOffset(String key) {
914
                int offset = 0;
915
                for (int i=0; i<dwgSectionOffsets.size(); i++) {
916
                        DwgSectionOffset dso = (DwgSectionOffset)dwgSectionOffsets.get(i);
917
                        String ikey = dso.getKey();
918
                        if (key.equals(ikey)) {
919
                                offset = dso.getSeek();
920
                                break;
921
                        }
922
                }
923
                return offset;
924
        }
925
        
926
        /**
927
         * Add a DWG object offset to the dwgObjectOffsets vector
928
         * 
929
         * @param handle Object handle
930
         * @param offset Offset of the object data in the DWG file
931
         */
932
        public void addDwgObjectOffset(int handle, int offset) {
933
                DwgObjectOffset doo = new DwgObjectOffset(handle, offset);
934
                dwgObjectOffsets.add(doo);
935
        }
936
        
937
        /**
938
         * 
939
         * Add a DWG object to the dwgObject vector
940
         * 
941
         * @param dwgObject DWG object
942
         */
943
        public void addDwgObject(DwgObject dwgObject){
944
                //TODO Ver si puedo inicializar las listas especificas
945
                //(IDwgPolyline, etc) aqu? 
946
                dwgObjects.add(dwgObject);
947
                handle_objects.put(new Integer(dwgObject.getHandle().getOffset()), dwgObject);
948
                
949
                /*
950
                 * TODO Quitar todos estos if-then y sustituirlos por un metodo callbackj
951
                 * 
952
                 * 
953
                 * (dwgObject.init(this), y que cada objeto haga lo que tenga que hacer
954
                 * */
955
                if(dwgObject instanceof DwgLayer){
956
                        this.addDwgLayer((DwgLayer) dwgObject);
957
                }
958
                
959
                //Probamos a no aplicar las extrusiones
960
                
961
                if(dwgObject instanceof IDwgExtrusionable){
962
                        ((IDwgExtrusionable)dwgObject).applyExtrussion();
963
                }
964
                
965
                
966
                
967
                if(dwgObject instanceof IDwgPolyline){
968
                        dwgPolylines.add(dwgObject);
969
                }
970
                if(dwgObject instanceof IDwg3DTestable){
971
                        if(! dwg3DFile){//if its true, we dont check again
972
                                dwg3DFile = ((IDwg3DTestable)dwgObject).has3DData();
973
                        }
974
                }
975
                if(dwgObject instanceof DwgInsert){
976
                        insertList.add(dwgObject);
977
                }
978
        }
979
        
980
        /**
981
         * Returns dwgObjects from its insertion order (position
982
         * in the dwg file)
983
         * 
984
         * @param index order in the dwg file
985
         * @return position
986
         * */
987
        public DwgObject getDwgObject(int index){
988
                return (DwgObject) dwgObjects.get(index);
989
        }
990
        
991
        public DwgObject getDwgObjectFromHandle(int handle){
992
                return (DwgObject) handle_objects.get(new Integer(handle));
993
        }
994
        
995
        /**
996
         * Add a DWG class to the dwgClasses vector
997
         * 
998
         * @param dwgClass DWG class
999
         */
1000
        public void addDwgClass(DwgClass dwgClass){
1001
                dwgClasses.add(dwgClass);
1002
        }
1003
        
1004
        public void printClasses(){
1005
                System.out.println("#### CLASSES ####");
1006
                for(int i = 0; i < dwgClasses.size(); i++){
1007
                        DwgClass clazz = (DwgClass) dwgClasses.get(i);
1008
                        System.out.println(clazz.toString());
1009
                }
1010
                System.out.println("#############");
1011
        }
1012
        
1013
        public List getDwgClasses(){
1014
                return dwgClasses;
1015
        }
1016
        
1017
    /**
1018
     * @return Returns the dwgObjectOffsets.
1019
     */
1020
    public ArrayList getDwgObjectOffsets() {
1021
        return dwgObjectOffsets;
1022
    }
1023
    /**
1024
     * @return Returns the dwgObjects.
1025
     */
1026
    public List getDwgObjects() {
1027
        return dwgObjects;
1028
    }
1029
    /**
1030
     * @return Returns the fileName.
1031
     */
1032
    public String getFileName() {
1033
        return fileName;
1034
    }
1035
    /**
1036
     * @return Returns the dwg3DFile.
1037
     */
1038
    public boolean isDwg3DFile() {
1039
        return dwg3DFile;
1040
    }
1041
    /**
1042
     * @param dwg3DFile The dwg3DFile to set.
1043
     */
1044
    public void setDwg3DFile(boolean dwg3DFile) {
1045
        this.dwg3DFile = dwg3DFile;
1046
    }
1047
}