Statistics
| Revision:

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

History | View | Annotate | Download (28.7 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
        public static final String DWG_ACAD2000 = "AC1015";
73
        public static final String DWG_ACAD14 = "AC1014";
74
        public static final String DWG_ACAD_PRE_14 = "AC1013";
75
        public static final String DWG_ACAD13 = "AC1012";
76
        public static final String DWG_ACAD12 = "AC1009";
77
        
78
        /**
79
         * It has all known DWG version's header.
80
         * Extracted from Autodesk web.
81
         */
82
        private static HashMap acadVersions = new HashMap();
83
        static{
84
                acadVersions.put("AC1004", "Autocad R9");
85
                acadVersions.put("AC1006", "Autocad R10");
86
                acadVersions.put("AC1007", "Autocad pre-R11");
87
                acadVersions.put("AC1007", "Autocad pre-R11");
88
                acadVersions.put("AC1008", "Autocad pre-R11b");
89
                acadVersions.put(DWG_ACAD12, "Autocad R12");
90
                acadVersions.put("AC1010", "Autocad pre-R13 a");
91
                acadVersions.put("AC1011", "Autocad pre-R13 b");
92
                acadVersions.put(DWG_ACAD13, "Autocad R13");
93
                acadVersions.put(DWG_ACAD_PRE_14, "Autocad pre-R14");
94
                acadVersions.put(DWG_ACAD14, "Autocad R14");
95
                acadVersions.put("AC1500", "Autocad pre-2000");
96
                acadVersions.put(DWG_ACAD2000, "Autocad R2000, R2000i, R2002");
97
                acadVersions.put("AC402a", "Autocad pre-2004a");
98
                acadVersions.put("AC402b", "Autocad pre-2004b");
99
                acadVersions.put("AC1018", "Autocad R2004, R2005, R2006");
100
                acadVersions.put("AC1021", "Autocad R2007");
101
        }
102
        
103
        
104
        /**
105
         * Registry of file readers
106
         * */
107
        private static HashMap acadReaders = new HashMap();
108
        static{
109
                acadReaders.put(DWG_ACAD2000,DwgFileV15Reader.class);
110
                acadReaders.put(DWG_ACAD_PRE_14,DwgFileV14Reader.class);
111
                acadReaders.put(DWG_ACAD14,DwgFileV14Reader.class);
112
                acadReaders.put(DWG_ACAD13,DwgFileV14Reader.class);
113
                acadReaders.put(DWG_ACAD12,DwgFileV12Reader.class);
114
        }
115
        
116
        public static Class getReaderForVersion(String dwgVersion){
117
                return (Class) acadReaders.get(dwgVersion);
118
        }
119
        
120
        public static void registerDwgReader(String version, Class dwgReaderClazz){
121
                if( IDwgFileReader.class.isAssignableFrom(dwgReaderClazz)){
122
                        if(!acadReaders.containsKey(version)){
123
                                acadReaders.put(version, dwgReaderClazz);
124
                        }else{
125
                                logger.warn("Ya hay un reader registrado para la version "+version);
126
                        }
127
                }else{
128
                        logger.warn("La clase "+dwgReaderClazz.getName()+" no es una implementacion valida de IDwgFileReader");
129
                }
130
        }
131
        /**
132
         * Returns an iterator over all the string that represents
133
         * dwg version for we have a registered reader
134
         * */
135
        public static Iterator getRegisteredVersions(){
136
                return acadReaders.keySet().iterator();
137
        }
138
        
139
        private static Logger logger = Logger.getLogger(DwgFile.class
140
                        .getName());
141
        
142
        /**
143
         * Path and name of the dwg file
144
         * */
145
        private String fileName;
146
        /**
147
         * DWG version of the file (AC1013, AC1018, etc.)
148
         * */
149
        private String dwgVersion;
150
        
151
        /**
152
         * Offsets to the DWG sections
153
         */
154
        private ArrayList dwgSectionOffsets;
155
        /**
156
         * Header vars readed from the HEADER section of the DWG file
157
         * */
158
        private Map headerVars;
159
        
160
        /**
161
         * This list contains what in OpenDWG specification is called
162
         * the object map ( a collection of entries where each entry contains
163
         * the seek of each object, and its size)
164
         * */
165
        private ArrayList dwgObjectOffsets;
166
        
167
        /**
168
         * For each entry in dwgObjectOffsets, we have an instance of
169
         * DwgObject in the dwgObjects collection
170
         * 
171
         * */
172
        private List dwgObjects;
173
        private HashMap handle_objects;
174
        
175

    
176
        private ArrayList dwgClasses;
177
        
178
        
179
        /**
180
         * hash map that indexes all DwgLayer objects
181
         * by its handle property
182
         * */
183
        private HashMap layerTable; 
184
        
185
        /**
186
         * Specific reader of the DWG file version (12, 13, 14, 2000, etc., each
187
         * version will have an specific reader)
188
         * */
189
        private IDwgFileReader dwgReader;
190
        private boolean dwg3DFile;
191
        /**
192
         * Memory mapped byte buffer of the whole DWG file
193
         * */
194
        private ByteBuffer bb;
195
        
196
        /*
197
         * Optimizaciones para evitar leer el fichero completo en cada
198
         * pasada.
199
         * */
200
        /**
201
         * Contains all IDwgPolyline implementations
202
         * */
203
        private List dwgPolylines;
204
        /**
205
         * Contains all INSERT entities of the dwg file
206
         * (these entities must be processed in a second pass)
207
         * 
208
         * */
209
        private List insertList;
210
        
211
        private List blockList;
212
        
213

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

    
484
                        switch(handleCode){
485
                        // TODO: case 0x2:
486
                        // TODO: case 0x3:
487
                        case 0x4:
488
                        case 0x5:
489
                                handle = offset;
490
                                break;
491
                        // TODO: case 0x6:
492
                        case 0x8:
493
                                handle=entity.getHandle().getOffset() - 1;
494
                                break;
495
                        case 0xA:
496
                                handle = entity.getHandle().getOffset() + offset;
497
                                break;
498
                        case 0xC:
499
                                handle = entity.getHandle().getOffset() - offset;
500
                                break;
501
                        default:
502
                                logger.warn ("DwgObject.getDwgSuperEntity: handleCode "+handleCode+" no implementado. offset = "+offset);
503
                        }
504
                        if(handle != -1){
505
                                object = getDwgObjectFromHandle(handle);
506
                                if(object != null)
507
                                        return object;
508
                        }
509
                }
