Statistics
| Revision:

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

History | View | Annotate | Download (31.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
        private String fileName;
112
        private String dwgVersion;
113
        
114
        /**
115
         * Offsets to the DWG sections
116
         */
117
        private ArrayList dwgSectionOffsets;
118
        /**
119
         * Header vars readed from the HEADER section of the DWG file
120
         * */
121
        private Map headerVars;
122
        
123
        /**
124
         * This list contains what in OpenDWG specification is called
125
         * the object map ( a collection of entries where each entry contains
126
         * the seek of each object, and its size)
127
         * */
128
        private ArrayList dwgObjectOffsets;
129
        
130
        /**
131
         * For each entry in dwgObjectOffsets, we have an instance of
132
         * DwgObject in the dwgObjects collection
133
         * 
134
         * */
135
        private LinkedList dwgObjects;
136
        private HashMap handle_objects;
137
        
138

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

    
296
                System.out.println ("handleCode = "+entity.getHandle().getCode());
297
                System.out.println ("entityLayerHandle = "+entity.getHandle().getOffset());
298
                if(entity.hasLayerHandle()){
299
                        System.out.println ("layerHandleCode = "+entity.getLayerHandle().getCode());
300
                        System.out.println ("layerHandle = "+entity.getLayerHandle().getOffset());
301
                }
302
                if(entity.hasSubEntityHandle()){
303
                        System.out.println ("subEntityHandleCode = "+entity.getSubEntityHandle().getCode());
304
                        System.out.println ("subEntityHandle = "+entity.getSubEntityHandle().getOffset());
305
                }
306
                if(entity.hasNextHandle()){
307
                        System.out.println ("nextHandleCode = "+entity.getNextHandle().getCode());
308
                        System.out.println ("nextHandle = "+entity.getNextHandle().getOffset());
309
                }
310
                if(entity.hasPreviousHandle()){
311
                        System.out.println ("previousHandleCode = "+entity.getPreviousHandle().getCode());
312
                        System.out.println ("previousHandle = "+entity.getPreviousHandle().getOffset());
313
                }
314
                if(entity.hasXDicObjHandle()){
315
                        System.out.println ("xDicObjHandleCode = "+entity.getXDicObjHandle());
316
                        System.out.println ("xDicObjHandle = "+entity.getXDicObjHandle());
317
                }
318
                if(entity.hasReactorsHandles()){
319
                        ArrayList reactorsHandles = entity.getReactorsHandles();
320
                        int size = reactorsHandles.size();
321
                        System.out.print ("NUMERO DE reactors = "+size);
322
                        DwgHandleReference hr;
323
                        for(int i=0; i<size; i++){
324
                                hr=(DwgHandleReference)reactorsHandles.get(i);
325
                                System.out.print ("reactorHandleCode = "+hr.getCode());
326
                                System.out.println (" reactorHandle = "+hr.getOffset());
327
                        }
328
                }
329
                
330
        }
