1 /******************************************************************************
2 ** libDXFrw - Library to read/write DXF files (ascii & binary) **
3 ** **
4 ** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com **
5 ** **
6 ** This library is free software, licensed under the terms of the GNU **
7 ** General Public License as published by the Free Software Foundation, **
8 ** either version 2 of the License, or (at your option) any later version. **
9 ** You should have received a copy of the GNU General Public License **
10 ** along with this program. If not, see <http://www.gnu.org/licenses/>. **
11 ******************************************************************************/
12
13 // uncomment to get detailed debug output on DWG read. Caution: this option makes DWG import super-slow!
14 // #define DWGDEBUG 1
15
16 #include <cstdlib>
17 #include <iostream>
18 #include <fstream>
19 #include <string>
20 #include <sstream>
21
22 #include "dwgreader.h"
23 #include "drw_textcodec.h"
24 #include "drw_dbg.h"
25
~dwgReader()26 dwgReader::~dwgReader()
27 {
28 for ( std::map<duint32, DRW_LType *>::iterator it = ltypemap.begin(); it != ltypemap.end(); ++it )
29 delete ( it->second );
30 for ( std::map<duint32, DRW_Layer *>::iterator it = layermap.begin(); it != layermap.end(); ++it )
31 delete ( it->second );
32 for ( std::map<duint32, DRW_Block *>::iterator it = blockmap.begin(); it != blockmap.end(); ++it )
33 delete ( it->second );
34 for ( std::map<duint32, DRW_Textstyle *>::iterator it = stylemap.begin(); it != stylemap.end(); ++it )
35 delete ( it->second );
36 for ( std::map<duint32, DRW_Dimstyle *>::iterator it = dimstylemap.begin(); it != dimstylemap.end(); ++it )
37 delete ( it->second );
38 for ( std::map<duint32, DRW_Vport *>::iterator it = vportmap.begin(); it != vportmap.end(); ++it )
39 delete ( it->second );
40 for ( std::map<duint32, DRW_Class *>::iterator it = classesmap.begin(); it != classesmap.end(); ++it )
41 delete ( it->second );
42 for ( std::map<duint32, DRW_Block_Record *>::iterator it = blockRecordmap.begin(); it != blockRecordmap.end(); ++it )
43 delete ( it->second );
44 for ( std::map<duint32, DRW_AppId *>::iterator it = appIdmap.begin(); it != appIdmap.end(); ++it )
45 delete ( it->second );
46 }
47
parseAttribs(DRW_Entity * e)48 void dwgReader::parseAttribs( DRW_Entity *e )
49 {
50 if ( e )
51 {
52 duint32 ltref = e->lTypeH.ref;
53 duint32 lyref = e->layerH.ref;
54 std::map<duint32, DRW_LType *>::iterator lt_it = ltypemap.find( ltref );
55 if ( lt_it != ltypemap.end() )
56 {
57 e->lineType = ( lt_it->second )->name;
58 }
59 std::map<duint32, DRW_Layer *>::iterator ly_it = layermap.find( lyref );
60 if ( ly_it != layermap.end() )
61 {
62 e->layer = ( ly_it->second )->name;
63 }
64 }
65 }
66
findTableName(DRW::TTYPE table,dint32 handle)67 std::string dwgReader::findTableName( DRW::TTYPE table, dint32 handle )
68 {
69 std::string name;
70 switch ( table )
71 {
72 case DRW::STYLE:
73 {
74 std::map<duint32, DRW_Textstyle *>::iterator st_it = stylemap.find( handle );
75 if ( st_it != stylemap.end() )
76 name = ( st_it->second )->name;
77 break;
78 }
79 case DRW::DIMSTYLE:
80 {
81 std::map<duint32, DRW_Dimstyle *>::iterator ds_it = dimstylemap.find( handle );
82 if ( ds_it != dimstylemap.end() )
83 name = ( ds_it->second )->name;
84 break;
85 }
86 case DRW::BLOCK_RECORD: //use DRW_Block because name are more correct
87 {
88 // std::map<duint32, DRW_Block*>::iterator bk_it = blockmap.find(handle);
89 // if (bk_it != blockmap.end())
90 std::map<duint32, DRW_Block_Record *>::iterator bk_it = blockRecordmap.find( handle );
91 if ( bk_it != blockRecordmap.end() )
92 name = ( bk_it->second )->name;
93 break;
94 }
95 #if 0
96 case DRW::VPORT:
97 {
98 std::map<duint32, DRW_Vport *>::iterator vp_it = vportmap.find( handle );
99 if ( vp_it != vportmap.end() )
100 name = ( vp_it->second )->name;
101 break;
102 }
103 #endif
104 case DRW::LAYER:
105 {
106 std::map<duint32, DRW_Layer *>::iterator ly_it = layermap.find( handle );
107 if ( ly_it != layermap.end() )
108 name = ( ly_it->second )->name;
109 break;
110 }
111 case DRW::LTYPE:
112 {
113 std::map<duint32, DRW_LType *>::iterator lt_it = ltypemap.find( handle );
114 if ( lt_it != ltypemap.end() )
115 name = ( lt_it->second )->name;
116 break;
117 }
118 default:
119 break;
120 }
121 return name;
122 }
123
readDwgHeader(DRW_Header & hdr,dwgBuffer * buf,dwgBuffer * hBuf)124 bool dwgReader::readDwgHeader( DRW_Header &hdr, dwgBuffer *buf, dwgBuffer *hBuf )
125 {
126 bool ret = hdr.parseDwg( version, buf, hBuf, maintenanceVersion );
127 //RLZ: copy objectControl handles
128 return ret;
129 }
130
131 //RLZ: TODO add check instead print
checkSentinel(dwgBuffer * buf,enum secEnum::DWGSection,bool start)132 bool dwgReader::checkSentinel( dwgBuffer *buf, enum secEnum::DWGSection, bool start )
133 {
134 DRW_UNUSED( start );
135 for ( int i = 0; i < 16; i++ )
136 {
137 DRW_DBGH(buf->getRawChar8()); DRW_DBG(" ");
138 }
139 return true;
140 }
141
142 /*********** objects map ************************/
143
144 /**
145 * Note: object map are split in sections with max size 2035?
146 * each section are 2 bytes size + data bytes + 2 bytes crc
147 * size value are data bytes + 2 and to calculate crc are used
148 * 2 bytes size + data bytes
149 * last section are 2 bytes size + 2 bytes crc (size value always 2)
150 **/
readDwgHandles(dwgBuffer * dbuf,duint32 offset,duint32 size)151 bool dwgReader::readDwgHandles( dwgBuffer *dbuf, duint32 offset, duint32 size )
152 {
153 DRW_DBG("\ndwgReader::readDwgHandles\n");
154 if ( !dbuf->setPosition( offset ) )
155 return false;
156
157 duint32 maxPos = offset + size;
158 DRW_DBG("\nSection HANDLES offset= "); DRW_DBG(offset);
159 DRW_DBG("\nSection HANDLES size= "); DRW_DBG(size);
160 DRW_DBG("\nSection HANDLES maxPos= "); DRW_DBG(maxPos);
161
162 int startPos = offset;
163
164 while ( maxPos > dbuf->getPosition() )
165 {
166 DRW_DBG("\nstart handles section buf->curPosition()= "); DRW_DBG(dbuf->getPosition()); DRW_DBG("\n");
167 duint16 size = dbuf->getBERawShort16();
168 DRW_DBG("object map section size= "); DRW_DBG(size); DRW_DBG("\n");
169
170 dbuf->setPosition( startPos );
171
172 duint8 *tmpByteStr = new duint8[size];
173 dbuf->getBytes( tmpByteStr, size );
174 dwgBuffer buff( tmpByteStr, size, &decoder );
175 if ( size != 2 )
176 {
177 buff.setPosition( 2 );
178 int lastHandle = 0;
179 int lastLoc = 0;
180 //read data
181 while ( buff.getPosition() < size )
182 {
183 lastHandle += buff.getUModularChar();
184 DRW_DBG("object map lastHandle= "); DRW_DBGH(lastHandle);
185 lastLoc += buff.getModularChar();
186 DRW_DBG(" lastLoc= "); DRW_DBG(lastLoc); DRW_DBG("\n");
187 ObjectMap[lastHandle] = objHandle( 0, lastHandle, lastLoc );
188 }
189 }
190 //verify crc
191 duint16 crcCalc = buff.crc8( 0xc0c1, 0, size );
192 delete[]tmpByteStr;
193 duint16 crcRead = dbuf->getBERawShort16();
194 DRW_DBG("object map section crc8 read= "); DRW_DBG(crcRead);
195 DRW_DBG("\nobject map section crc8 calculated= "); DRW_DBG(crcCalc);
196 DRW_DBG("\nobject section buf->curPosition()= "); DRW_DBG(dbuf->getPosition()); DRW_DBG("\n");
197 startPos = dbuf->getPosition();
198 }
199
200 return dbuf->isGood();
201 }
202
203 /*********** objects ************************/
204
205 /**
206 * Reads all the object referenced in the object map section of the DWG file
207 * (using their object file offsets)
208 */
readDwgTables(DRW_Header & hdr,dwgBuffer * dbuf)209 bool dwgReader::readDwgTables( DRW_Header &hdr, dwgBuffer *dbuf )
210 {
211 DRW_DBG("\ndwgReader::readDwgTables start\n");
212 bool ret = true;
213 bool ret2 = true;
214 objHandle oc;
215 std::map<duint32, objHandle>::iterator mit;
216 dint16 oType;
217 duint32 bs = 0; //bit size of handle stream 2010+
218 duint8 *tmpByteStr = nullptr;
219
220 //parse linetypes, start with linetype Control
221 mit = ObjectMap.find( hdr.linetypeCtrl );
222 if ( mit == ObjectMap.end() )
223 {
224 DRW_DBG("\nWARNING: LineType control not found\n");
225 ret = false;
226 }
227 else
228 {
229 DRW_DBG("\n**********Parsing LineType control*******\n");
230 oc = mit->second;
231 ObjectMap.erase( mit );
232 DRW_ObjControl ltControl;
233 dbuf->setPosition( oc.loc );
234 int csize = dbuf->getModularShort();
235 if ( version > DRW::AC1021 ) //2010+
236 bs = dbuf->getUModularChar();
237 else
238 bs = 0;
239 tmpByteStr = new duint8[csize];
240 dbuf->getBytes( tmpByteStr, csize );
241 dwgBuffer cbuff( tmpByteStr, csize, &decoder );
242 //verify if object are correct
243 oType = cbuff.getObjType( version );
244 if ( oType != 0x38 )
245 {
246 DRW_DBG("\nWARNING: Not LineType control object, found oType ");
247 DRW_DBG(oType); DRW_DBG(" instead 0x38\n");
248 ret = false;
249 }
250 else //reset position
251 {
252 cbuff.resetPosition();
253 ret2 = ltControl.parseDwg( version, &cbuff, bs );
254 if ( ret )
255 ret = ret2;
256 }
257 delete[]tmpByteStr;
258 for ( std::list<duint32>::iterator it = ltControl.handlesList.begin(); it != ltControl.handlesList.end(); ++it )
259 {
260 mit = ObjectMap.find( *it );
261 if ( mit == ObjectMap.end() )
262 {
263 DRW_DBG("\nWARNING: LineType not found\n");
264 ret = false;
265 }
266 else
267 {
268 oc = mit->second;
269 ObjectMap.erase( mit );
270 DRW_DBG("\nLineType Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" loc.: "); DRW_DBG(oc.loc); DRW_DBG("\n");
271 DRW_LType *lt = new DRW_LType();
272 dbuf->setPosition( oc.loc );
273 int lsize = dbuf->getModularShort();
274 DRW_DBG("LineType size in bytes= "); DRW_DBG(lsize);
275 if ( version > DRW::AC1021 ) //2010+
276 bs = dbuf->getUModularChar();
277 else
278 bs = 0;
279 tmpByteStr = new duint8[lsize];
280 dbuf->getBytes( tmpByteStr, lsize );
281 dwgBuffer lbuff( tmpByteStr, lsize, &decoder );
282 ret2 = lt->parseDwg( version, &lbuff, bs );
283 ltypemap[lt->handle] = lt;
284 if ( ret )
285 ret = ret2;
286 delete[]tmpByteStr;
287 }
288 }
289 }
290
291 //parse layers, start with layer Control
292 mit = ObjectMap.find( hdr.layerCtrl );
293 if ( mit == ObjectMap.end() )
294 {
295 DRW_DBG("\nWARNING: Layer control not found\n");
296 ret = false;
297 }
298 else
299 {
300 DRW_DBG("\n**********Parsing Layer control*******\n");
301 oc = mit->second;
302 ObjectMap.erase( mit );
303 DRW_ObjControl layControl;
304 dbuf->setPosition( oc.loc );
305 int size = dbuf->getModularShort();
306 if ( version > DRW::AC1021 ) //2010+
307 bs = dbuf->getUModularChar();
308 else
309 bs = 0;
310 tmpByteStr = new duint8[size];
311 dbuf->getBytes( tmpByteStr, size );
312 dwgBuffer buff( tmpByteStr, size, &decoder );
313 //verify if object are correct
314 oType = buff.getObjType( version );
315 if ( oType != 0x32 )
316 {
317 DRW_DBG("\nWARNING: Not Layer control object, found oType ");
318 DRW_DBG(oType); DRW_DBG(" instead 0x32\n");
319 ret = false;
320 }
321 else //reset position
322 {
323 buff.resetPosition();
324 ret2 = layControl.parseDwg( version, &buff, bs );
325 if ( ret )
326 ret = ret2;
327 }
328 delete[]tmpByteStr;
329 for ( std::list<duint32>::iterator it = layControl.handlesList.begin(); it != layControl.handlesList.end(); ++it )
330 {
331 mit = ObjectMap.find( *it );
332 if ( mit == ObjectMap.end() )
333 {
334 DRW_DBG("\nWARNING: Layer not found\n");
335 ret = false;
336 }
337 else
338 {
339 oc = mit->second;
340 ObjectMap.erase( mit );
341 DRW_DBG("Layer Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
342 DRW_Layer *la = new DRW_Layer();
343 dbuf->setPosition( oc.loc );
344 int size = dbuf->getModularShort();
345 if ( version > DRW::AC1021 ) //2010+
346 bs = dbuf->getUModularChar();
347 else
348 bs = 0;
349 tmpByteStr = new duint8[size];
350 dbuf->getBytes( tmpByteStr, size );
351 dwgBuffer buff( tmpByteStr, size, &decoder );
352 ret2 = la->parseDwg( version, &buff, bs );
353 layermap[la->handle] = la;
354 if ( ret )
355 ret = ret2;
356 delete[]tmpByteStr;
357 }
358 }
359 }
360
361 //set linetype in layer
362 for ( std::map<duint32, DRW_Layer *>::iterator it = layermap.begin(); it != layermap.end(); ++it )
363 {
364 DRW_Layer *ly = it->second;
365 duint32 ref = ly->lTypeH.ref;
366 std::map<duint32, DRW_LType *>::iterator lt_it = ltypemap.find( ref );
367 if ( lt_it != ltypemap.end() )
368 {
369 ly->lineType = ( lt_it->second )->name;
370 }
371 }
372
373 //parse text styles, start with style Control
374 mit = ObjectMap.find( hdr.styleCtrl );
375 if ( mit == ObjectMap.end() )
376 {
377 DRW_DBG("\nWARNING: Style control not found\n");
378 ret = false;
379 }
380 else
381 {
382 DRW_DBG("\n**********Parsing Style control*******\n");
383 oc = mit->second;
384 ObjectMap.erase( mit );
385 DRW_ObjControl styControl;
386 dbuf->setPosition( oc.loc );
387 int size = dbuf->getModularShort();
388 if ( version > DRW::AC1021 ) //2010+
389 bs = dbuf->getUModularChar();
390 else
391 bs = 0;
392 tmpByteStr = new duint8[size];
393 dbuf->getBytes( tmpByteStr, size );
394 dwgBuffer buff( tmpByteStr, size, &decoder );
395 //verify if object are correct
396 oType = buff.getObjType( version );
397 if ( oType != 0x34 )
398 {
399 DRW_DBG("\nWARNING: Not Text Style control object, found oType ");
400 DRW_DBG(oType); DRW_DBG(" instead 0x34\n");
401 ret = false;
402 }
403 else //reset position
404 {
405 buff.resetPosition();
406 ret2 = styControl.parseDwg( version, &buff, bs );
407 if ( ret )
408 ret = ret2;
409 }
410 delete[]tmpByteStr;
411 for ( std::list<duint32>::iterator it = styControl.handlesList.begin(); it != styControl.handlesList.end(); ++it )
412 {
413 mit = ObjectMap.find( *it );
414 if ( mit == ObjectMap.end() )
415 {
416 DRW_DBG("\nWARNING: Style not found\n");
417 ret = false;
418 }
419 else
420 {
421 oc = mit->second;
422 ObjectMap.erase( mit );
423 DRW_DBG("Style Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
424 DRW_Textstyle *sty = new DRW_Textstyle();
425 dbuf->setPosition( oc.loc );
426 int size = dbuf->getModularShort();
427 if ( version > DRW::AC1021 ) //2010+
428 bs = dbuf->getUModularChar();
429 else
430 bs = 0;
431 tmpByteStr = new duint8[size];
432 dbuf->getBytes( tmpByteStr, size );
433 dwgBuffer buff( tmpByteStr, size, &decoder );
434 ret2 = sty->parseDwg( version, &buff, bs );
435 stylemap[sty->handle] = sty;
436 if ( ret )
437 ret = ret2;
438 delete[]tmpByteStr;
439 }
440 }
441 }
442
443 //parse dim styles, start with dimstyle Control
444 mit = ObjectMap.find( hdr.dimstyleCtrl );
445 if ( mit == ObjectMap.end() )
446 {
447 DRW_DBG("\nWARNING: Dimension Style control not found\n");
448 ret = false;
449 }
450 else
451 {
452 DRW_DBG("\n**********Parsing Dimension Style control*******\n");
453 oc = mit->second;
454 ObjectMap.erase( mit );
455 DRW_ObjControl dimstyControl;
456 dbuf->setPosition( oc.loc );
457 duint32 size = dbuf->getModularShort();
458 if ( version > DRW::AC1021 ) //2010+
459 bs = dbuf->getUModularChar();
460 else
461 bs = 0;
462 tmpByteStr = new duint8[size];
463 dbuf->getBytes( tmpByteStr, size );
464 dwgBuffer buff( tmpByteStr, size, &decoder );
465 //verify if object are correct
466 oType = buff.getObjType( version );
467 if ( oType != 0x44 )
468 {
469 DRW_DBG("\nWARNING: Not Dim Style control object, found oType ");
470 DRW_DBG(oType); DRW_DBG(" instead 0x44\n");
471 ret = false;
472 }
473 else //reset position
474 {
475 buff.resetPosition();
476 ret2 = dimstyControl.parseDwg( version, &buff, bs );
477 if ( ret )
478 ret = ret2;
479 }
480 delete[]tmpByteStr;
481 for ( std::list<duint32>::iterator it = dimstyControl.handlesList.begin(); it != dimstyControl.handlesList.end(); ++it )
482 {
483 mit = ObjectMap.find( *it );
484 if ( mit == ObjectMap.end() )
485 {
486 DRW_DBG("\nWARNING: Dimension Style not found\n");
487 ret = false;
488 }
489 else
490 {
491 oc = mit->second;
492 ObjectMap.erase( mit );
493 DRW_DBG("Dimstyle Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
494
495 DRW_Dimstyle *sty = new DRW_Dimstyle();
496 dbuf->setPosition( oc.loc );
497 int size = dbuf->getModularShort();
498 if ( version > DRW::AC1021 ) //2010+
499 bs = dbuf->getUModularChar();
500 else
501 bs = 0;
502 tmpByteStr = new duint8[size];
503 dbuf->getBytes( tmpByteStr, size );
504 dwgBuffer buff( tmpByteStr, size, &decoder );
505 ret2 = sty->parseDwg( version, &buff, bs );
506 dimstylemap[sty->handle] = sty;
507 if ( ret )
508 ret = ret2;
509 delete[]tmpByteStr;
510 }
511 }
512 }
513
514 //parse vports, start with vports Control
515 mit = ObjectMap.find( hdr.vportCtrl );
516 if ( mit == ObjectMap.end() )
517 {
518 DRW_DBG("\nWARNING: vports control not found\n");
519 ret = false;
520 }
521 else
522 {
523 DRW_DBG("\n**********Parsing vports control*******\n");
524 oc = mit->second;
525 ObjectMap.erase( mit );
526 DRW_ObjControl vportControl;
527 dbuf->setPosition( oc.loc );
528 int size = dbuf->getModularShort();
529 if ( version > DRW::AC1021 ) //2010+
530 bs = dbuf->getUModularChar();
531 else
532 bs = 0;
533 tmpByteStr = new duint8[size];
534 dbuf->getBytes( tmpByteStr, size );
535 dwgBuffer buff( tmpByteStr, size, &decoder );
536 //verify if object are correct
537 oType = buff.getObjType( version );
538 if ( oType != 0x40 )
539 {
540 DRW_DBG("\nWARNING: Not VPorts control object, found oType: ");
541 DRW_DBG(oType); DRW_DBG(" instead 0x40\n");
542 ret = false;
543 }
544 else //reset position
545 {
546 buff.resetPosition();
547 ret2 = vportControl.parseDwg( version, &buff, bs );
548 if ( ret )
549 ret = ret2;
550 }
551 delete[]tmpByteStr;
552 for ( std::list<duint32>::iterator it = vportControl.handlesList.begin(); it != vportControl.handlesList.end(); ++it )
553 {
554 mit = ObjectMap.find( *it );
555 if ( mit == ObjectMap.end() )
556 {
557 DRW_DBG("\nWARNING: vport not found\n");
558 ret = false;
559 }
560 else
561 {
562 oc = mit->second;
563 ObjectMap.erase( mit );
564 DRW_DBG("Vport Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
565 DRW_Vport *vp = new DRW_Vport();
566 dbuf->setPosition( oc.loc );
567 int size = dbuf->getModularShort();
568 if ( version > DRW::AC1021 ) //2010+
569 bs = dbuf->getUModularChar();
570 else
571 bs = 0;
572 tmpByteStr = new duint8[size];
573 dbuf->getBytes( tmpByteStr, size );
574 dwgBuffer buff( tmpByteStr, size, &decoder );
575 ret2 = vp->parseDwg( version, &buff, bs );
576 vportmap[vp->handle] = vp;
577 if ( ret )
578 ret = ret2;
579 delete[]tmpByteStr;
580 }
581 }
582 }
583
584 //parse Block_records , start with Block_record Control
585 mit = ObjectMap.find( hdr.blockCtrl );
586 if ( mit == ObjectMap.end() )
587 {
588 DRW_DBG("\nWARNING: Block_record control not found\n");
589 ret = false;
590 }
591 else
592 {
593 DRW_DBG("\n**********Parsing Block_record control*******\n");
594 oc = mit->second;
595 ObjectMap.erase( mit );
596 DRW_ObjControl blockControl;
597 dbuf->setPosition( oc.loc );
598 int csize = dbuf->getModularShort();
599 if ( version > DRW::AC1021 ) //2010+
600 bs = dbuf->getUModularChar();
601 else
602 bs = 0;
603 tmpByteStr = new duint8[csize];
604 dbuf->getBytes( tmpByteStr, csize );
605 dwgBuffer buff( tmpByteStr, csize, &decoder );
606 //verify if object are correct
607 oType = buff.getObjType( version );
608 if ( oType != 0x30 )
609 {
610 DRW_DBG("\nWARNING: Not Block Record control object, found oType ");
611 DRW_DBG(oType); DRW_DBG(" instead 0x30\n");
612 ret = false;
613 }
614 else //reset position
615 {
616 buff.resetPosition();
617 ret2 = blockControl.parseDwg( version, &buff, bs );
618 if ( ret )
619 ret = ret2;
620 }
621 delete[]tmpByteStr;
622 for ( std::list<duint32>::iterator it = blockControl.handlesList.begin(); it != blockControl.handlesList.end(); ++it )
623 {
624 mit = ObjectMap.find( *it );
625 if ( mit == ObjectMap.end() )
626 {
627 DRW_DBG("\nWARNING: block record not found\n");
628 ret = false;
629 }
630 else
631 {
632 oc = mit->second;
633 ObjectMap.erase( mit );
634 DRW_DBG("block record Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
635 DRW_Block_Record *br = new DRW_Block_Record();
636 dbuf->setPosition( oc.loc );
637 int size = dbuf->getModularShort();
638 if ( version > DRW::AC1021 ) //2010+
639 bs = dbuf->getUModularChar();
640 else
641 bs = 0;
642 tmpByteStr = new duint8[size];
643 dbuf->getBytes( tmpByteStr, size );
644 dwgBuffer buff( tmpByteStr, size, &decoder );
645 ret2 = br->parseDwg( version, &buff, bs );
646 blockRecordmap[br->handle] = br;
647 if ( ret )
648 ret = ret2;
649 delete[]tmpByteStr;
650 }
651 }
652 }
653
654 //parse appId , start with appId Control
655 mit = ObjectMap.find( hdr.appidCtrl );
656 if ( mit == ObjectMap.end() )
657 {
658 DRW_DBG("\nWARNING: AppId control not found\n");
659 ret = false;
660 }
661 else
662 {
663 DRW_DBG("\n**********Parsing AppId control*******\n");
664 oc = mit->second;
665 ObjectMap.erase( mit );
666 DRW_DBG("AppId Control Obj Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
667
668 DRW_ObjControl appIdControl;
669 dbuf->setPosition( oc.loc );
670 int size = dbuf->getModularShort();
671 if ( version > DRW::AC1021 ) //2010+
672 bs = dbuf->getUModularChar();
673 else
674 bs = 0;
675 tmpByteStr = new duint8[size];
676 dbuf->getBytes( tmpByteStr, size );
677 dwgBuffer buff( tmpByteStr, size, &decoder );
678 //verify if object are correct
679 oType = buff.getObjType( version );
680 if ( oType != 0x42 )
681 {
682 DRW_DBG("\nWARNING: Not AppId control object, found oType ");
683 DRW_DBG(oType); DRW_DBG(" instead 0x42\n");
684 ret = false;
685 }
686 else //reset position
687 {
688 buff.resetPosition();
689 ret2 = appIdControl.parseDwg( version, &buff, bs );
690 if ( ret )
691 ret = ret2;
692 }
693 delete[]tmpByteStr;
694 for ( std::list<duint32>::iterator it = appIdControl.handlesList.begin(); it != appIdControl.handlesList.end(); ++it )
695 {
696 mit = ObjectMap.find( *it );
697 if ( mit == ObjectMap.end() )
698 {
699 DRW_DBG("\nWARNING: AppId not found\n");
700 ret = false;
701 }
702 else
703 {
704 oc = mit->second;
705 ObjectMap.erase( mit );
706 DRW_DBG("AppId Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
707 DRW_AppId *ai = new DRW_AppId();
708 dbuf->setPosition( oc.loc );
709 int size = dbuf->getModularShort();
710 if ( version > DRW::AC1021 ) //2010+
711 bs = dbuf->getUModularChar();
712 else
713 bs = 0;
714 tmpByteStr = new duint8[size];
715 dbuf->getBytes( tmpByteStr, size );
716 dwgBuffer buff( tmpByteStr, size, &decoder );
717 ret2 = ai->parseDwg( version, &buff, bs );
718 appIdmap[ai->handle] = ai;
719 if ( ret )
720 ret = ret2;
721 delete[]tmpByteStr;
722 }
723 }
724 }
725
726 #if 0
727 //RLZ: parse remaining object controls, TODO: implement all
728 mit = ObjectMap.find( hdr.viewCtrl );
729 if ( mit == ObjectMap.end() )
730 {
731 QgsDebugMsg( "WARNING: View control not found" );
732 ret = false;
733 }
734 else
735 {
736 QgsDebugMsg( "**********Parsing View control*******" );
737 oc = mit->second;
738 ObjectMap.erase( mit );
739 QgsDebugMsg( QString( "View Control Obj Handle=0x%1 loc=%2" ).arg( oc.handle, 0, 16 ).arg( oc.loc ) );
740
741 DRW_ObjControl viewControl;
742 dbuf->setPosition( oc.loc );
743 int size = dbuf->getModularShort();
744 if ( version > DRW::AC1021 ) //2010+
745 bs = dbuf->getUModularChar();
746 else
747 bs = 0;
748 tmpByteStr = new duint8[size];
749 dbuf->getBytes( tmpByteStr, size );
750 dwgBuffer buff( tmpByteStr, size, &decoder );
751 //verify if object are correct
752 oType = buff.getObjType( version );
753 if ( oType != 0x3C )
754 {
755 QgsDebugMsg( QString( "WARNING: Not View control object, found oType 0x%1 instead of 0x3c" ).arg( oType, 0, 16 ) );
756 ret = false;
757 }
758 else //reset position
759 {
760 buff.resetPosition();
761 ret2 = viewControl.parseDwg( version, &buff, bs );
762 if ( ret )
763 ret = ret2;
764 }
765 delete[]tmpByteStr;
766 }
767
768 mit = ObjectMap.find( hdr.ucsCtrl );
769 if ( mit == ObjectMap.end() )
770 {
771 QgsDebugMsg( "WARNING: Ucs control not found" );
772 ret = false;
773 }
774 else
775 {
776 oc = mit->second;
777 ObjectMap.erase( mit );
778 QgsDebugMsg( "**********Parsing Ucs control*******" );
779 QgsDebugMsg( QString( "Ucs Control Obj Handle=0x%1 loc=%2" ).arg( oc.handle, 0, 16 ).arg( oc.loc ) );
780
781 DRW_ObjControl ucsControl;
782 dbuf->setPosition( oc.loc );
783 int size = dbuf->getModularShort();
784 if ( version > DRW::AC1021 ) //2010+
785 bs = dbuf->getUModularChar();
786 else
787 bs = 0;
788 tmpByteStr = new duint8[size];
789 dbuf->getBytes( tmpByteStr, size );
790 dwgBuffer buff( tmpByteStr, size, &decoder );
791 //verify if object are correct
792 oType = buff.getObjType( version );
793 if ( oType != 0x3E )
794 {
795 QgsDebugMsg( QString( "WARNING: Not Ucs control object, found oType 0x%1 instead of 0x3e" ).arg( oType, 0, 16 ) );
796 ret = false;
797 }
798 else //reset position
799 {
800 buff.resetPosition();
801 ret2 = ucsControl.parseDwg( version, &buff, bs );
802 if ( ret )
803 ret = ret2;
804 }
805 delete[]tmpByteStr;
806 }
807
808 if ( version < DRW::AC1018 ) //r2000-
809 {
810 mit = ObjectMap.find( hdr.vpEntHeaderCtrl );
811 if ( mit == ObjectMap.end() )
812 {
813 QgsDebugMsg( "WARNING: vpEntHeader control not found" );
814 ret = false;
815 }
816 else
817 {
818 QgsDebugMsg( "**********Parsing vpEntHeader control*******" );
819 oc = mit->second;
820 ObjectMap.erase( mit );
821 QgsDebugMsg( QString( "vpEntHeader Control Obj Handle=0x%1 loc=%2" ).arg( oc.handle, 0, 16 ).arg( oc.loc ) );
822
823 DRW_ObjControl vpEntHeaderCtrl;
824 dbuf->setPosition( oc.loc );
825 int size = dbuf->getModularShort();
826 if ( version > DRW::AC1021 ) //2010+
827 bs = dbuf->getUModularChar();
828 else
829 bs = 0;
830 tmpByteStr = new duint8[size];
831 dbuf->getBytes( tmpByteStr, size );
832 dwgBuffer buff( tmpByteStr, size, &decoder );
833 //verify if object are correct
834 oType = buff.getObjType( version );
835 if ( oType != 0x46 )
836 {
837 QgsDebugMsg( QString( "WARNING: Not vpEntHeader control object, found oType 0x%1 instead of 0x46" ).arg( oType, 0, 16 ) );
838 ret = false;
839 }
840 else //reset position
841 {
842 buff.resetPosition();
843 #if 0
844 /* RLZ: writeme */
845 ret2 = vpEntHeader.parseDwg( version, &buff, bs );
846 if ( ret )
847 ret = ret2;
848 #endif // 0
849 }
850 delete[]tmpByteStr;
851 }
852 }
853 #endif // 0
854
855 return ret;
856 }
857
readDwgBlocks(DRW_Interface & intfa,dwgBuffer * dbuf)858 bool dwgReader::readDwgBlocks( DRW_Interface &intfa, dwgBuffer *dbuf )
859 {
860 bool ret = true;
861 bool ret2 = true;
862 duint32 bs = 0;
863 duint8 *tmpByteStr = nullptr;
864 std::map<duint32, objHandle>::iterator mit;
865 DRW_DBG("\nobject map total size= "); DRW_DBG(ObjectMap.size());
866
867 for ( std::map<duint32, DRW_Block_Record *>::iterator it = blockRecordmap.begin(); it != blockRecordmap.end(); ++it )
868 {
869 DRW_Block_Record *bkr = it->second;
870 DRW_DBG("\nParsing Block, record handle= "); DRW_DBGH(it->first); DRW_DBG(" Name= "); DRW_DBG(bkr->name); DRW_DBG("\n");
871 DRW_DBG("\nFinding Block, handle= "); DRW_DBGH(bkr->block); DRW_DBG("\n");
872 mit = ObjectMap.find( bkr->block );
873 if ( mit == ObjectMap.end() )
874 {
875 DRW_DBG("\nWARNING: block entity not found\n");
876 ret = false;
877 continue;
878 }
879 objHandle oc = mit->second;
880 ObjectMap.erase( mit );
881 DRW_DBG("Block Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" Location: "); DRW_DBG(oc.loc); DRW_DBG("\n");
882 if ( !( dbuf->setPosition( oc.loc ) ) )
883 {
884 DRW_DBG("Bad Location reading blocks\n");
885 ret = false;
886 continue;
887 }
888 int size = dbuf->getModularShort();
889 if ( version > DRW::AC1021 ) //2010+
890 bs = dbuf->getUModularChar();
891 else
892 bs = 0;
893 tmpByteStr = new duint8[size];
894 dbuf->getBytes( tmpByteStr, size );
895 dwgBuffer buff( tmpByteStr, size, &decoder );
896 DRW_Block bk;
897 ret2 = bk.parseDwg( version, &buff, bs );
898 if ( !ret2 )
899 {
900 DRW_DBG( "parseDwg failed\n" );
901 }
902 delete[]tmpByteStr;
903 ret = ret && ret2;
904 parseAttribs( &bk );
905 //complete block entity with block record data
906 bk.basePoint = bkr->basePoint;
907 bk.flags = bkr->flags;
908 intfa.addBlock( bk );
909 //and update block record name
910 bkr->name = bk.name;
911
912 //! Read & send block entities
913 // in dwg code 330 are not set like dxf in ModelSpace & PaperSpace, set it (RLZ: only tested in 2000)
914 if ( bk.parentHandle == DRW::NoHandle )
915 {
916 // in dwg code 330 are not set like dxf in ModelSpace & PaperSpace, set it
917 bk.parentHandle = bkr->handle;
918 //and do not send block entities like dxf
919 }
920 else
921 {
922 if ( version < DRW::AC1018 ) //pre 2004
923 {
924 duint32 nextH = bkr->firstEH;
925 while ( nextH != 0 )
926 {
927 mit = ObjectMap.find( nextH );
928 if ( mit == ObjectMap.end() )
929 {
930 nextH = bkr->lastEH;//end while if entity not foud
931 DRW_DBG("\nWARNING: Entity of block not found\n");
932 ret = false;
933 continue;
934 }
935 else //foud entity reads it
936 {
937 oc = mit->second;
938 ObjectMap.erase( mit );
939 ret2 = readDwgEntity( dbuf, oc, intfa );
940 if ( !ret2 )
941 {
942 DRW_DBG( "readDwgEntity failed\n" );
943 }
944 ret = ret && ret2;
945 }
946 if ( nextH == bkr->lastEH )
947 nextH = 0; //redundant, but prevent read errors
948 else
949 nextH = nextEntLink;
950 }
951 }
952 else //2004+
953 {
954 for ( std::vector<duint32>::iterator it = bkr->entMap.begin() ; it != bkr->entMap.end(); ++it )
955 {
956 duint32 nextH = *it;
957 mit = ObjectMap.find( nextH );
958 if ( mit == ObjectMap.end() )
959 {
960 DRW_DBG("\nWARNING: Entity of block not found\n");
961 ret = false;
962 continue;
963 }
964 else //found entity, read it
965 {
966 oc = mit->second;
967 ObjectMap.erase( mit );
968 DRW_DBG("\nBlocks, parsing entity: "); DRW_DBGH(oc.handle); DRW_DBG(", pos: "); DRW_DBG(oc.loc); DRW_DBG("\n");
969 ret2 = readDwgEntity( dbuf, oc, intfa );
970 if ( !ret2 )
971 {
972 DRW_DBG( "readDwgEntity failed\n" );
973 }
974 ret = ret && ret2;
975 }
976 }
977 }//end 2004+
978 }
979
980 //end block entity, really needed to parse a dummy entity??
981 mit = ObjectMap.find( bkr->endBlock );
982 if ( mit == ObjectMap.end() )
983 {
984 DRW_DBG("\nWARNING: end block entity not found\n");
985 ret = false;
986 continue;
987 }
988 oc = mit->second;
989 ObjectMap.erase( mit );
990 DRW_DBG("End block Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" Location: "); DRW_DBG(oc.loc); DRW_DBG("\n");
991
992 dbuf->setPosition( oc.loc );
993 size = dbuf->getModularShort();
994 if ( version > DRW::AC1021 ) //2010+
995 bs = dbuf->getUModularChar();
996 else
997 bs = 0;
998 tmpByteStr = new duint8[size];
999 dbuf->getBytes( tmpByteStr, size );
1000 dwgBuffer buff1( tmpByteStr, size, &decoder );
1001 DRW_Block end;
1002 end.isEnd = true;
1003 ret2 = end.parseDwg( version, &buff1, bs );
1004 if ( !ret2 )
1005 {
1006 DRW_DBG( "parseDwg failed\n" );
1007 }
1008 delete[]tmpByteStr;
1009 ret = ret && ret2;
1010 if ( bk.parentHandle == DRW::NoHandle ) bk.parentHandle = bkr->handle;
1011 parseAttribs( &end );
1012 intfa.endBlock();
1013 }
1014
1015 return ret;
1016 }
1017
readPlineVertex(DRW_Polyline & pline,dwgBuffer * dbuf)1018 bool dwgReader::readPlineVertex( DRW_Polyline &pline, dwgBuffer *dbuf )
1019 {
1020 bool ret = true;
1021 bool ret2 = true;
1022 objHandle oc;
1023 duint32 bs = 0;
1024 std::map<duint32, objHandle>::iterator mit;
1025
1026 if ( version < DRW::AC1018 ) //pre 2004
1027 {
1028 duint32 nextH = pline.firstEH;
1029 while ( nextH != 0 )
1030 {
1031 mit = ObjectMap.find( nextH );
1032 if ( mit == ObjectMap.end() )
1033 {
1034 nextH = pline.lastEH;//end while if entity not foud
1035 DRW_DBG("\nWARNING: pline vertex not found\n");
1036 ret = false;
1037 continue;
1038 }
1039 else //foud entity reads it
1040 {
1041 oc = mit->second;
1042 ObjectMap.erase( mit );
1043 DRW_Vertex vt;
1044 dbuf->setPosition( oc.loc );
1045 //RLZ: verify if pos is ok
1046 int size = dbuf->getModularShort();
1047 if ( version > DRW::AC1021 ) //2010+
1048 {
1049 bs = dbuf->getUModularChar();
1050 }
1051 duint8 *tmpByteStr = new duint8[size];
1052 dbuf->getBytes( tmpByteStr, size );
1053 dwgBuffer buff( tmpByteStr, size, &decoder );
1054 dint16 oType = buff.getObjType( version );
1055 buff.resetPosition();
1056 DRW_DBG(" object type= "); DRW_DBG(oType); DRW_DBG("\n");
1057 ret2 = vt.parseDwg( version, &buff, bs, pline.basePoint.z );
1058 delete[]tmpByteStr;
1059 pline.addVertex( vt );
1060 nextEntLink = vt.nextEntLink;
1061 \
1062 prevEntLink = vt.prevEntLink;
1063 ret = ret && ret2;
1064 }
1065 if ( nextH == pline.lastEH )
1066 nextH = 0; //redundant, but prevent read errors
1067 else
1068 nextH = nextEntLink;
1069 }
1070 }
1071 else //2004+
1072 {
1073 for ( std::list<duint32>::iterator it = pline.handlesList.begin() ; it != pline.handlesList.end(); ++it )
1074 {
1075 duint32 nextH = *it;
1076 mit = ObjectMap.find( nextH );
1077 if ( mit == ObjectMap.end() )
1078 {
1079 DRW_DBG("\nWARNING: Entity of block not found\n");
1080 ret = false;
1081 continue;
1082 }
1083 else //foud entity reads it
1084 {
1085 oc = mit->second;
1086 ObjectMap.erase( mit );
1087 DRW_DBG("\nPline vertex, parsing entity: "); DRW_DBGH(oc.handle); DRW_DBG(", pos: "); DRW_DBG(oc.loc); DRW_DBG("\n");
1088 DRW_Vertex vt;
1089 dbuf->setPosition( oc.loc );
1090 //RLZ: verify if pos is ok
1091 int size = dbuf->getModularShort();
1092 if ( version > DRW::AC1021 ) //2010+
1093 {
1094 bs = dbuf->getUModularChar();
1095 }
1096 duint8 *tmpByteStr = new duint8[size];
1097 dbuf->getBytes( tmpByteStr, size );
1098 dwgBuffer buff( tmpByteStr, size, &decoder );
1099 dint16 oType = buff.getObjType( version );
1100 buff.resetPosition();
1101 DRW_DBG(" object type= "); DRW_DBG(oType); DRW_DBG("\n");
1102 ret2 = vt.parseDwg( version, &buff, bs, pline.basePoint.z );
1103 delete[]tmpByteStr;
1104 pline.addVertex( vt );
1105 nextEntLink = vt.nextEntLink;
1106 \
1107 prevEntLink = vt.prevEntLink;
1108 ret = ret && ret2;
1109 }
1110 }
1111 }//end 2004+
1112 DRW_DBG("\nRemoved SEQEND entity: "); DRW_DBGH(pline.seqEndH.ref);DRW_DBG("\n");
1113 ObjectMap.erase( pline.seqEndH.ref );
1114
1115 return ret;
1116 }
1117
readDwgEntities(DRW_Interface & intfa,dwgBuffer * dbuf)1118 bool dwgReader::readDwgEntities( DRW_Interface &intfa, dwgBuffer *dbuf )
1119 {
1120 bool ret = true;
1121 bool ret2 = true;
1122
1123 DRW_DBG("\nobject map total size= "); DRW_DBG(ObjectMap.size());
1124 std::map<duint32, objHandle>::iterator itB = ObjectMap.begin();
1125 std::map<duint32, objHandle>::iterator itE = ObjectMap.end();
1126 while ( itB != itE )
1127 {
1128 ret2 = readDwgEntity( dbuf, itB->second, intfa );
1129 ObjectMap.erase( itB );
1130 itB = ObjectMap.begin();
1131 if ( ret )
1132 ret = ret2;
1133 }
1134 return ret;
1135 }
1136
1137 /**
1138 * Reads a dwg drawing entity (dwg object entity) given its offset in the file
1139 */
readDwgEntity(dwgBuffer * dbuf,objHandle & obj,DRW_Interface & intfa)1140 bool dwgReader::readDwgEntity( dwgBuffer *dbuf, objHandle &obj, DRW_Interface &intfa )
1141 {
1142 bool ret = true;
1143 duint32 bs = 0;
1144
1145 #define ENTRY_PARSE(e) \
1146 ret = e.parseDwg(version, &buff, bs); \
1147 parseAttribs(&e); \
1148 e.applyExtrusion(); \
1149 nextEntLink = e.nextEntLink; \
1150 prevEntLink = e.prevEntLink;
1151
1152 nextEntLink = prevEntLink = 0;// set to 0 to skip unimplemented entities
1153 dbuf->setPosition( obj.loc );
1154 //verify if position is ok:
1155 if ( !dbuf->isGood() )
1156 {
1157 DRW_DBG(" Warning: readDwgEntity, bad location\n");
1158 return false;
1159 }
1160 int size = dbuf->getModularShort();
1161 if ( version > DRW::AC1021 ) //2010+
1162 {
1163 bs = dbuf->getUModularChar();
1164 }
1165 duint8 *tmpByteStr = new duint8[size];
1166 dbuf->getBytes( tmpByteStr, size );
1167 //verify if getBytes is ok:
1168 if ( !dbuf->isGood() )
1169 {
1170 DRW_DBGH(obj.handle); DRW_DBG(" bad size "); DRW_DBG( size ); DRW_DBG ("\n");
1171 delete[]tmpByteStr;
1172 return false;
1173 }
1174 dwgBuffer buff( tmpByteStr, size, &decoder );
1175 dint16 oType = buff.getObjType( version );
1176 buff.resetPosition();
1177
1178 if ( oType > 499 )
1179 {
1180 std::map<duint32, DRW_Class *>::iterator it = classesmap.find( oType );
1181 if ( it == classesmap.end() ) //fail, not found in classes set error
1182 {
1183 DRW_DBG("Class "); DRW_DBG(oType);DRW_DBG("not found, handle: "); DRW_DBG(obj.handle); DRW_DBG("\n");
1184 delete[]tmpByteStr;
1185 return false;
1186 }
1187 else
1188 {
1189 DRW_Class *cl = it->second;
1190 if ( cl->dwgType != 0 )
1191 oType = cl->dwgType;
1192 }
1193 }
1194
1195 obj.type = oType;
1196 switch ( oType )
1197 {
1198 case 17:
1199 {
1200 DRW_Arc e;
1201 ENTRY_PARSE( e )
1202 intfa.addArc( e );
1203 break;
1204 }
1205 case 18:
1206 {
1207 DRW_Circle e;
1208 ENTRY_PARSE( e )
1209 intfa.addCircle( e );
1210 break;
1211 }
1212 case 19:
1213 {
1214 DRW_Line e;
1215 ENTRY_PARSE( e )
1216 intfa.addLine( e );
1217 break;
1218 }
1219 case 27:
1220 {
1221 DRW_Point e;
1222 ENTRY_PARSE( e )
1223 intfa.addPoint( e );
1224 break;
1225 }
1226 case 35:
1227 {
1228 DRW_Ellipse e;
1229 ENTRY_PARSE( e )
1230 intfa.addEllipse( e );
1231 break;
1232 }
1233 case 7:
1234 case 8: //minsert = 8
1235 {
1236 DRW_Insert e;
1237 ENTRY_PARSE( e )
1238 e.name = findTableName( DRW::BLOCK_RECORD, e.blockRecH.ref );//RLZ: find as block or blockrecord (ps & ps0)
1239 intfa.addInsert( e );
1240 break;
1241 }
1242 case 77:
1243 {
1244 DRW_LWPolyline e;
1245 ENTRY_PARSE( e )
1246 intfa.addLWPolyline( e );
1247 break;
1248 }
1249 case 1:
1250 {
1251 DRW_Text e;
1252 ENTRY_PARSE( e )
1253 e.style = findTableName( DRW::STYLE, e.styleH.ref );
1254 intfa.addText( e );
1255 break;
1256 }
1257 case 44:
1258 {
1259 DRW_MText e;
1260 ENTRY_PARSE( e )
1261 e.style = findTableName( DRW::STYLE, e.styleH.ref );
1262 intfa.addMText( e );
1263 break;
1264 }
1265 case 28:
1266 {
1267 DRW_3Dface e;
1268 ENTRY_PARSE( e )
1269 intfa.add3dFace( e );
1270 break;
1271 }
1272 case 20:
1273 {
1274 DRW_DimOrdinate e;
1275 ENTRY_PARSE( e )
1276 e.style = findTableName( DRW::DIMSTYLE, e.dimStyleH.ref );
1277 intfa.addDimOrdinate( &e );
1278 break;
1279 }
1280 case 21:
1281 {
1282 DRW_DimLinear e;
1283 ENTRY_PARSE( e )
1284 e.style = findTableName( DRW::DIMSTYLE, e.dimStyleH.ref );
1285 intfa.addDimLinear( &e );
1286 break;
1287 }
1288 case 22:
1289 {
1290 DRW_DimAligned e;
1291 ENTRY_PARSE( e )
1292 e.style = findTableName( DRW::DIMSTYLE, e.dimStyleH.ref );
1293 intfa.addDimAlign( &e );
1294 break;
1295 }
1296 case 23:
1297 {
1298 DRW_DimAngular3p e;
1299 ENTRY_PARSE( e )
1300 e.style = findTableName( DRW::DIMSTYLE, e.dimStyleH.ref );
1301 intfa.addDimAngular3P( &e );
1302 break;
1303 }
1304 case 24:
1305 {
1306 DRW_DimAngular e;
1307 ENTRY_PARSE( e )
1308 e.style = findTableName( DRW::DIMSTYLE, e.dimStyleH.ref );
1309 intfa.addDimAngular( &e );
1310 break;
1311 }
1312 case 25:
1313 {
1314 DRW_DimRadial e;
1315 ENTRY_PARSE( e )
1316 e.style = findTableName( DRW::DIMSTYLE, e.dimStyleH.ref );
1317 intfa.addDimRadial( &e );
1318 break;
1319 }
1320 case 26:
1321 {
1322 DRW_DimDiametric e;
1323 ENTRY_PARSE( e )
1324 e.style = findTableName( DRW::DIMSTYLE, e.dimStyleH.ref );
1325 intfa.addDimDiametric( &e );
1326 break;
1327 }
1328 case 45:
1329 {
1330 DRW_Leader e;
1331 ENTRY_PARSE( e )
1332 e.style = findTableName( DRW::DIMSTYLE, e.dimStyleH.ref );
1333 intfa.addLeader( &e );
1334 break;
1335 }
1336 case 31:
1337 {
1338 DRW_Solid e;
1339 ENTRY_PARSE( e )
1340 intfa.addSolid( e );
1341 break;
1342 }
1343 case 78:
1344 {
1345 DRW_Hatch e;
1346 ENTRY_PARSE( e )
1347 intfa.addHatch( &e );
1348 break;
1349 }
1350 case 32:
1351 {
1352 DRW_Trace e;
1353 ENTRY_PARSE( e )
1354 intfa.addTrace( e );
1355 break;
1356 }
1357 case 34:
1358 {
1359 DRW_Viewport e;
1360 ENTRY_PARSE( e )
1361 intfa.addViewport( e );
1362 break;
1363 }
1364 case 36:
1365 {
1366 DRW_Spline e;
1367 ENTRY_PARSE( e )
1368 intfa.addSpline( &e );
1369 break;
1370 }
1371 case 40:
1372 {
1373 DRW_Ray e;
1374 ENTRY_PARSE( e )
1375 intfa.addRay( e );
1376 break;
1377 }
1378 case 15: // pline 2D
1379 case 16: // pline 3D
1380 case 29: // pline PFACE
1381 {
1382 DRW_Polyline e;
1383 ENTRY_PARSE( e )
1384 readPlineVertex( e, dbuf );
1385 intfa.addPolyline( e );
1386 break;
1387 }
1388 #if 0
1389 case 30:
1390 {
1391 DRW_Polyline e;// MESH (not pline)
1392 ENTRY_PARSE( e )
1393 intfa.addRay( e );
1394 break;
1395 }
1396 #endif
1397 case 41:
1398 {
1399 DRW_Xline e;
1400 ENTRY_PARSE( e )
1401 intfa.addXline( e );
1402 break;
1403 }
1404 case 101:
1405 {
1406 DRW_Image e;
1407 ENTRY_PARSE( e )
1408 intfa.addImage( &e );
1409 break;
1410 }
1411
1412 default:
1413 //not supported or are object add to remaining map
1414 objObjectMap[obj.handle] = obj;
1415 break;
1416 }
1417 if ( !ret )
1418 {
1419 DRW_DBG("Warning: Entity type "); DRW_DBG(oType);DRW_DBG("has failed, handle: "); DRW_DBG(obj.handle); DRW_DBG("\n");
1420 }
1421 delete[]tmpByteStr;
1422 return ret;
1423 }
1424
readDwgObjects(DRW_Interface & intfa,dwgBuffer * dbuf)1425 bool dwgReader::readDwgObjects( DRW_Interface &intfa, dwgBuffer *dbuf )
1426 {
1427 bool ret = true;
1428 bool ret2 = true;
1429
1430 duint32 i=0;
1431 DRW_DBG("\nentities map total size= "); DRW_DBG(ObjectMap.size());
1432 DRW_DBG("\nobjects map total size= "); DRW_DBG(objObjectMap.size());
1433 std::map<duint32, objHandle>::iterator itB = objObjectMap.begin();
1434 std::map<duint32, objHandle>::iterator itE = objObjectMap.end();
1435 while ( itB != itE )
1436 {
1437 ret2 = readDwgObject( dbuf, itB->second, intfa );
1438 objObjectMap.erase( itB );
1439 itB = objObjectMap.begin();
1440 if ( ret )
1441 ret = ret2;
1442 }
1443 if (DRW_DBGGL == DRW_dbg::Level::Debug) {
1444 for (std::map<duint32, objHandle>::iterator it=remainingMap.begin(); it != remainingMap.end(); ++it){
1445 DRW_DBG("\nnum.# "); DRW_DBG(i++); DRW_DBG(" Remaining object Handle, loc, type= "); DRW_DBG(it->first);
1446 DRW_DBG(" "); DRW_DBG(it->second.loc); DRW_DBG(" "); DRW_DBG(it->second.type);
1447 }
1448 DRW_DBG("\n");
1449 }
1450 return ret;
1451 }
1452
1453 /**
1454 * Reads a dwg drawing object (dwg object object) given its offset in the file
1455 */
readDwgObject(dwgBuffer * dbuf,objHandle & obj,DRW_Interface & intfa)1456 bool dwgReader::readDwgObject( dwgBuffer *dbuf, objHandle &obj, DRW_Interface &intfa )
1457 {
1458 bool ret = true;
1459 duint32 bs = 0;
1460
1461 dbuf->setPosition( obj.loc );
1462 //verify if position is ok:
1463 if ( !dbuf->isGood() )
1464 {
1465 DRW_DBGH(obj.handle); DRW_DBG(" bad location "); DRW_DBG( obj.loc ); DRW_DBG ("\n");
1466 return false;
1467 }
1468 int size = dbuf->getModularShort();
1469 if ( version > DRW::AC1021 ) //2010+
1470 {
1471 bs = dbuf->getUModularChar();
1472 }
1473 duint8 *tmpByteStr = new duint8[size];
1474 dbuf->getBytes( tmpByteStr, size );
1475 //verify if getBytes is ok:
1476 if ( !dbuf->isGood() )
1477 {
1478 DRW_DBGH(obj.handle); DRW_DBG(" bad size "); DRW_DBG( size ); DRW_DBG ("\n");
1479 delete[]tmpByteStr;
1480 return false;
1481 }
1482 dwgBuffer buff( tmpByteStr, size, &decoder );
1483 //oType are set parsing entities
1484 dint16 oType = obj.type;
1485
1486 switch ( oType )
1487 {
1488 case 102:
1489 {
1490 DRW_ImageDef e;
1491 ret = e.parseDwg( version, &buff, bs );
1492 intfa.linkImage( &e );
1493 break;
1494 }
1495 default:
1496 //not supported object or entity add to remaining map for debug
1497 remainingMap[obj.handle] = obj;
1498 break;
1499 }
1500 if ( !ret )
1501 {
1502 DRW_DBG("Warning: Object type "); DRW_DBG(oType);DRW_DBG("has failed, handle: "); DRW_DBG(obj.handle); DRW_DBG("\n");
1503 }
1504 delete[]tmpByteStr;
1505 return ret;
1506 }
1507
1508
1509
parseDwg(DRW::Version version,dwgBuffer * buf,duint32 bs)1510 bool DRW_ObjControl::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs )
1511 {
1512 int unkData = 0;
1513 bool ret = DRW_TableEntry::parseDwg( version, buf, nullptr, bs );
1514 DRW_DBG("\n***************************** parsing object control entry *********************************************\n");
1515 if ( !ret )
1516 return ret;
1517 //last parsed is: XDic Missing Flag 2004+
1518 int numEntries = buf->getBitLong();
1519 DRW_DBG(" num entries: "); DRW_DBG(numEntries); DRW_DBG("\n");
1520 DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n");
1521
1522 // if (oType == 68 && version== DRW::AC1015){//V2000 dimstyle seems have one unknown byte hard handle counter??
1523 if ( oType == 68 && version > DRW::AC1014 ) //dimstyle seems have one unknown byte hard handle counter??
1524 {
1525 unkData = buf->getRawChar8();
1526 DRW_DBG(" unknown v2000 byte: "); DRW_DBG( unkData); DRW_DBG("\n");
1527 }
1528 if ( version > DRW::AC1018 ) //from v2007+ have a bit for strings follows (ObjControl do not have)
1529 {
1530 int stringBit = buf->getBit();
1531 DRW_DBG(" string bit for v2007+: "); DRW_DBG( stringBit); DRW_DBG("\n");
1532 }
1533
1534 dwgHandle objectH = buf->getHandle();
1535 DRW_DBG(" NULL Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n");
1536 DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n");
1537
1538 // if (oType == 56 && version== DRW::AC1015){//linetype in 2004 seems not have XDicObjH or NULL handle
1539 if ( xDictFlag != 1 ) //linetype in 2004 seems not have XDicObjH or NULL handle
1540 {
1541 dwgHandle XDicObjH = buf->getHandle();
1542 DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n");
1543 DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n");
1544 }
1545 //add 2 for modelspace, paperspace blocks & bylayer, byblock linetypes
1546 numEntries = ( ( oType == 48 ) || ( oType == 56 ) ) ? ( numEntries + 2 ) : numEntries;
1547
1548 for ( int i = 0; i < numEntries; i++ )
1549 {
1550 objectH = buf->getOffsetHandle( handle );
1551 if ( objectH.ref != 0 ) //in vports R14 I found some NULL handles
1552 handlesList.push_back( objectH.ref );
1553 DRW_DBG(" objectH Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n");
1554 DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n");
1555 }
1556
1557 for ( int i = 0; i < unkData; i++ )
1558 {
1559 objectH = buf->getOffsetHandle( handle );
1560 DRW_DBG(" unknown Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n");
1561 DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n");
1562 }
1563 return buf->isGood();
1564 }
1565