510
                return null;
511
        }
512
   
513
        public String getLayerName(DwgObject entity) {                
514
                DwgLayer dwgLayer = getDwgLayer(entity);
515
                if(dwgLayer == null){
516
                        return "";
517
                }else{
518
                        return dwgLayer.getName();
519
                }
520
        }
521
        
522
        /**
523
     * Returns the color of the layer of a DWG object 
524
         * 
525
     * @param entity DWG object which we want to know its layer color
526
         * @return int Layer color of the DWG object in the Autocad color code
527
         */
528
        public int getColorByLayer(DwgObject entity) {
529
                int colorByLayer;
530
                DwgLayer dwgLyr = getDwgLayer(entity);
531
                if(dwgLyr == null)
532
                        colorByLayer = 0;
533
                else
534
                        colorByLayer = dwgLyr.getColor();
535
                return colorByLayer;
536
        }
537
        /**
538
         * Configure the geometry of the polylines in a DWG file from the vertex list in
539
         * this DWG file. This geometry is given by an array of Points.
540
         * Besides, manage closed polylines and polylines with bulges in a GIS Data model.
541
     * It means that the arcs of the polylines will be done through a set of points and
542
     * a distance between these points.
543
         */
544
        public void calculateGisModelDwgPolylines() {
545
                /*
546
                 * In Dwg 12 format, all vertices of a polyline are between polyline entity
547
                 * and endsec entity. Also, polylines dont save any handle of their vertices (first and last).
548
                 * 
549
                 * After Dwg 12 version, we have the opposite case: polylines have handles/pointers to their
550
                 * first and last vertices.
551
                 * 
552
                 * If dwg file is not V12, we must look for all polyline vertices (and we must to wait until
553
                 * all entities are readed).
554
                 * If dwg file is V12, all polylines already have their vertices.
555
                 * */
556
                if(! (dwgReader instanceof DwgFileV12Reader)){
557
                        for (int i = 0; i < dwgPolylines.size(); i++){
558
                                DwgObject pol = (DwgObject)dwgPolylines.get(i);
559
                                if (pol instanceof IDwgPolyline) {
560
                                        ((IDwgPolyline)pol).calculateGisModel(this);
561
                                }//if 
562
                        }//for
563
                }
564
        }