331
        public DwgLayer getDwgLayer(DwgObject entity){
332
                DwgHandleReference handle = entity.getLayerHandle();
333
                if(handle == null){
334
//                        System.out.print("Entidad con layer handle a null (debe ser una LwPolyline) ==> ");
335
//                        System.out.println(entity.getClass().getName());
336
                        //TODO Ver que hacemos con estas entidades (lanzan excepcion antes de hacer readTailer)
337
                        return null;
338
                }
339
                int        handleCode = handle.getCode();
340
                int        entityLayerHandle = entity.getLayerHandle().getOffset();
341
                int layerHandle = -1;
342
                
343
                int entityRecord;
344
                DwgObject object;
345
                
346
                
347
                /*
348
                 * OpenDWG spec, v3, page 11. HANDLE REFERENCES
349
                 * 
350
                 * A handle is formed by this fields:
351
                 * a) CODE (4 bits)
352
                 * b) COUNTER (4 bits)
353
                 * c) OFFSET of the object (handle itself).
354
                 * 
355
                 * CODE could take these values:
356
                 * 1) 0x2, 0x3, 0x4, 0x5 -> offset is the handle of the layer
357
                 * 2) 0x6 -> offset is the next object handle
358
                 * 3) 0x8 -> offset is the previous object handle
359
                 * 4) 0xA -> result is reference handle plus offset
360
                  * 5) 0xC -> result is reference handle minus offset
361
                 * 
362
                 * */
363
                
364
                // FIXME: Esto no esta terminado. Falta considerar los codigo
365
                // 0x2, 0x3, 0x6, 0xA que no han aparecido en los archivos de prueba.
366
                switch(handleCode){
367
                case 0x4:
368
                        if (entity.hasNextHandle()){
369
                                int nextHandleCode = entity.getNextHandle().getCode();
370
                                if (nextHandleCode == 0x5) {
371
                                        layerHandle = entity.getNextHandle().getOffset();
372
                                } else {
373
                                        //TODO: No se han previsto nextHandleCode != 0x5
374
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
375
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
376
                                }
377
                        } else {
378
                                layerHandle = entity.getLayerHandle().getOffset();
379
                        }
380
                        break;
381
                case 0x5:
382
                        layerHandle = entity.getLayerHandle().getOffset();
383
                        break;
384
                case 0x8:
385
                        if (entity.hasNextHandle()){
386
                                int nextHandleCode = entity.getNextHandle().getCode();
387
                                if (nextHandleCode == 0x5) {
388
                                        layerHandle = entity.getNextHandle().getOffset();
389
                                } else {
390
                                        //TODO No se han previsto nextHandleCode != 0x5
391
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
392
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
393
                                }
394
                        } else {
395
                                layerHandle = entity.getHandle().getOffset() - 1;
396
                        }
397
                        break;
398
                case 0xC:
399
                        if (entity.hasNextHandle()){
400
                                int nextHandleCode = entity.getNextHandle().getCode();
401
                                if (nextHandleCode == 0x5) {
402
                                        layerHandle = entity.getNextHandle().getOffset();
403
                                } else {
404
                                        //TODO: No se han previsto nextHandleCode != 0x5
405
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
406
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
407
                                }
408
                        } else {
409
                                layerHandle = entity.getHandle().getOffset() - entity.getLayerHandle().getOffset() + 1;
410
                        }
411
                        break;
412
                default:
413
//                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+" no implementado. entityLayerHandle="+entityLayerHandle);
414
                }
415
                
416
                if(layerHandle != -1){
417
                        Iterator lyrIterator = layerTable.values().iterator();
418
                        while(lyrIterator.hasNext()){
419
                                DwgLayer lyr = (DwgLayer) lyrIterator.next();
420
                                int lyrHdl = lyr.getHandle().getOffset();
421
                                if (lyrHdl == layerHandle){
422
                                        return lyr;
423
                                }
424
                        }
425
                }
426
//                System.out.println("NO SE HA ENCONTRADO UNA CAPA CON HANDLE " + layerHandle);
427
//                printInfoOfAObject(entity);
428
                return null;
429
        }
430
        
431
   
432
        public String getLayerName(DwgObject entity) {                
433
                DwgLayer dwgLayer = getDwgLayer(entity);
434
                if(dwgLayer == null){//TODO Puede haber entidades sin layer???
435
                        return "";
436
                }else{
437
                        return dwgLayer.getName();
438
                }
439
        }
440
        
441
        /**
442
     * Returns the color of the layer of a DWG object 
443
         * 
444
     * @param entity DWG object which we want to know its layer color
445
         * @return int Layer color of the DWG object in the Autocad color code
446
         */
447
        public int getColorByLayer(DwgObject entity) {
448
                int colorByLayer;
449
                DwgLayer dwgLyr = getDwgLayer(entity);
450
                if(dwgLyr == null)
451
                        colorByLayer = 0;
452
                else
453
                        colorByLayer = dwgLyr.getColor();
454
                return colorByLayer;
455
        }
456
        
457

    
458
        //azabala: esto ahora se hace conforme se van creando los objetos
