Statistics
| Revision:

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

History | View | Annotate | Download (28.7 KB)

1 2896 jmorell
/* 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 9830 azabala
import java.util.ArrayList;
44 7116 azabala
import java.util.HashMap;
45 9992 fdiaz
import java.util.Iterator;
46 9825 azabala
import java.util.List;
47 9843 azabala
import java.util.Map;
48 10590 azabala
import java.util.Vector;
49 2896 jmorell
50 10590 azabala
import org.apache.log4j.Logger;
51
52 2896 jmorell
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 10590 azabala
import com.iver.cit.jdwglib.dwg.readers.DwgFileV12Reader;
56 10148 azabala
import com.iver.cit.jdwglib.dwg.readers.DwgFileV14Reader;
57 9602 azabala
import com.iver.cit.jdwglib.dwg.readers.DwgFileV15Reader;
58 10590 azabala
import com.iver.cit.jdwglib.dwg.readers.IDwgFileReader;
59 2896 jmorell
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 9602 azabala
 * @author azabala
69 2896 jmorell
 */
70
public class DwgFile {
71 10878 azabala
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 7116 azabala
        /**
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 10878 azabala
                acadVersions.put(DWG_ACAD12, "Autocad R12");
90 7116 azabala
                acadVersions.put("AC1010", "Autocad pre-R13 a");
91
                acadVersions.put("AC1011", "Autocad pre-R13 b");
92 10878 azabala
                acadVersions.put(DWG_ACAD13, "Autocad R13");
93
                acadVersions.put(DWG_ACAD_PRE_14, "Autocad pre-R14");
94
                acadVersions.put(DWG_ACAD14, "Autocad R14");
95 7116 azabala
                acadVersions.put("AC1500", "Autocad pre-2000");
96 10878 azabala
                acadVersions.put(DWG_ACAD2000, "Autocad R2000, R2000i, R2002");
97 7116 azabala
                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 10878 azabala
        }
102 7116 azabala
103 10878 azabala
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 7116 azabala
        }
115 10590 azabala
116 10878 azabala
        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 10590 azabala
        private static Logger logger = Logger.getLogger(DwgFile.class
140
                        .getName());
141 10878 azabala
142 10305 azabala
        /**
143
         * Path and name of the dwg file
144
         * */
145 2896 jmorell
        private String fileName;
146 10305 azabala
        /**
147
         * DWG version of the file (AC1013, AC1018, etc.)
148
         * */
149 2896 jmorell
        private String dwgVersion;
150 9602 azabala
151 9825 azabala
        /**
152
         * Offsets to the DWG sections
153
         */
154 7178 azabala
        private ArrayList dwgSectionOffsets;
155 9872 azabala
        /**
156
         * Header vars readed from the HEADER section of the DWG file
157
         * */
158
        private Map headerVars;
159 9602 azabala
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 7178 azabala
        private ArrayList dwgObjectOffsets;
166 9602 azabala
167
        /**
168
         * For each entry in dwgObjectOffsets, we have an instance of
169
         * DwgObject in the dwgObjects collection
170
         *
171
         * */
172 10386 azabala
        private List dwgObjects;
173 9840 azabala
        private HashMap handle_objects;
174 9602 azabala
175 9889 azabala
176 7178 azabala
        private ArrayList dwgClasses;
177 9602 azabala
178
179
        /**
180
         * hash map that indexes all DwgLayer objects
181
         * by its handle property
182
         * */
183
        private HashMap layerTable;
184
185 9825 azabala
        /**
186
         * Specific reader of the DWG file version (12, 13, 14, 2000, etc., each
187
         * version will have an specific reader)
188
         * */
189 9910 azabala
        private IDwgFileReader dwgReader;
190 2896 jmorell
        private boolean dwg3DFile;
191
        /**
192 9602 azabala
         * Memory mapped byte buffer of the whole DWG file
193
         * */
194
        private ByteBuffer bb;
195
196 9825 azabala
        /*
197
         * Optimizaciones para evitar leer el fichero completo en cada
198
         * pasada.
199
         * */
200 9602 azabala
        /**
201 9825 azabala
         * Contains all IDwgPolyline implementations
202
         * */
203
        private List dwgPolylines;
204 10305 azabala
        /**
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 9825 azabala
211 10590 azabala
        private List blockList;
212
213
214 9825 azabala
        /**
215 9843 azabala
         * Constructor.
216 2896 jmorell
         * @param fileName an absolute path to the DWG file
217
         */
218
        public DwgFile(String fileName) {
219
                this.fileName = fileName;
220 9602 azabala
221 7178 azabala
                dwgSectionOffsets = new ArrayList();
222
                dwgObjectOffsets = new ArrayList();
223 9872 azabala
                headerVars = new HashMap();
224 9719 azabala
225 9602 azabala
                dwgClasses = new ArrayList();
226 9719 azabala
227 10386 azabala
                dwgObjects = new ArrayList();
228 9840 azabala
                handle_objects = new HashMap();
229 9602 azabala
230
                layerTable = new HashMap();
231 9830 azabala
232
                dwgPolylines = new ArrayList();
233 10305 azabala
                insertList = new ArrayList();
234 10590 azabala
235
                blockList = new ArrayList();
236 2896 jmorell
        }
237
238 9305 jjdelcerro
        public String getDwgVersion() {
239
                return dwgVersion;
240
        }
241
242 10878 azabala
243 2896 jmorell
        /**
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 7116 azabala
        public void read() throws IOException,
250
                                DwgVersionNotSupportedException
251
        {
252 2896 jmorell
                setDwgVersion();
253 10878 azabala
254
                //main readers (not configurable)
255 7116 azabala
                if (dwgVersion.equalsIgnoreCase("Autocad R2000, R2000i, R2002")) {
256 2896 jmorell
                        dwgReader = new DwgFileV15Reader();
257 10221 azabala
                }else if (dwgVersion.equalsIgnoreCase("Autocad pre-R14")||
258
                                dwgVersion.equalsIgnoreCase("Autocad R14") ||
259
                                dwgVersion.equalsIgnoreCase("Autocad R13")) {
260 10148 azabala
                        dwgReader = new DwgFileV14Reader();
261 10590 azabala
                } 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 10878 azabala
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 2896 jmorell
                }
288 10878 azabala
289 10820 azabala
                try{
290 10878 azabala
                        dwgReader.read(this, bb);
291 10820 azabala
                }catch(Throwable t){
292
                        t.printStackTrace();
293
                        throw new IOException("Error leyendo dwg");
294
                }
295 2896 jmorell
        }
296 9602 azabala
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 9872 azabala
        public void setHeader(String key, Object value){
323
                headerVars.put(key, value);
324
        }
325 9602 azabala
326 10820 azabala
        public Object getHeader(String key){
327
                return headerVars.get(key);
328
        }
329
330 9719 azabala
        /*
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 10590 azabala
        protected void addDwgLayer(DwgLayer dwgLayer){
338 10014 fdiaz
                layerTable.put(new Integer(dwgLayer.getHandle().getOffset()),
339 9602 azabala
                                dwgLayer);
340
        }
341
342 10179 fdiaz
        private void printInfoOfAObject (DwgObject entity){
343 10590 azabala
                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 10179 fdiaz
                if(entity.hasLayerHandle()){
347 10590 azabala
                        logger.info("layerHandleCode = "+entity.getLayerHandle().getCode());
348
                        logger.info("layerHandle = "+entity.getLayerHandle().getOffset());
349 10179 fdiaz
                }
350
                if(entity.hasSubEntityHandle()){
351 10590 azabala
                        logger.info("subEntityHandleCode = "+entity.getSubEntityHandle().getCode());
352
                        logger.info("subEntityHandle = "+entity.getSubEntityHandle().getOffset());
353 10179 fdiaz
                }
354
                if(entity.hasNextHandle()){
355 10590 azabala
                        logger.info("nextHandleCode = "+entity.getNextHandle().getCode());
356
                        logger.info("nextHandle = "+entity.getNextHandle().getOffset());
357 10179 fdiaz
                }
358
                if(entity.hasPreviousHandle()){
359 10590 azabala
                        logger.info ("previousHandleCode = "+entity.getPreviousHandle().getCode());
360
                        logger.info ("previousHandle = "+entity.getPreviousHandle().getOffset());
361 10179 fdiaz
                }
362
                if(entity.hasXDicObjHandle()){
363 10590 azabala
                        logger.info ("xDicObjHandleCode = "+entity.getXDicObjHandle());
364
                        logger.info ("xDicObjHandle = "+entity.getXDicObjHandle());
365 10179 fdiaz
                }
366
                if(entity.hasReactorsHandles()){
367
                        ArrayList reactorsHandles = entity.getReactorsHandles();
368
                        int size = reactorsHandles.size();
369 10590 azabala
                        logger.info ("NUMERO DE reactors = "+size);
370 10179 fdiaz
                        DwgHandleReference hr;
371
                        for(int i=0; i<size; i++){
372
                                hr=(DwgHandleReference)reactorsHandles.get(i);
373 10590 azabala
                                logger.info ("reactorHandleCode = "+hr.getCode());
374
                                logger.info (" reactorHandle = "+hr.getOffset());
375 10179 fdiaz
                        }
376
                }
377
378
        }
379 9602 azabala
        public DwgLayer getDwgLayer(DwgObject entity){
380 10054 azabala
                DwgHandleReference handle = entity.getLayerHandle();
381
                if(handle == null){
382
                        return null;
383
                }
384 10179 fdiaz
                int        handleCode = handle.getCode();
385
                int        entityLayerHandle = entity.getLayerHandle().getOffset();
386 9719 azabala
                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 10179 fdiaz
                // FIXME: Esto no esta terminado. Falta considerar los codigo
410
                // 0x2, 0x3, 0x6, 0xA que no han aparecido en los archivos de prueba.
411 9992 fdiaz
                switch(handleCode){
412 10179 fdiaz
                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 10221 azabala
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
420
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
421 9992 fdiaz
                                }
422 10179 fdiaz
                        } else {
423
                                layerHandle = entity.getLayerHandle().getOffset();
424 9992 fdiaz
                        }
425
                        break;
426 10179 fdiaz
                case 0x5:
427
                        layerHandle = entity.getLayerHandle().getOffset();
428
                        break;
429 9992 fdiaz
                case 0x8:
430
                        if (entity.hasNextHandle()){
431 10014 fdiaz
                                int nextHandleCode = entity.getNextHandle().getCode();
432 9992 fdiaz
                                if (nextHandleCode == 0x5) {
433 10014 fdiaz
                                        layerHandle = entity.getNextHandle().getOffset();
434 9992 fdiaz
                                } else {
435
                                        //TODO No se han previsto nextHandleCode != 0x5
436 10221 azabala
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
437
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
438 9992 fdiaz
                                }
439 10179 fdiaz
                        } else {
440
                                layerHandle = entity.getHandle().getOffset() - 1;
441 9992 fdiaz
                        }
442
                        break;
443
                case 0xC:
444
                        if (entity.hasNextHandle()){
445 10014 fdiaz
                                int nextHandleCode = entity.getNextHandle().getCode();
446 9992 fdiaz
                                if (nextHandleCode == 0x5) {
447 10014 fdiaz
                                        layerHandle = entity.getNextHandle().getOffset();
448 9992 fdiaz
                                } else {
449 10179 fdiaz
                                        //TODO: No se han previsto nextHandleCode != 0x5
450 10221 azabala
//                                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+
451
//                                                        " con nextHandleCode "+ nextHandleCode +" no implementado.");
452 9992 fdiaz
                                }
453
                        } else {
454 10014 fdiaz
                                layerHandle = entity.getHandle().getOffset() - entity.getLayerHandle().getOffset() + 1;
455 9992 fdiaz
                        }
456
                        break;
457
                default:
458 10221 azabala
//                        System.out.println ("DwgFile.getDwgLayer: handleCode "+handleCode+" no implementado. entityLayerHandle="+entityLayerHandle);
459 9992 fdiaz
                }
460 9719 azabala
461 9992 fdiaz
                if(layerHandle != -1){
462
                        Iterator lyrIterator = layerTable.values().iterator();
463
                        while(lyrIterator.hasNext()){
464
                                DwgLayer lyr = (DwgLayer) lyrIterator.next();
465 10014 fdiaz
                                int lyrHdl = lyr.getHandle().getOffset();
466 9992 fdiaz
                                if (lyrHdl == layerHandle){
467
                                        return lyr;
468
                                }
469
                        }
470
                }
471 10221 azabala
//                System.out.println("NO SE HA ENCONTRADO UNA CAPA CON HANDLE " + layerHandle);
472
//                printInfoOfAObject(entity);
473 9992 fdiaz
                return null;
474 9602 azabala
        }
475
476 10310 fdiaz
        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 10590 azabala
                                logger.warn ("DwgObject.getDwgSuperEntity: handleCode "+handleCode+" no implementado. offset = "+offset);
503 10310 fdiaz
                        }
504
                        if(handle != -1){
505
                                object = getDwgObjectFromHandle(handle);
506
                                if(object != null)
507
                                        return object;
508
                        }
509
                }
510
                return null;
511
        }
512 9830 azabala
513 9719 azabala
        public String getLayerName(DwgObject entity) {
514 9602 azabala
                DwgLayer dwgLayer = getDwgLayer(entity);
515 10590 azabala
                if(dwgLayer == null){
516 9602 azabala
                        return "";
517 10179 fdiaz
                }else{
518 9602 azabala
                        return dwgLayer.getName();
519 10179 fdiaz
                }
520 9602 azabala
        }
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 2896 jmorell
        /**
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 9825 azabala
                /*
546 10632 azabala
                 * 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 9825 azabala
                 * */
556 10632 azabala
                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 2896 jmorell
                }
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 9843 azabala
        //TODO Refactorizar para que solo se aplique a las Polilineas