565
        
566
    /**
567
     * Configure the geometry of the polylines in a DWG file from the vertex list in
568
     * this DWG file. This geometry is given by an array of Points
569
     * Besides, manage closed polylines and polylines with bulges in a GIS Data model.
570
     * It means that the arcs of the polylines will be done through a curvature
571
     * parameter called bulge associated with the points of the polyline.
572
     */
573
        //TODO Refactorizar para que solo se aplique a las Polilineas
574
        
575
//        public void calculateCadModelDwgPolylines() {
576
//                for (int i=0;i<dwgObjects.size();i++) {
577
//                        DwgObject pol = (DwgObject)dwgObjects.get(i);
578
//                        if (pol instanceof DwgPolyline2D) {
579
//                                int flags = ((DwgPolyline2D)pol).getFlags();
580
//                                int firstHandle = ((DwgPolyline2D)pol).getFirstVertexHandle().getOffset();
581
//                                int lastHandle = ((DwgPolyline2D)pol).getLastVertexHandle().getOffset();
582
//                                ArrayList pts = new ArrayList();
583
//                                ArrayList bulges = new ArrayList();
584
//                                double[] pt = new double[3];
585
//                                for (int j=0;j<dwgObjects.size();j++) {
586
//                                        DwgObject firstVertex = (DwgObject)dwgObjects.get(j);
587
//                                        if (firstVertex instanceof DwgVertex2D) {
588
//                                                int vertexHandle = firstVertex.getHandle().getOffset();
589
//                                                if (vertexHandle==firstHandle) {
590
//                                                        int k=0;
591
//                                                        while (true) {
592
//                                                                DwgObject vertex = (DwgObject)dwgObjects.get(j+k);
593
//                                                                int vHandle = vertex.getHandle().getOffset();
594
//                                                                if (vertex instanceof DwgVertex2D) {
595
//                                                                        pt = ((DwgVertex2D)vertex).getPoint();
596
//                                                                        pts.add(new Point2D.Double(pt[0], pt[1]));
597
//                                                                        double bulge = ((DwgVertex2D)vertex).getBulge();
598
//                                                                        bulges.add(new Double(bulge));
599
//                                                                        k++;
600
//                                                                        if (vHandle==lastHandle && vertex instanceof DwgVertex2D) {
601
//                                                                                break;
602
//                                                                        }
603
//                                                                } else if (vertex instanceof DwgSeqend) {
604
//                                                                        break;
605
//                                                                }
606
//                                                        }
607
//                                                }
608
//                                        }
609
//                                }
610
//                                if (pts.size()>0) {
611
//                                        /*Point2D[] newPts = new Point2D[pts.size()];
612
//                                        if ((flags & 0x1)==0x1) {
613
//                                                newPts = new Point2D[pts.size()+1];
614
//                                                for (int j=0;j<pts.size();j++) {
615
//                                                        newPts[j] = (Point2D)pts.get(j);
616
//                                                }
617
//                                                newPts[pts.size()] = (Point2D)pts.get(0);
618
//                                                bulges.add(new Double(0));
619
//                                        } else {
620
//                                                for (int j=0;j<pts.size();j++) {
621
//                                                        newPts[j] = (Point2D)pts.get(j);
622
//                                                }
623
//                                        }*/
624
//                                        double[] bs = new double[bulges.size()];
625
//                                        for (int j=0;j<bulges.size();j++) {
626
//                                                bs[j] = ((Double)bulges.get(j)).doubleValue();
627
//                                        }
628
//                                        ((DwgPolyline2D)pol).setBulges(bs);
629
//                                        //Point2D[] points = GisModelCurveCalculator.calculateGisModelBulge(newPts, bs);
630
//                                        Point2D[] points = new Point2D[pts.size()];
631
//                                        for (int j=0;j<pts.size();j++) {
632
//                                            points[j] = (Point2D)pts.get(j);
633
//                                        }
634
//                                        ((DwgPolyline2D)pol).setPts(points);
635
//                                } else {
636
////                                        System.out.println("Encontrada polil?nea sin puntos ...");
637
//                                        // TODO: No se debe mandar nunca una polil?nea sin puntos, si esto
638
//                                        // ocurre es porque existe un error que hay que corregir ...
639
//                                }
640
//                        } else if (pol instanceof DwgPolyline3D) {
641
//                        } else if (pol instanceof DwgLwPolyline && ((DwgLwPolyline)pol).getVertices()!=null) {
642
//                        }
643
//                }
644
//        }
645
        