459
        //(y no al final en una segunda pasada
460
//    public void applyExtrusions() {
461
//        for (int i=0;i<dwgObjects.size();i++) {
462
//            DwgObject dwgObject = (DwgObject)dwgObjects.get(i);
463
//            if(dwgObject instanceof IDwgExtrusionable){
464
//                    ((IDwgExtrusionable)dwgObject).applyExtrussion();
465
//            }
466
//            // Seems that Autocad don't apply the extrusion to Ellipses
467
//            /*} else if (dwgObject instanceof DwgEllipse) {
468
//                double[] ellipseCenter = ((DwgEllipse)dwgObject).getCenter();
469
//                double[] ellipseExt = ((DwgEllipse)dwgObject).getExtrusion();
470
//                ellipseCenter = AcadExtrusionCalculator.CalculateAcadExtrusion(ellipseCenter, ellipseExt);
471
//                ((DwgEllipse)dwgObject).setCenter(ellipseCenter);*/
472
//        }//for
473
//    }
474
        
475
        /**
476
         * Configure the geometry of the polylines in a DWG file from the vertex list in
477
         * this DWG file. This geometry is given by an array of Points.
478
         * Besides, manage closed polylines and polylines with bulges in a GIS Data model.
479
     * It means that the arcs of the polylines will be done through a set of points and
480
     * a distance between these points.
481
         */
482
        public void calculateGisModelDwgPolylines() {
483
                /*
484
                 * Ahora mismo esto se est? haciendo al final (en una segunda pasada)
485
                 * porque posiblemente una Linea requiera de vertices que vengan
486
                 * despues, lo que complicar?a bastante todo....
487
                 * */
488
                
489
//                for (int i=0;i<dwgObjects.size();i++) {
490
                for (int i = 0; i < dwgPolylines.size(); i++){
491
//                        DwgObject pol = (DwgObject)dwgObjects.get(i);
492
                        DwgObject pol = (DwgObject)dwgPolylines.get(i);
493
                        if (pol instanceof IDwgPolyline) {
494
//                                ((IDwgPolyline)pol).calculateGisModel(dwgObjects);
495
                                ((IDwgPolyline)pol).calculateGisModel(this);
496
                        } 
497
                }
498
        }
499
        
500
    /**
501
     * Configure the geometry of the polylines in a DWG file from the vertex list in
502
     * this DWG file. This geometry is given by an array of Points
503
     * Besides, manage closed polylines and polylines with bulges in a GIS Data model.
504
     * It means that the arcs of the polylines will be done through a curvature
505
     * parameter called bulge associated with the points of the polyline.
506
     */
507
        //TODO Refactorizar para que solo se aplique a las Polilineas