574 10305 azabala
575 10632 azabala
//        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 10590 azabala
        /*
647
         * TODO Revisar los bloques que son XREF
648
         * */
649 10240 azabala
        public void blockManagement2(){
650 10632 azabala
                Iterator it = null;
651 10305 azabala
652 10632 azabala
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 10861 azabala
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 10632 azabala
                                }
696
                        }//while
697
                }//if dwgfilev12
698
699 10305 azabala
                //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 10590 azabala
}
719
720
721 2896 jmorell
722 10305 azabala
        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 10590 azabala
                        logger.error("No hemos encontrado el BlockHeader cuyo handle es "+bHandle);
730 10305 azabala
                        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 10590 azabala
                        logger.error("handle incorrecto." + object.getClass().getName() + " no es un blockheader");
735 10305 azabala
                        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 10590 azabala
                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 10305 azabala
                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 10590 azabala
760 9977 azabala
        public int getIndexOf(DwgObject dwgObject){
761 10590 azabala
                return dwgObjects.indexOf(dwgObject);
762 9977 azabala
        }
763 9969 azabala
764
765 9977 azabala
766 2896 jmorell
    /**
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 9977 azabala
        private void manageBlockEntity(DwgObject entity,
780 9843 azabala
                                                                        double[] bPoint,
781
                                                                        Point2D insPoint,
782
                                                                        double[] scale,
783
                                                                        double rot,
784 10240 azabala
                                                                        List dwgObjectsWithoutBlocks,
785
                                                                        Map handleObjectsWithoutBlocks) {
786 9840 azabala
787 9843 azabala
                if(entity instanceof IDwgBlockMember){
788
                        IDwgBlockMember blockMember = (IDwgBlockMember)entity;
789 10240 azabala
                        blockMember.transform2Block(bPoint, insPoint, scale, rot,
790
                                        dwgObjectsWithoutBlocks,
791
                                        handleObjectsWithoutBlocks,this);
792 9840 azabala
                }
793 10820 azabala
794 2896 jmorell
        }
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 9825 azabala
                //TODO Ver si puedo inicializar las listas especificas
847
                //(IDwgPolyline, etc) aqu?
848 2896 jmorell
                dwgObjects.add(dwgObject);
849 10014 fdiaz
                handle_objects.put(new Integer(dwgObject.getHandle().getOffset()), dwgObject);
850 10305 azabala
851 9843 azabala
                /*
852 10590 azabala
                 * TODO Quitar todos estos if-then y sustituirlos por un metodo callback
853 9843 azabala
                 *
854
                 *
855
                 * (dwgObject.init(this), y que cada objeto haga lo que tenga que hacer
856
                 * */