646
        /*
647
         * TODO Revisar los bloques que son XREF
648
         * */
649
        public void blockManagement2(){
650
                Iterator it = null;
651
                
652
                
653
                //dwg v12 blocks already has their entities added
654
                //for the rest of versions, we add block entities to their owner block
655
                if(! (dwgReader instanceof DwgFileV12Reader)){
656
                        //once we have read all dwg entities, we look for all of them
657
                        //that has a superentity that is a block (to fill in the entity list
658
                        //of each block
659
                        it = dwgObjects.iterator();
660
                        int i = 0;
661
                        while(it.hasNext()){
662
                                DwgObject entity = (DwgObject)it.next();
663
                                DwgObject superEnt = getDwgSuperEntity(entity);
664
                                if(superEnt instanceof DwgBlockHeader){
665
                                        DwgBlockHeader blk = (DwgBlockHeader)superEnt;
666
                                        blk.addObject(entity);
667
                                        it.remove();//TODO Creo que esto es lento, mejor
668
                                        //el metodo original (en java solo se duplican las referencias)
669
                                        i++;
670
                                        
671
                                
672
                                        if(blk.isBlkIsXRef()){
673
                                                 System.out.println("bloque "+blk.getName()+" es referencia externa");
674
                                                 System.out.println("path="+blk.getXRefPName());
675
                                                 String path = blk.getXRefPName();
676
                                                 DwgFile externalRef = new DwgFile(path);
677
                                                 try {
678
                                                        externalRef.read();
679
                                                        externalRef.calculateGisModelDwgPolylines();
680
                                                        externalRef.blockManagement2();
681
                                                        List dwgObjects = externalRef.getDwgObjects();
682
                                                        blk.getObjects().addAll(dwgObjects);
683
                                                } catch (IOException e) {
684
                                                        // TODO Auto-generated catch block
685
                                                        e.printStackTrace();
686
                                                        continue;
687
                                                } catch (DwgVersionNotSupportedException e) {
688
                                                        // TODO Auto-generated catch block
689
                                                        e.printStackTrace();
690
                                                        continue;
691
                                                }
692
                                         }                                        
693
                                        
694
                                        
695
                                }
696
                        }//while
697
                }//if dwgfilev12
698
                
699
                //after that, we process the INSERTs
700
                it = insertList.iterator();
701
                while(it.hasNext()){
702
                        DwgInsert insert = (DwgInsert) it.next();
703
                        if(insert.isProcessed()){
704
                                //It has been processed nexted to other insert
705
                                continue;
706
                        }
707
                        insert.setProcessed(true);
708
                        double[] p = insert.getInsertionPoint();
709
                        Point2D point = new Point2D.Double(p[0], p[1]);
710
                        double[] scale = insert.getScale();
711
                        double rot = insert.getRotation();
712
                        int blockHandle = insert.getBlockHeaderHandle().getOffset();
713
                        manageInsert2(point, scale,
714
                                        rot, blockHandle, 
715
                                        dwgObjects, handle_objects);
716
                }        
717

    
718
}
719

    
720
   
721
        