508
        public void calculateCadModelDwgPolylines() {
509
                for (int i=0;i<dwgObjects.size();i++) {
510
                        DwgObject pol = (DwgObject)dwgObjects.get(i);
511
                        if (pol instanceof DwgPolyline2D) {
512
                                int flags = ((DwgPolyline2D)pol).getFlags();
513
                                int firstHandle = ((DwgPolyline2D)pol).getFirstVertexHandle().getOffset();
514
                                int lastHandle = ((DwgPolyline2D)pol).getLastVertexHandle().getOffset();
515
                                ArrayList pts = new ArrayList();
516
                                ArrayList bulges = new ArrayList();
517
                                double[] pt = new double[3];
518
                                for (int j=0;j<dwgObjects.size();j++) {
519
                                        DwgObject firstVertex = (DwgObject)dwgObjects.get(j);
520
                                        if (firstVertex instanceof DwgVertex2D) {
521
                                                int vertexHandle = firstVertex.getHandle().getOffset();
522
                                                if (vertexHandle==firstHandle) {
523
                                                        int k=0;
524
                                                        while (true) {
525
                                                                DwgObject vertex = (DwgObject)dwgObjects.get(j+k);
526
                                                                int vHandle = vertex.getHandle().getOffset();
527
                                                                if (vertex instanceof DwgVertex2D) {
528
                                                                        pt = ((DwgVertex2D)vertex).getPoint();
529
                                                                        pts.add(new Point2D.Double(pt[0], pt[1]));
530
                                                                        double bulge = ((DwgVertex2D)vertex).getBulge();
531
                                                                        bulges.add(new Double(bulge));
532
                                                                        k++;
533
                                                                        if (vHandle==lastHandle && vertex instanceof DwgVertex2D) {
534
                                                                                break;
535
                                                                        }
536
                                                                } else if (vertex instanceof DwgSeqend) {
537
                                                                        break;
538
                                                                }
539
                                                        }
540
                                                }
541
                                        }
542
                                }
543
                                if (pts.size()>0) {
544
                                        /*Point2D[] newPts = new Point2D[pts.size()];
545
                                        if ((flags & 0x1)==0x1) {
546
                                                newPts = new Point2D[pts.size()+1];
547
                                                for (int j=0;j<pts.size();j++) {
548
                                                        newPts[j] = (Point2D)pts.get(j);
549
                                                }
550
                                                newPts[pts.size()] = (Point2D)pts.get(0);
551
                                                bulges.add(new Double(0));
552
                                        } else {
553
                                                for (int j=0;j<pts.size();j++) {
554
                                                        newPts[j] = (Point2D)pts.get(j);
555
                                                }
556
                                        }*/
557
                                        double[] bs = new double[bulges.size()];
558
                                        for (int j=0;j<bulges.size();j++) {
559
                                                bs[j] = ((Double)bulges.get(j)).doubleValue();
560
                                        }
561
                                        ((DwgPolyline2D)pol).setBulges(bs);
562
                                        //Point2D[] points = GisModelCurveCalculator.calculateGisModelBulge(newPts, bs);
563
                                        Point2D[] points = new Point2D[pts.size()];
564
                                        for (int j=0;j<pts.size();j++) {
565
                                            points[j] = (Point2D)pts.get(j);
566
                                        }
567
                                        ((DwgPolyline2D)pol).setPts(points);
568
                                } else {
569
//                                        System.out.println("Encontrada polil?nea sin puntos ...");
570
                                        // TODO: No se debe mandar nunca una polil?nea sin puntos, si esto
571
                                        // ocurre es porque existe un error que hay que corregir ...
572
                                }
573
                        } else if (pol instanceof DwgPolyline3D) {
574
                        } else if (pol instanceof DwgLwPolyline && ((DwgLwPolyline)pol).getVertices()!=null) {
575
                        }
576
                }
577
        }
578
        
579
    /**
580
     * Modify the geometry of the objects contained in the blocks of a DWG file and
581
     * add these objects to the DWG object list.
582
     * 
583
     * TODO Revisar los bloques que son XREF
584
     */