857 9602 azabala
                if(dwgObject instanceof DwgLayer){
858
                        this.addDwgLayer((DwgLayer) dwgObject);
859
                }
860 10350 azabala
861
                //Probamos a no aplicar las extrusiones
862
863 9825 azabala
                if(dwgObject instanceof IDwgExtrusionable){
864
                        ((IDwgExtrusionable)dwgObject).applyExtrussion();
865 10590 azabala
866 9825 azabala
                }
867 10350 azabala
868 9825 azabala
                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 10305 azabala
                if(dwgObject instanceof DwgInsert){
877
                        insertList.add(dwgObject);
878 9843 azabala
                }
879 10590 azabala
880
                if(dwgObject instanceof DwgBlockHeader){
881
                        blockList.add(dwgObject);
882
                }
883 2896 jmorell
        }
884
885 9840 azabala
        /**
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 9719 azabala
        public DwgObject getDwgObject(int index){
893
                return (DwgObject) dwgObjects.get(index);
894
        }
895
896 9840 azabala
        public DwgObject getDwgObjectFromHandle(int handle){
897
                return (DwgObject) handle_objects.get(new Integer(handle));
898
        }
899
900 2896 jmorell
        /**
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 10221 azabala
        public void printClasses(){
910 10590 azabala
                logger.info("#### CLASSES ####");
911 10221 azabala
                for(int i = 0; i < dwgClasses.size(); i++){
912
                        DwgClass clazz = (DwgClass) dwgClasses.get(i);
913 10590 azabala
                        logger.info(clazz.toString());
914 10221 azabala
                }
915 10590 azabala
                logger.info("#############");
916 10221 azabala
        }
917
918 9889 azabala
        public List getDwgClasses(){
919
                return dwgClasses;
920
        }
921
922 2896 jmorell
    /**
923
     * @return Returns the dwgObjectOffsets.
924
     */
925 7178 azabala
    public ArrayList getDwgObjectOffsets() {
926 2896 jmorell
        return dwgObjectOffsets;
927
    }
928
    /**
929
     * @return Returns the dwgObjects.
930
     */
931 10386 azabala
    public List getDwgObjects() {
932 2896 jmorell
        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
}