722
        public void manageInsert2(Point2D insPoint, double[] scale,
723
                        double rot, int bHandle, 
724
                        List dwgObjectsWithoutBlocks, 
725
                        Map handleObjectsWithoutBlocks) {
726
                
727
                DwgObject object = (DwgObject) handle_objects.get(new Integer(bHandle));
728
                if(object == null){
729
                        logger.error("No hemos encontrado el BlockHeader cuyo handle es "+bHandle);
730
                        return;
731
                }else if(! (object instanceof DwgBlockHeader)){
732
                        //Hay un problema con la asignaci?n de handle
733
                        //Un INSERT tiene como handle de Block una entidad que no es block
734
                        logger.error("handle incorrecto." + object.getClass().getName() + " no es un blockheader");
735
                        return;
736
                }
737
                
738
                DwgBlockHeader blockHeader = (DwgBlockHeader)object;
739
                double[] bPoint = blockHeader.getBasePoint();
740
                String bname = blockHeader.getName();
741
                if (bname.startsWith("*")) 
742
                        return;
743
                
744
                //TODO Cambiar por List
745
                Vector entities = blockHeader.getObjects();
746
                if(entities.size() == 0){
747
                        logger.warn("El bloque "+blockHeader.getName()+" no tiene ninguna entidad");
748
                }
749
                Iterator blkEntIt = entities.iterator();
750
                while(blkEntIt.hasNext()){
751
                        DwgObject obj = (DwgObject) blkEntIt.next();
752
                         manageBlockEntity(obj, bPoint, 
753
                                           insPoint, scale, 
754
                                           rot, dwgObjectsWithoutBlocks,
755
                                           handleObjectsWithoutBlocks);        
756
                }//while
757
        }
758
        
759
   
760
        public int getIndexOf(DwgObject dwgObject){
761
                return dwgObjects.indexOf(dwgObject);        
762
        }
763
        
764
        
765
        
766
    /**
767
     * Changes the location of an object extracted from a block. This location will be
768
     * obtained through the insertion parameters from the block and the corresponding
769
     * insert.
770
     * @param entity, the entity extracted from the block.
771
     * @param bPoint, offset for the coordinates of the entity.
772
     * @param insPoint, coordinates of the insertion point for the entity.
773
     * @param scale, scale for the entity.
774
     * @param rot, rotation angle for the entity.
775
     * @param id, a count as a id.
776
     * @param dwgObjectsWithoutBlocks, a object list with the elements extracted from
777
     * the blocks.
778
     */
779
        private void manageBlockEntity(DwgObject entity, 
780
                                                                        double[] bPoint, 
781
                                                                        Point2D insPoint, 
782
                                                                        double[] scale, 
783
                                                                        double rot, 
784
                                                                        List dwgObjectsWithoutBlocks,
785
                                                                        Map handleObjectsWithoutBlocks) {
786
                
787
                if(entity instanceof IDwgBlockMember){
788
                        IDwgBlockMember blockMember = (IDwgBlockMember)entity;
789
                        blockMember.transform2Block(bPoint, insPoint, scale, rot, 
790
                                        dwgObjectsWithoutBlocks,
791
                                        handleObjectsWithoutBlocks,this);
792
                }
793
                
794
        }
795
        
796
        
797
        /**
798
         * Add a DWG section offset to the dwgSectionOffsets vector
799
         * 
800
         * @param key Define the DWG section
801
         * @param seek Offset of the section
802
         * @param size Size of the section
803
         */
804
        public void addDwgSectionOffset(String key, int seek, int size) {
805
                DwgSectionOffset dso = new DwgSectionOffset(key, seek, size);
806
                dwgSectionOffsets.add(dso);
807
        }
808
        
809
        /**
810
     * Returns the offset of DWG section given by its key 
811
         * 
812
     * @param key Define the DWG section
813
         * @return int Offset of the section in the DWG file
814
         */
815
        public int getDwgSectionOffset(String key) {
816
                int offset = 0;
817
                for (int i=0; i<dwgSectionOffsets.size(); i++) {
818
                        DwgSectionOffset dso = (DwgSectionOffset)dwgSectionOffsets.get(i);
819
                        String ikey = dso.getKey();
820
                        if (key.equals(ikey)) {
821
                                offset = dso.getSeek();
822
                                break;
823
                        }
824
                }
825
                return offset;
826
        }
827
        