585
        public void blockManagement() {
586
                LinkedList dwgObjectsWithoutBlocks = new LinkedList();
587
            boolean addingToBlock = false;
588
            try{
589
                        for (int i=0; i < dwgObjects.size(); i++) {
590
                                DwgObject entity = (DwgObject)dwgObjects.get(i);
591
                                if (entity instanceof DwgArc && !addingToBlock) {
592
                                        dwgObjectsWithoutBlocks.add(entity);
593
                                } else if (entity instanceof DwgEllipse && !addingToBlock) {
594
                                        dwgObjectsWithoutBlocks.add(entity);
595
                                } else if (entity instanceof DwgCircle && !addingToBlock) {
596
                                        dwgObjectsWithoutBlocks.add(entity);
597
                                } else if (entity instanceof DwgPolyline2D && !addingToBlock) {
598
                                        dwgObjectsWithoutBlocks.add(entity);
599
                                } else if (entity instanceof DwgPolyline3D && !addingToBlock) {
600
                                        dwgObjectsWithoutBlocks.add(entity);
601
                                } else if (entity instanceof DwgLwPolyline && !addingToBlock) {
602
                                        dwgObjectsWithoutBlocks.add(entity);
603
                                } else if (entity instanceof DwgSolid && !addingToBlock) {
604
                                        dwgObjectsWithoutBlocks.add(entity);
605
                                } else if (entity instanceof DwgLine && !addingToBlock) {
606
                                        dwgObjectsWithoutBlocks.add(entity);
607
                                } else if (entity instanceof DwgPoint && !addingToBlock) {
608
                                        dwgObjectsWithoutBlocks.add(entity);
609
                                } else if (entity instanceof DwgMText && !addingToBlock) {
610
                                        dwgObjectsWithoutBlocks.add(entity);
611
                                } else if (entity instanceof DwgText && !addingToBlock) {
612
                                        dwgObjectsWithoutBlocks.add(entity);
613
                                } else if (entity instanceof DwgAttrib && !addingToBlock) {
614
                                        dwgObjectsWithoutBlocks.add(entity);
615
                                } else if (entity instanceof DwgAttdef && !addingToBlock) {
616
                                        dwgObjectsWithoutBlocks.add(entity);
617
                                } else if (entity instanceof DwgBlock) {
618
                                        addingToBlock = true;
619
                                } else if (entity instanceof DwgEndblk) {
620
                                        addingToBlock = false;
621
                                } else if (entity instanceof DwgBlockHeader) {
622
                                        addingToBlock = true;
623
                                } 
624
                                //Segun esto, un insert solo se procesa dentro de un Block (o BlockHeader)
625
                                //?Puede haber INSERT fuera de BLOCK-ENDBLK?
626
                                else if (entity instanceof DwgInsert && !addingToBlock) {
627
                                        double[] p = ((DwgInsert)entity).getInsertionPoint();
628
                                        Point2D point = new Point2D.Double(p[0], p[1]);
629
                                        double[] scale = ((DwgInsert)entity).getScale();
630
                                        double rot = ((DwgInsert)entity).getRotation();
631
                                        int blockHandle = ((DwgInsert)entity).getBlockHeaderHandle().getOffset();
632
                                        manageInsert(point, scale, rot, blockHandle, dwgObjectsWithoutBlocks);
633
                                } else {
634
        //                                System.out.println(entity.getClass().getName() +" en un bloque");
635
                                        //Se ha encontrado una entidad rara, o forma parte de un bloque
636
                                        //y ser? procesada despu?s (con los punteros del propio bloque)
637
                                        
638
                                        //TODO No se podr?a hacer mas rapido, quitando de la lista original
639
                                        //las entidades que forman parte de bloque??
640
                                }
641
                        }
642
            }catch(RuntimeException re){
643
                    re.printStackTrace();
644
            }
645
                dwgObjects = dwgObjectsWithoutBlocks;
646
        }
647
        
648
    /**
649
     * Manages an INSERT of a DWG file. This object is the insertion point of a DWG
650
     * block. 
651
     * 
652
     * @param insPoint, coordinates of the insertion point.
653
     * @param scale, scale of the elements of the block that will be inserted.
654
     * @param rot, rotation angle of the elements of the block.
655
     * 
656
     * @param bHandle, offset for the coordinates of the elements of the block.
657
     * @param id, count that serves as a id.
658
     * @param dwgObjectsWithoutBlocks, a object list with the elements extracted from
659
     * the blocks.
660
     */
661
        public void manageInsert(Point2D insPoint, double[] scale,
662
                                                        double rot, int bHandle, 
663
                                                        List dwgObjectsWithoutBlocks) {
664
                
665
                DwgObject object = (DwgObject) handle_objects.get(new Integer(bHandle));
666
                if(object == null){
667
//                        System.out.println("No hemos encontrado el BlockHeader cuyo handle es "+bHandle);
668
                        return;
669
                }else if(! (object instanceof DwgBlockHeader)){
670
                        //Hay un problema con la asignaci?n de handle
671
                        //Un INSERT tiene como handle de Block una entidad que no es block
672
//                        System.out.println("handle incorrecto." + object.getClass().getName() + " no es un blockheader");
673
                        return;
674
                }
675
                DwgBlockHeader blockHeader = (DwgBlockHeader)object;
676
                double[] bPoint = blockHeader.getBasePoint();
677
                String bname = blockHeader.getName();
678
                if (bname.startsWith("*")) 
679
                        return;
680
                
681
                DwgHandleReference firstHdl = blockHeader.getFirstEntityHandle();
682
                DwgHandleReference lastHdl = blockHeader.getLastEntityHandle();
683
                if(firstHdl == null || lastHdl == null){
684
//                        System.out.println("Problemas en el bloque "+bname);
685
//                        System.out.println("1er obj="+firstHdl+" 2o obj="+lastHdl);
686
                        return;
687
                }        
688
                
689
                
690
                
691
                int firstObjectHandle = firstHdl.getOffset();   
692
                int lastObjectHandle = lastHdl.getOffset();
693
                
694
                //TODO Ver que hacia el metodo antiguo cuando llegaban handles a 0
695
                //como extremos de un bloque (sera bloque vacio, supongo)
696
                if(firstObjectHandle == 0 || lastObjectHandle == 0){
697
//                        System.out.println("Problemas en el bloque "+bname);
698
//                        System.out.println("1er obj="+firstObjectHandle+" 2o obj="+lastObjectHandle);
699
                        return;
700
                }        
701
                
702
                /*
703
                 * Ahora localiza la primera entidad del bloque, 
704
                 * y a partir de ah?, a?ade
705
                 * al bloque todas las entidades que encuentre hasta la 
706
                 * ?ltima entidad del bloque
707
                 * 
708
                 * */
709
                 DwgObject firstObj = (DwgObject) handle_objects.
710
                                                 get(new Integer(firstObjectHandle));
711
                 DwgObject lastObj =  (DwgObject) handle_objects.
712
                                                 get(new Integer(lastObjectHandle));
713
                 
714
                 int firstObjIdx = dwgObjects.indexOf(firstObj);
715
                 int lastObjIdx = dwgObjects.indexOf(lastObj);
716
                 if(firstObjIdx == -1){
717
//                         System.out.println("El primer objeto del bloque "+
718
//                                                         blockHeader.getName()+
719
//                                                 " no ha sido localizado a partir del handle "+
720
//                                                 firstObjectHandle);
721
                         return;
722
                 }
723
                         
724
                 if(lastObjIdx == -1){
725
//                         System.out.println("El ultimo objeto del bloque "+
726
//                                                         blockHeader.getName()+
727
//                                                 " no ha sido localizado a partir del handle "+
728
//                                                 lastObjectHandle);
729
                         
730
                         //Intentamos ver si como delimitador final de bloque aparece EndBlk
731
                         LinkedList tempDwgObj = new LinkedList();
732
                         DwgObject scannedEntity = (DwgObject) dwgObjects.get(firstObjIdx);
733
                         while(! (scannedEntity instanceof DwgEndblk)){
734
                                 manageBlockEntity(scannedEntity, bPoint, 
735
                                                 insPoint, scale, rot, 
736
                                                 tempDwgObj);
737
                                 firstObjIdx++;
738
                                 scannedEntity = (DwgObject) dwgObjects.get(firstObjIdx);
739
                                 if( (scannedEntity instanceof DwgBlock) ||
740
                                        (scannedEntity instanceof DwgBlockHeader)){
741
                                         //No puede haber bloques anidados
742
                                         //Descartar 
743
//                                         System.out.println("Error, aparecen bloques anidados");
744
                         return;
745
                 }
746
                         }//while
747
                         if(tempDwgObj.size() > 0)
748
                                 dwgObjectsWithoutBlocks.addAll(tempDwgObj);
749
                         return;
750
                         
751
                 }//if
752
                 for(int i = firstObjIdx; i <= lastObjIdx; i++){
753
                         DwgObject obj = (DwgObject) dwgObjects.get(i);
754
                         manageBlockEntity(obj, bPoint, 
755
                                                           insPoint, scale, 
756
                                                           rot, dwgObjectsWithoutBlocks);
757
                 }//for
758
        }