828
        /**
829
         * Add a DWG object offset to the dwgObjectOffsets vector
830
         * 
831
         * @param handle Object handle
832
         * @param offset Offset of the object data in the DWG file
833
         */
834
        public void addDwgObjectOffset(int handle, int offset) {
835
                DwgObjectOffset doo = new DwgObjectOffset(handle, offset);
836
                dwgObjectOffsets.add(doo);
837
        }
838
        
839
        /**
840
         * 
841
         * Add a DWG object to the dwgObject vector
842
         * 
843
         * @param dwgObject DWG object
844
         */
845
        public void addDwgObject(DwgObject dwgObject){
846
                //TODO Ver si puedo inicializar las listas especificas
847
                //(IDwgPolyline, etc) aqu? 
848
                dwgObjects.add(dwgObject);
849
                handle_objects.put(new Integer(dwgObject.getHandle().getOffset()), dwgObject);
850
                
851
                /*
852
                 * TODO Quitar todos estos if-then y sustituirlos por un metodo callback
853
                 * 
854
                 * 
855
                 * (dwgObject.init(this), y que cada objeto haga lo que tenga que hacer
856
                 * */
857
                if(dwgObject instanceof DwgLayer){
858
                        this.addDwgLayer((DwgLayer) dwgObject);
859
                }
860
                
861
                //Probamos a no aplicar las extrusiones
862
                
863
                if(dwgObject instanceof IDwgExtrusionable){
864
                        ((IDwgExtrusionable)dwgObject).applyExtrussion();
865
                                
866
                }
867
                
868
                if(dwgObject instanceof IDwgPolyline){
869
                        dwgPolylines.add(dwgObject);
870
                }
871
                if(dwgObject instanceof IDwg3DTestable){
872
                        if(! dwg3DFile){//if its true, we dont check again
873
                                dwg3DFile = ((IDwg3DTestable)dwgObject).has3DData();
874
                        }
875
                }
876
                if(dwgObject instanceof DwgInsert){
877
                        insertList.add(dwgObject);
878
                }
879
                
880
                if(dwgObject instanceof DwgBlockHeader){
881
                        blockList.add(dwgObject);
882
                }
883
        }
884
        
885
        /**
886
         * Returns dwgObjects from its insertion order (position
887
         * in the dwg file)
888
         * 
889
         * @param index order in the dwg file
890
         * @return position
891
         * */
892
        public DwgObject getDwgObject(int index){
893
                return (DwgObject) dwgObjects.get(index);
894
        }
895
        
896
        public DwgObject getDwgObjectFromHandle(int handle){
897
                return (DwgObject) handle_objects.get(new Integer(handle));
898
        }
899
        
900
        /**
901
         * Add a DWG class to the dwgClasses vector
902
         * 
903
         * @param dwgClass DWG class
904
         */
905
        public void addDwgClass(DwgClass dwgClass){
906
                dwgClasses.add(dwgClass);
907
        }
908
        
909
        public void printClasses(){
910
                logger.info("#### CLASSES ####");
911
                for(int i = 0; i < dwgClasses.size(); i++){
912
                        DwgClass clazz = (DwgClass) dwgClasses.get(i);
913
                        logger.info(clazz.toString());
914
                }
915
                logger.info("#############");
916
        }
917
        
918
        public List getDwgClasses(){
919
                return dwgClasses;
920
        }
921
        
922
    /**
923
     * @return Returns the dwgObjectOffsets.
924
     */
925
    public ArrayList getDwgObjectOffsets() {
926
        return dwgObjectOffsets;
927
    }
928
    /**
929
     * @return Returns the dwgObjects.
930
     */
931
    public List getDwgObjects() {
932
        return dwgObjects;
933
    }
934
    /**
935
     * @return Returns the fileName.
936
     */
937
    public String getFileName() {
938
        return fileName;
939
    }
940
    /**
941
     * @return Returns the dwg3DFile.
942
     */
943
    public boolean isDwg3DFile() {
944
        return dwg3DFile;
945
    }
946
    /**
947
     * @param dwg3DFile The dwg3DFile to set.
948
     */
949
    public void setDwg3DFile(boolean dwg3DFile) {
950
        this.dwg3DFile = dwg3DFile;
951
    }
952
}