759
        
760
        public int getIndexOf(DwgObject dwgObject){
761
                return dwgObjects.indexOf(dwgObject);
762
                
763
                
764
        }
765
        
766
        
767
        
768
    /**
769
     * Changes the location of an object extracted from a block. This location will be
770
     * obtained through the insertion parameters from the block and the corresponding
771
     * insert.
772
     * @param entity, the entity extracted from the block.
773
     * @param bPoint, offset for the coordinates of the entity.
774
     * @param insPoint, coordinates of the insertion point for the entity.
775
     * @param scale, scale for the entity.
776
     * @param rot, rotation angle for the entity.
777
     * @param id, a count as a id.
778
     * @param dwgObjectsWithoutBlocks, a object list with the elements extracted from
779
     * the blocks.
780
     */
781
        private void manageBlockEntity(DwgObject entity, 
782
                                                                        double[] bPoint, 
783
                                                                        Point2D insPoint, 
784
                                                                        double[] scale, 
785
                                                                        double rot, 
786
                                                                        List dwgObjectsWithoutBlocks) {
787
                
788
                if(entity instanceof IDwgBlockMember){
789
                        IDwgBlockMember blockMember = (IDwgBlockMember)entity;
790
                        blockMember.transform2Block(bPoint, insPoint, scale, rot, dwgObjectsWithoutBlocks, this);
791
                }else{
792
                        //TODO REIMPLEMENTAR ENTIDADES QUE PUEDEN FORMAR PARTE DE BLOQUES.
793
                        //POR EJEMPLO: DwgText y DwgMText pueden formar parte 
794
                        //de bloques, y de hecho, est?n apareciendo
795
                        
796
//                        System.out.println(entity.getClass().getName()+" dentro de un bloque");
797
                }
798
        }
799
        
800
        
801
        /*
802
         * azabala: Esto ahora se hace mientras las entidades dwg
803
         * se van creando, y no en una segunda pasada
804
         * */
805
        /*
806
        public void testDwg3D() {
807
                for (int i=0;i<dwgObjects.size();i++) {
808
                        DwgObject obj = (DwgObject)dwgObjects.get(i);
809
                        
810
                        if(obj instanceof IDwg3DTestable){
811
                                if(((IDwg3DTestable)obj).has3DData())
812
                                        dwg3DFile = true;
813
                                return;
814
                        }
815
                        
816
                        //} else if (obj instanceof DwgLinearDimension) {
817
                        //        z = ((DwgLinearDimension)obj).getElevation();
818
                        //        if (z!=0.0) dwg3DFile = true;         
819
                }//for
820
                dwg3DFile = false;
821
        }
822
        */
823
        
824
        /**
825
         * Add a DWG section offset to the dwgSectionOffsets vector
826
         * 
827
         * @param key Define the DWG section
828
         * @param seek Offset of the section
829
         * @param size Size of the section
830
         */
831
        public void addDwgSectionOffset(String key, int seek, int size) {
832
                DwgSectionOffset dso = new DwgSectionOffset(key, seek, size);
833
                dwgSectionOffsets.add(dso);
834
        }
835
        
836
        /**
837
     * Returns the offset of DWG section given by its key 
838
         * 
839
     * @param key Define the DWG section
840
         * @return int Offset of the section in the DWG file
841
         */
842
        public int getDwgSectionOffset(String key) {
843
                int offset = 0;
844
                for (int i=0; i<dwgSectionOffsets.size(); i++) {
845
                        DwgSectionOffset dso = (DwgSectionOffset)dwgSectionOffsets.get(i);
846
                        String ikey = dso.getKey();
847
                        if (key.equals(ikey)) {
848
                                offset = dso.getSeek();
849
                                break;
850
                        }
851
                }
852
                return offset;
853
        }
854
        
855
        /**
856
         * Add a DWG object offset to the dwgObjectOffsets vector
857
         * 
858
         * @param handle Object handle
859
         * @param offset Offset of the object data in the DWG file
860
         */
861
        public void addDwgObjectOffset(int handle, int offset) {
862
                DwgObjectOffset doo = new DwgObjectOffset(handle, offset);
863
                dwgObjectOffsets.add(doo);
864
        }
865
        
866
        /**
867
         * 
868
         * Add a DWG object to the dwgObject vector
869
         * 
870
         * @param dwgObject DWG object
871
         */
872
        public void addDwgObject(DwgObject dwgObject){
873
                //TODO Ver si puedo inicializar las listas especificas
874
                //(IDwgPolyline, etc) aqu? 
875
                dwgObjects.add(dwgObject);
876
                handle_objects.put(new Integer(dwgObject.getHandle().getOffset()), dwgObject);
877
                /*
878
                 * TODO Quitar todos estos if-then y sustituirlos por un metodo callbackj
879
                 * 
880
                 * 
881
                 * (dwgObject.init(this), y que cada objeto haga lo que tenga que hacer
882
                 * */
883
                if(dwgObject instanceof DwgLayer){
884
                        this.addDwgLayer((DwgLayer) dwgObject);
885
                }
886
                if(dwgObject instanceof IDwgExtrusionable){
887
                        ((IDwgExtrusionable)dwgObject).applyExtrussion();
888
                }
889
                if(dwgObject instanceof IDwgPolyline){
890
                        dwgPolylines.add(dwgObject);
891
                }
892
                if(dwgObject instanceof IDwg3DTestable){
893
                        if(! dwg3DFile){//if its true, we dont check again
894
                                dwg3DFile = ((IDwg3DTestable)dwgObject).has3DData();
895
                        }
896
                }
897
                
898
                if(dwgObject instanceof DwgBlock){
899
                        DwgBlock block = (DwgBlock) dwgObject;
900
                        names_blocks.put(block.getName(), block);
901
                }
902
                
903
                
904
        }
905
        
906
        /**
907
         * Returns dwgObjects from its insertion order (position
908
         * in the dwg file)
909
         * 
910
         * @param index order in the dwg file
911
         * @return position
912
         * */
913
        public DwgObject getDwgObject(int index){
914
                return (DwgObject) dwgObjects.get(index);
915
        }
916
        
917
        public DwgObject getDwgObjectFromHandle(int handle){
918
                return (DwgObject) handle_objects.get(new Integer(handle));
919
        }
920
        
921
        /**
922
         * Add a DWG class to the dwgClasses vector
923
         * 
924
         * @param dwgClass DWG class
925
         */
926
        public void addDwgClass(DwgClass dwgClass){
927
                dwgClasses.add(dwgClass);
928
        }
929
        
930
        public void printClasses(){
931
                System.out.println("#### CLASSES ####");
932
                for(int i = 0; i < dwgClasses.size(); i++){
933
                        DwgClass clazz = (DwgClass) dwgClasses.get(i);
934
                        System.out.println(clazz.toString());
935
                }
936
                System.out.println("#############");
937
        }
938
        
939
        public List getDwgClasses(){
940
                return dwgClasses;
941
        }
942
        
943
    /**
944
     * @return Returns the dwgObjectOffsets.
945
     */
946
    public ArrayList getDwgObjectOffsets() {
947
        return dwgObjectOffsets;
948
    }
949
    /**
950
     * @return Returns the dwgObjects.
951
     */
952
    public LinkedList getDwgObjects() {
953
        return dwgObjects;
954
    }
955
    /**
956
     * @return Returns the fileName.
957
     */
958
    public String getFileName() {
959
        return fileName;
960
    }
961
    /**
962
     * @return Returns the dwg3DFile.
963
     */
964
    public boolean isDwg3DFile() {
965
        return dwg3DFile;
966
    }
967
    /**
968
     * @param dwg3DFile The dwg3DFile to set.
969
     */
970
    public void setDwg3DFile(boolean dwg3DFile) {
971
        this.dwg3DFile = dwg3DFile;
972
    }
973
}