You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6402 lines
148 KiB

  1. /****************************************************************************
  2. ** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
  3. **
  4. ** This file is part of the dxflib project.
  5. **
  6. ** This file is free software; you can redistribute it and/or modify
  7. ** it under the terms of the GNU General Public License as published by
  8. ** the Free Software Foundation; either version 2 of the License, or
  9. ** (at your option) any later version.
  10. **
  11. ** Licensees holding valid dxflib Professional Edition licenses may use
  12. ** this file in accordance with the dxflib Commercial License
  13. ** Agreement provided with the Software.
  14. **
  15. ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  16. ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  17. **
  18. ** See http://www.ribbonsoft.com for further details.
  19. **
  20. ** Contact info@ribbonsoft.com if any conditions of this licensing are
  21. ** not clear to you.
  22. **
  23. **********************************************************************/
  24. #include "dl_dxf.h"
  25. #include <algorithm>
  26. #include <string>
  27. #include <cstdio>
  28. #include <cassert>
  29. #include <cmath>
  30. #include "dl_attributes.h"
  31. #include "dl_codes.h"
  32. #include "dl_creationadapter.h"
  33. #include "dl_writer_ascii.h"
  34. #include "iostream"
  35. /**
  36. * Default constructor.
  37. */
  38. DL_Dxf::DL_Dxf()
  39. {
  40. version = DL_VERSION_2000;
  41. vertices = NULL;
  42. maxVertices = 0;
  43. vertexIndex = 0;
  44. knots = NULL;
  45. maxKnots = 0;
  46. knotIndex = 0;
  47. weights = NULL;
  48. weightIndex = 0;
  49. controlPoints = NULL;
  50. maxControlPoints = 0;
  51. controlPointIndex = 0;
  52. fitPoints = NULL;
  53. maxFitPoints = 0;
  54. fitPointIndex = 0;
  55. leaderVertices = NULL;
  56. maxLeaderVertices = 0;
  57. leaderVertexIndex = 0;
  58. // Aux members, initialized here to avoid warnings in analysers
  59. firstHatchLoop = true;
  60. xRecordValues = false;
  61. groupCode = 0;
  62. currentObjectType = 0;
  63. settingValue[0] = 0;
  64. firstCall = true;
  65. libVersion = 0;
  66. appDictionaryHandle = 0;
  67. styleHandleStd = 0;
  68. }
  69. /**
  70. * Destructor.
  71. */
  72. DL_Dxf::~DL_Dxf()
  73. {
  74. if( vertices!=NULL )
  75. {
  76. delete[] vertices;
  77. }
  78. if( knots!=NULL )
  79. {
  80. delete[] knots;
  81. }
  82. if( controlPoints!=NULL )
  83. {
  84. delete[] controlPoints;
  85. }
  86. if( fitPoints!=NULL )
  87. {
  88. delete[] fitPoints;
  89. }
  90. if( weights!=NULL )
  91. {
  92. delete[] weights;
  93. }
  94. if( leaderVertices!=NULL )
  95. {
  96. delete[] leaderVertices;
  97. }
  98. }
  99. /**
  100. * @brief Reads the given file and calls the appropriate functions in
  101. * the given creation interface for every entity found in the file.
  102. *
  103. * @param file Input
  104. * Path and name of file to read
  105. * @param creationInterface
  106. * Pointer to the class which takes care of the entities in the file.
  107. *
  108. * @retval true If \p file could be opened.
  109. * @retval false If \p file could not be opened.
  110. */
  111. bool DL_Dxf::in( const std::string& file, DL_CreationInterface* creationInterface )
  112. {
  113. FILE* fp;
  114. firstCall = true;
  115. currentObjectType = DL_UNKNOWN;
  116. fp = fopen( file.c_str(), "rt" );
  117. if( fp )
  118. {
  119. std::locale oldLocale = std::locale::global( std::locale( "C" ) ); // use dot in numbers
  120. while( readDxfGroups( fp, creationInterface ) )
  121. {
  122. }
  123. std::locale::global( oldLocale );
  124. fclose( fp );
  125. return true;
  126. }
  127. return false;
  128. }
  129. /**
  130. * Reads a DXF file from an existing stream.
  131. *
  132. * @param stream The string stream.
  133. * @param creationInterface
  134. * Pointer to the class which takes care of the entities in the file.
  135. *
  136. * @retval true If \p file could be opened.
  137. * @retval false If \p file could not be opened.
  138. */
  139. bool DL_Dxf::in( std::stringstream& stream,
  140. DL_CreationInterface* creationInterface )
  141. {
  142. if( stream.good() )
  143. {
  144. firstCall = true;
  145. currentObjectType = DL_UNKNOWN;
  146. while( readDxfGroups( stream, creationInterface ) )
  147. {
  148. }
  149. return true;
  150. }
  151. return false;
  152. }
  153. /**
  154. * @brief Reads a group couplet from a DXF file. Calls another function
  155. * to process it.
  156. *
  157. * A group couplet consists of two lines that represent a single
  158. * piece of data. An integer constant on the first line indicates
  159. * the type of data. The value is on the next line.\n
  160. *
  161. * This function reads a couplet, determines the type of data, and
  162. * passes the value to the the appropriate handler function of
  163. * \p creationInterface.\n
  164. *
  165. * \p fp is advanced so that the next call to \p readDXFGroups() reads
  166. * the next couplet in the file.
  167. *
  168. * @param fp Handle of input file
  169. * @param creationInterface Handle of class which processes entities
  170. * in the file
  171. *
  172. * @retval true If EOF not reached.
  173. * @retval false If EOF reached.
  174. */
  175. bool DL_Dxf::readDxfGroups( FILE* fp, DL_CreationInterface* creationInterface )
  176. {
  177. static int line = 1;
  178. // Read one group of the DXF file and strip the lines:
  179. if( DL_Dxf::getStrippedLine( groupCodeTmp, DL_DXF_MAXLINE, fp )
  180. && DL_Dxf::getStrippedLine( groupValue, DL_DXF_MAXLINE, fp, false ) )
  181. {
  182. groupCode = (unsigned int) toInt( groupCodeTmp );
  183. creationInterface->processCodeValuePair( groupCode, groupValue );
  184. line += 2;
  185. processDXFGroup( creationInterface, groupCode, groupValue );
  186. }
  187. return !feof( fp );
  188. }
  189. /**
  190. * Same as above but for stringstreams.
  191. */
  192. bool DL_Dxf::readDxfGroups( std::stringstream& stream,
  193. DL_CreationInterface* creationInterface )
  194. {
  195. static int line = 1;
  196. // Read one group of the DXF file and chop the lines:
  197. if( DL_Dxf::getStrippedLine( groupCodeTmp, DL_DXF_MAXLINE, stream )
  198. && DL_Dxf::getStrippedLine( groupValue, DL_DXF_MAXLINE, stream, false ) )
  199. {
  200. groupCode = (unsigned int) toInt( groupCodeTmp );
  201. line += 2;
  202. processDXFGroup( creationInterface, groupCode, groupValue );
  203. }
  204. return !stream.eof();
  205. }
  206. /**
  207. * @brief Reads line from file & strips whitespace at start and newline
  208. * at end.
  209. *
  210. * @param s Output\n
  211. * Pointer to character array that chopped line will be returned in.
  212. * @param size Size of \p s. (Including space for NULL.)
  213. * @param fp Input\n
  214. * Handle of input file.
  215. *
  216. * @retval true if line could be read
  217. * @retval false if \p fp is already at end of file
  218. *
  219. * @todo Change function to use safer FreeBSD strl* functions
  220. * @todo Is it a problem if line is blank (i.e., newline only)?
  221. * Then, when function returns, (s==NULL).
  222. */
  223. bool DL_Dxf::getStrippedLine( std::string& s, unsigned int size, FILE* fp, bool stripSpace )
  224. {
  225. if( !feof( fp ) )
  226. {
  227. // The whole line in the file. Includes space for NULL.
  228. char* wholeLine = new char[size];
  229. // Only the useful part of the line
  230. char* line;
  231. line = fgets( wholeLine, size, fp );
  232. if( line!=NULL && line[0] != '\0' ) // Evaluates to fgets() retval
  233. {
  234. // line == wholeLine at this point.
  235. // Both guaranteed to be NULL terminated.
  236. // Strip leading whitespace and trailing CR/LF.
  237. stripWhiteSpace( &line, stripSpace );
  238. s = line;
  239. assert( size > s.length() );
  240. }
  241. delete[] wholeLine; // Done with wholeLine
  242. return true;
  243. }
  244. else
  245. {
  246. s = "";
  247. return false;
  248. }
  249. }
  250. /**
  251. * Same as above but for stringstreams.
  252. */
  253. bool DL_Dxf::getStrippedLine( std::string& s, unsigned int size,
  254. std::stringstream& stream, bool stripSpace )
  255. {
  256. if( !stream.eof() )
  257. {
  258. // Only the useful part of the line
  259. char* line = new char[size + 1];
  260. char* oriLine = line;
  261. stream.getline( line, size );
  262. stripWhiteSpace( &line, stripSpace );
  263. s = line;
  264. assert( size > s.length() );
  265. delete[] oriLine;
  266. return true;
  267. }
  268. else
  269. {
  270. s[0] = '\0';
  271. return false;
  272. }
  273. }
  274. /**
  275. * @brief Strips leading whitespace and trailing Carriage Return (CR)
  276. * and Line Feed (LF) from NULL terminated string.
  277. *
  278. * @param s Input and output.
  279. * NULL terminates string.
  280. *
  281. * @retval true if \p s is non-NULL
  282. * @retval false if \p s is NULL
  283. */
  284. bool DL_Dxf::stripWhiteSpace( char** s, bool stripSpace )
  285. {
  286. // last non-NULL char:
  287. int lastChar = strlen( *s ) - 1;
  288. // Is last character CR or LF?
  289. while( (lastChar >= 0)
  290. && ( ( (*s)[lastChar] == 10 ) || ( (*s)[lastChar] == 13 )
  291. || ( stripSpace && ( (*s)[lastChar] == ' ' || ( (*s)[lastChar] == '\t' ) ) ) ) )
  292. {
  293. (*s)[lastChar] = '\0';
  294. lastChar--;
  295. }
  296. // Skip whitespace, excluding \n, at beginning of line
  297. if( stripSpace )
  298. {
  299. while( (*s)[0]==' ' || (*s)[0]=='\t' )
  300. {
  301. ++(*s);
  302. }
  303. }
  304. return (*s) ? true : false;
  305. }
  306. /**
  307. * Processes a group (pair of group code and value).
  308. *
  309. * @param creationInterface Handle to class that creates entities and
  310. * other CAD data from DXF group codes
  311. *
  312. * @param agroupCode Constant indicating the data type of the group.
  313. * @param agroupValue The data value.
  314. *
  315. * @retval true if done processing current entity and new entity begun
  316. * @retval false if not done processing current entity
  317. */
  318. bool DL_Dxf::processDXFGroup( DL_CreationInterface* creationInterface,
  319. int agroupCode, const std::string& agroupValue )
  320. {
  321. // printf("%d\n", agroupCode);
  322. // printf("%s\n", agroupValue.c_str());
  323. // Init values on first call
  324. if( firstCall )
  325. {
  326. settingValue[0] = '\0';
  327. firstCall = false;
  328. }
  329. // Indicates comment or dxflib version:
  330. if( agroupCode==999 )
  331. {
  332. if( !agroupValue.empty() )
  333. {
  334. if( agroupValue.substr( 0, 6 )=="dxflib" )
  335. {
  336. libVersion = getLibVersion( agroupValue.substr( 7 ) );
  337. }
  338. addComment( creationInterface, agroupValue );
  339. }
  340. }
  341. // Indicates start of new entity or variable:
  342. else if( agroupCode==0 || agroupCode==9 )
  343. {
  344. // If new entity is encountered, the last one is complete.
  345. // Prepare default attributes for next entity:
  346. std::string layer = getStringValue( 8, "0" );
  347. int width;
  348. // Compatibility with qcad1:
  349. if( hasValue( 39 ) && !hasValue( 370 ) )
  350. {
  351. width = getIntValue( 39, -1 );
  352. }
  353. // since autocad 2002:
  354. else if( hasValue( 370 ) )
  355. {
  356. width = getIntValue( 370, -1 );
  357. }
  358. // default to BYLAYER:
  359. else
  360. {
  361. width = -1;
  362. }
  363. int color;
  364. color = getIntValue( 62, 256 );
  365. int color24;
  366. color24 = getIntValue( 420, -1 );
  367. int handle;
  368. handle = getInt16Value( 5, -1 );
  369. std::string linetype = getStringValue( 6, "BYLAYER" );
  370. attrib = DL_Attributes( layer, // layer
  371. color, // color
  372. color24, // 24 bit color
  373. width, // width
  374. linetype, // linetype
  375. handle ); // handle
  376. attrib.setInPaperSpace( (bool) getIntValue( 67, 0 ) );
  377. attrib.setLinetypeScale( getRealValue( 48, 1.0 ) );
  378. creationInterface->setAttributes( attrib );
  379. int elevationGroupCode = 30;
  380. if( currentObjectType==DL_ENTITY_LWPOLYLINE )
  381. {
  382. // see lwpolyline group codes reference
  383. elevationGroupCode = 38;
  384. }
  385. else
  386. {
  387. // see polyline group codes reference
  388. elevationGroupCode = 30;
  389. }
  390. creationInterface->setExtrusion( getRealValue( 210, 0.0 ),
  391. getRealValue( 220, 0.0 ),
  392. getRealValue( 230, 1.0 ),
  393. getRealValue( elevationGroupCode, 0.0 ) );
  394. // Add the previously parsed entity via creationInterface
  395. switch( currentObjectType )
  396. {
  397. case DL_SETTING:
  398. addSetting( creationInterface );
  399. break;
  400. case DL_LAYER:
  401. addLayer( creationInterface );
  402. break;
  403. case DL_LINETYPE:
  404. addLinetype( creationInterface );
  405. break;
  406. case DL_BLOCK:
  407. addBlock( creationInterface );
  408. break;
  409. case DL_ENDBLK:
  410. endBlock( creationInterface );
  411. break;
  412. case DL_STYLE:
  413. addTextStyle( creationInterface );
  414. break;
  415. case DL_ENTITY_POINT:
  416. addPoint( creationInterface );
  417. break;
  418. case DL_ENTITY_LINE:
  419. addLine( creationInterface );
  420. break;
  421. case DL_ENTITY_XLINE:
  422. addXLine( creationInterface );
  423. break;
  424. case DL_ENTITY_RAY:
  425. addRay( creationInterface );
  426. break;
  427. case DL_ENTITY_POLYLINE:
  428. case DL_ENTITY_LWPOLYLINE:
  429. addPolyline( creationInterface );
  430. break;
  431. case DL_ENTITY_VERTEX:
  432. addVertex( creationInterface );
  433. break;
  434. case DL_ENTITY_SPLINE:
  435. addSpline( creationInterface );
  436. break;
  437. case DL_ENTITY_ARC:
  438. addArc( creationInterface );
  439. break;
  440. case DL_ENTITY_CIRCLE:
  441. addCircle( creationInterface );
  442. break;
  443. case DL_ENTITY_ELLIPSE:
  444. addEllipse( creationInterface );
  445. break;
  446. case DL_ENTITY_INSERT:
  447. addInsert( creationInterface );
  448. break;
  449. case DL_ENTITY_MTEXT:
  450. addMText( creationInterface );
  451. break;
  452. case DL_ENTITY_TEXT:
  453. addText( creationInterface );
  454. break;
  455. case DL_ENTITY_ARCALIGNEDTEXT:
  456. addArcAlignedText( creationInterface );
  457. break;
  458. case DL_ENTITY_ATTRIB:
  459. addAttribute( creationInterface );
  460. break;
  461. case DL_ENTITY_DIMENSION:
  462. {
  463. int type = (getIntValue( 70, 0 ) & 0x07);
  464. switch( type )
  465. {
  466. case 0:
  467. addDimLinear( creationInterface );
  468. break;
  469. case 1:
  470. addDimAligned( creationInterface );
  471. break;
  472. case 2:
  473. addDimAngular( creationInterface );
  474. break;
  475. case 3:
  476. addDimDiametric( creationInterface );
  477. break;
  478. case 4:
  479. addDimRadial( creationInterface );
  480. break;
  481. case 5:
  482. addDimAngular3P( creationInterface );
  483. break;
  484. case 6:
  485. addDimOrdinate( creationInterface );
  486. break;
  487. default:
  488. break;
  489. }
  490. }
  491. break;
  492. case DL_ENTITY_LEADER:
  493. addLeader( creationInterface );
  494. break;
  495. case DL_ENTITY_HATCH:
  496. // addHatch(creationInterface);
  497. handleHatchData( creationInterface );
  498. break;
  499. case DL_ENTITY_IMAGE:
  500. addImage( creationInterface );
  501. break;
  502. case DL_ENTITY_IMAGEDEF:
  503. addImageDef( creationInterface );
  504. break;
  505. case DL_ENTITY_TRACE:
  506. addTrace( creationInterface );
  507. break;
  508. case DL_ENTITY_3DFACE:
  509. add3dFace( creationInterface );
  510. break;
  511. case DL_ENTITY_SOLID:
  512. addSolid( creationInterface );
  513. break;
  514. case DL_ENTITY_SEQEND:
  515. endSequence( creationInterface );
  516. break;
  517. default:
  518. break;
  519. }
  520. creationInterface->endSection();
  521. // reset all values (they are not persistent and only this
  522. // way we can set defaults for omitted values)
  523. // for (int i=0; i<DL_DXF_MAXGROUPCODE; ++i) {
  524. // values[i][0] = '\0';
  525. // }
  526. values.clear();
  527. settingValue[0] = '\0';
  528. settingKey = "";
  529. firstHatchLoop = true;
  530. // firstHatchEdge = true;
  531. hatchEdge = DL_HatchEdgeData();
  532. // xRecordHandle = "";
  533. xRecordValues = false;
  534. // Last DXF entity or setting has been handled
  535. // Now determine what the next entity or setting type is
  536. int prevEntity = currentObjectType;
  537. // Read DXF variable:
  538. if( agroupValue[0]=='$' )
  539. {
  540. currentObjectType = DL_SETTING;
  541. settingKey = agroupValue;
  542. }
  543. // Read Layers:
  544. else if( agroupValue=="LAYER" )
  545. {
  546. currentObjectType = DL_LAYER;
  547. }
  548. // Read Linetypes:
  549. else if( agroupValue=="LTYPE" )
  550. {
  551. currentObjectType = DL_LINETYPE;
  552. }
  553. // Read Blocks:
  554. else if( agroupValue=="BLOCK" )
  555. {
  556. currentObjectType = DL_BLOCK;
  557. }
  558. else if( agroupValue=="ENDBLK" )
  559. {
  560. currentObjectType = DL_ENDBLK;
  561. }
  562. // Read text styles:
  563. else if( agroupValue=="STYLE" )
  564. {
  565. currentObjectType = DL_STYLE;
  566. }
  567. // Read entities:
  568. else if( agroupValue=="POINT" )
  569. {
  570. currentObjectType = DL_ENTITY_POINT;
  571. }
  572. else if( agroupValue=="LINE" )
  573. {
  574. currentObjectType = DL_ENTITY_LINE;
  575. }
  576. else if( agroupValue=="XLINE" )
  577. {
  578. currentObjectType = DL_ENTITY_XLINE;
  579. }
  580. else if( agroupValue=="RAY" )
  581. {
  582. currentObjectType = DL_ENTITY_RAY;
  583. }
  584. else if( agroupValue=="POLYLINE" )
  585. {
  586. currentObjectType = DL_ENTITY_POLYLINE;
  587. }
  588. else if( agroupValue=="LWPOLYLINE" )
  589. {
  590. currentObjectType = DL_ENTITY_LWPOLYLINE;
  591. }
  592. else if( agroupValue=="VERTEX" )
  593. {
  594. currentObjectType = DL_ENTITY_VERTEX;
  595. }
  596. else if( agroupValue=="SPLINE" )
  597. {
  598. currentObjectType = DL_ENTITY_SPLINE;
  599. }
  600. else if( agroupValue=="ARC" )
  601. {
  602. currentObjectType = DL_ENTITY_ARC;
  603. }
  604. else if( agroupValue=="ELLIPSE" )
  605. {
  606. currentObjectType = DL_ENTITY_ELLIPSE;
  607. }
  608. else if( agroupValue=="CIRCLE" )
  609. {
  610. currentObjectType = DL_ENTITY_CIRCLE;
  611. }
  612. else if( agroupValue=="INSERT" )
  613. {
  614. currentObjectType = DL_ENTITY_INSERT;
  615. }
  616. else if( agroupValue=="TEXT" )
  617. {
  618. currentObjectType = DL_ENTITY_TEXT;
  619. }
  620. else if( agroupValue=="MTEXT" )
  621. {
  622. currentObjectType = DL_ENTITY_MTEXT;
  623. }
  624. else if( agroupValue=="ARCALIGNEDTEXT" )
  625. {
  626. currentObjectType = DL_ENTITY_ARCALIGNEDTEXT;
  627. }
  628. else if( agroupValue=="ATTRIB" )
  629. {
  630. currentObjectType = DL_ENTITY_ATTRIB;
  631. }
  632. else if( agroupValue=="DIMENSION" )
  633. {
  634. currentObjectType = DL_ENTITY_DIMENSION;
  635. }
  636. else if( agroupValue=="LEADER" )
  637. {
  638. currentObjectType = DL_ENTITY_LEADER;
  639. }
  640. else if( agroupValue=="HATCH" )
  641. {
  642. currentObjectType = DL_ENTITY_HATCH;
  643. }
  644. else if( agroupValue=="IMAGE" )
  645. {
  646. currentObjectType = DL_ENTITY_IMAGE;
  647. }
  648. else if( agroupValue=="IMAGEDEF" )
  649. {
  650. currentObjectType = DL_ENTITY_IMAGEDEF;
  651. }
  652. else if( agroupValue=="TRACE" )
  653. {
  654. currentObjectType = DL_ENTITY_TRACE;
  655. }
  656. else if( agroupValue=="SOLID" )
  657. {
  658. currentObjectType = DL_ENTITY_SOLID;
  659. }
  660. else if( agroupValue=="3DFACE" )
  661. {
  662. currentObjectType = DL_ENTITY_3DFACE;
  663. }
  664. else if( agroupValue=="SEQEND" )
  665. {
  666. currentObjectType = DL_ENTITY_SEQEND;
  667. }
  668. else if( agroupValue=="XRECORD" )
  669. {
  670. currentObjectType = DL_XRECORD;
  671. }
  672. else if( agroupValue=="DICTIONARY" )
  673. {
  674. currentObjectType = DL_DICTIONARY;
  675. }
  676. else
  677. {
  678. currentObjectType = DL_UNKNOWN;
  679. }
  680. // end of old style POLYLINE entity
  681. if( prevEntity==DL_ENTITY_VERTEX && currentObjectType!=DL_ENTITY_VERTEX )
  682. {
  683. endEntity( creationInterface );
  684. }
  685. // TODO: end of SPLINE entity
  686. // if (prevEntity==DL_ENTITY_CONTROLPOINT && currentEntity!=DL_ENTITY_CONTROLPOINT) {
  687. // endEntity(creationInterface);
  688. // }
  689. return true;
  690. }
  691. else
  692. {
  693. // Group code does not indicate start of new entity or setting,
  694. // so this group must be continuation of data for the current
  695. // one.
  696. if( agroupCode<DL_DXF_MAXGROUPCODE )
  697. {
  698. bool handled = false;
  699. switch( currentObjectType )
  700. {
  701. case DL_ENTITY_MTEXT:
  702. handled = handleMTextData( creationInterface );
  703. break;
  704. case DL_ENTITY_LWPOLYLINE:
  705. handled = handleLWPolylineData( creationInterface );
  706. break;
  707. case DL_ENTITY_SPLINE:
  708. handled = handleSplineData( creationInterface );
  709. break;
  710. case DL_ENTITY_LEADER:
  711. handled = handleLeaderData( creationInterface );
  712. break;
  713. case DL_ENTITY_HATCH:
  714. handled = handleHatchData( creationInterface );
  715. break;
  716. case DL_XRECORD:
  717. handled = handleXRecordData( creationInterface );
  718. break;
  719. case DL_DICTIONARY:
  720. handled = handleDictionaryData( creationInterface );
  721. break;
  722. case DL_LINETYPE:
  723. handled = handleLinetypeData( creationInterface );
  724. break;
  725. default:
  726. break;
  727. }
  728. // Always try to handle XData, unless we're in an XData record:
  729. if( currentObjectType!=DL_XRECORD )
  730. {
  731. handled = handleXData( creationInterface );
  732. }
  733. if( !handled )
  734. {
  735. // Normal group / value pair:
  736. values[agroupCode] = agroupValue;
  737. }
  738. }
  739. return false;
  740. }
  741. return false;
  742. }
  743. /**
  744. * Adds a comment from the DXF file.
  745. */
  746. void DL_Dxf::addComment( DL_CreationInterface* creationInterface, const std::string& comment )
  747. {
  748. creationInterface->addComment( comment );
  749. }
  750. void DL_Dxf::addDictionary( DL_CreationInterface* creationInterface )
  751. {
  752. creationInterface->addDictionary( DL_DictionaryData( getStringValue( 5, "" ) ) );
  753. }
  754. void DL_Dxf::addDictionaryEntry( DL_CreationInterface* creationInterface )
  755. {
  756. creationInterface->addDictionaryEntry( DL_DictionaryEntryData( getStringValue( 3, "" ),
  757. getStringValue( 350, "" ) ) );
  758. }
  759. /**
  760. * Adds a variable from the DXF file.
  761. */
  762. void DL_Dxf::addSetting( DL_CreationInterface* creationInterface )
  763. {
  764. int c = -1;
  765. std::map<int, std::string>::iterator it = values.begin();
  766. if( it!=values.end() )
  767. {
  768. c = it->first;
  769. }
  770. // for (int i=0; i<=380; ++i) {
  771. // if (values[i][0]!='\0') {
  772. // c = i;
  773. // break;
  774. // }
  775. // }
  776. // string
  777. if( c>=0 && c<=9 )
  778. {
  779. creationInterface->setVariableString( settingKey, values[c], c );
  780. #ifdef DL_COMPAT
  781. // backwards compatibility:
  782. creationInterface->setVariableString( settingKey.c_str(), values[c].c_str(), c );
  783. #endif
  784. }
  785. // vector
  786. else if( c>=10 && c<=39 )
  787. {
  788. if( c==10 )
  789. {
  790. creationInterface->setVariableVector(
  791. settingKey,
  792. getRealValue( c, 0.0 ),
  793. getRealValue( c + 10, 0.0 ),
  794. getRealValue( c + 20, 0.0 ),
  795. c );
  796. }
  797. }
  798. // double
  799. else if( c>=40 && c<=59 )
  800. {
  801. creationInterface->setVariableDouble( settingKey, getRealValue( c, 0.0 ), c );
  802. }
  803. // int
  804. else if( c>=60 && c<=99 )
  805. {
  806. creationInterface->setVariableInt( settingKey, getIntValue( c, 0 ), c );
  807. }
  808. // misc
  809. else if( c>=0 )
  810. {
  811. creationInterface->setVariableString( settingKey, getStringValue( c, "" ), c );
  812. }
  813. }
  814. /**
  815. * Adds a layer that was read from the file via the creation interface.
  816. */
  817. void DL_Dxf::addLayer( DL_CreationInterface* creationInterface )
  818. {
  819. // correct some invalid attributes for layers:
  820. attrib = creationInterface->getAttributes();
  821. if( attrib.getColor()==256 || attrib.getColor()==0 )
  822. {
  823. attrib.setColor( 7 );
  824. }
  825. if( attrib.getWidth()<0 )
  826. {
  827. attrib.setWidth( 1 );
  828. }
  829. std::string linetype = attrib.getLinetype();
  830. std::transform( linetype.begin(), linetype.end(), linetype.begin(), ::toupper );
  831. if( linetype=="BYLAYER" || linetype=="BYBLOCK" )
  832. {
  833. attrib.setLinetype( "CONTINUOUS" );
  834. }
  835. // add layer
  836. std::string name = getStringValue( 2, "" );
  837. if( name.length()==0 )
  838. {
  839. return;
  840. }
  841. creationInterface->addLayer( DL_LayerData( name, getIntValue( 70, 0 ) ) );
  842. }
  843. /**
  844. * Adds a linetype that was read from the file via the creation interface.
  845. */
  846. void DL_Dxf::addLinetype( DL_CreationInterface* creationInterface )
  847. {
  848. std::string name = getStringValue( 2, "" );
  849. if( name.length()==0 )
  850. {
  851. return;
  852. }
  853. int numDashes = getIntValue( 73, 0 );
  854. // double dashes[numDashes];
  855. DL_LinetypeData d(
  856. // name:
  857. name,
  858. // description:
  859. getStringValue( 3, "" ),
  860. // flags
  861. getIntValue( 70, 0 ),
  862. // number of dashes:
  863. numDashes,
  864. // pattern length:
  865. getRealValue( 40, 0.0 )
  866. // pattern:
  867. // dashes
  868. );
  869. if( name != "By Layer" && name != "By Block" && name != "BYLAYER" && name != "BYBLOCK" )
  870. {
  871. creationInterface->addLinetype( d );
  872. }
  873. }
  874. /**
  875. * Handles all dashes in linetype pattern.
  876. */
  877. bool DL_Dxf::handleLinetypeData( DL_CreationInterface* creationInterface )
  878. {
  879. if( groupCode == 49 )
  880. {
  881. creationInterface->addLinetypeDash( toReal( groupValue ) );
  882. return true;
  883. }
  884. return false;
  885. }
  886. /**
  887. * Adds a block that was read from the file via the creation interface.
  888. */
  889. void DL_Dxf::addBlock( DL_CreationInterface* creationInterface )
  890. {
  891. std::string name = getStringValue( 2, "" );
  892. if( name.length()==0 )
  893. {
  894. return;
  895. }
  896. DL_BlockData d(
  897. // Name:
  898. name,
  899. // flags:
  900. getIntValue( 70, 0 ),
  901. // base point:
  902. getRealValue( 10, 0.0 ),
  903. getRealValue( 20, 0.0 ),
  904. getRealValue( 30, 0.0 ) );
  905. creationInterface->addBlock( d );
  906. }
  907. /**
  908. * Ends a block that was read from the file via the creation interface.
  909. */
  910. void DL_Dxf::endBlock( DL_CreationInterface* creationInterface )
  911. {
  912. creationInterface->endBlock();
  913. }
  914. void DL_Dxf::addTextStyle( DL_CreationInterface* creationInterface )
  915. {
  916. std::string name = getStringValue( 2, "" );
  917. if( name.length()==0 )
  918. {
  919. return;
  920. }
  921. DL_StyleData d(
  922. // name:
  923. name,
  924. // flags
  925. getIntValue( 70, 0 ),
  926. // fixed text heigth:
  927. getRealValue( 40, 0.0 ),
  928. // width factor:
  929. getRealValue( 41, 0.0 ),
  930. // oblique angle:
  931. getRealValue( 50, 0.0 ),
  932. // text generation flags:
  933. getIntValue( 71, 0 ),
  934. // last height used:
  935. getRealValue( 42, 0.0 ),
  936. // primart font file:
  937. getStringValue( 3, "" ),
  938. // big font file:
  939. getStringValue( 4, "" )
  940. );
  941. creationInterface->addTextStyle( d );
  942. }
  943. /**
  944. * Adds a point entity that was read from the file via the creation interface.
  945. */
  946. void DL_Dxf::addPoint( DL_CreationInterface* creationInterface )
  947. {
  948. DL_PointData d( getRealValue( 10, 0.0 ),
  949. getRealValue( 20, 0.0 ),
  950. getRealValue( 30, 0.0 ) );
  951. creationInterface->addPoint( d );
  952. }
  953. /**
  954. * Adds a line entity that was read from the file via the creation interface.
  955. */
  956. void DL_Dxf::addLine( DL_CreationInterface* creationInterface )
  957. {
  958. DL_LineData d( getRealValue( 10, 0.0 ),
  959. getRealValue( 20, 0.0 ),
  960. getRealValue( 30, 0.0 ),
  961. getRealValue( 11, 0.0 ),
  962. getRealValue( 21, 0.0 ),
  963. getRealValue( 31, 0.0 ) );
  964. creationInterface->addLine( d );
  965. }
  966. /**
  967. * Adds an xline entity that was read from the file via the creation interface.
  968. */
  969. void DL_Dxf::addXLine( DL_CreationInterface* creationInterface )
  970. {
  971. DL_XLineData d( getRealValue( 10, 0.0 ),
  972. getRealValue( 20, 0.0 ),
  973. getRealValue( 30, 0.0 ),
  974. getRealValue( 11, 0.0 ),
  975. getRealValue( 21, 0.0 ),
  976. getRealValue( 31, 0.0 ) );
  977. creationInterface->addXLine( d );
  978. }
  979. /**
  980. * Adds a ray entity that was read from the file via the creation interface.
  981. */
  982. void DL_Dxf::addRay( DL_CreationInterface* creationInterface )
  983. {
  984. DL_RayData d( getRealValue( 10, 0.0 ),
  985. getRealValue( 20, 0.0 ),
  986. getRealValue( 30, 0.0 ),
  987. getRealValue( 11, 0.0 ),
  988. getRealValue( 21, 0.0 ),
  989. getRealValue( 31, 0.0 ) );
  990. creationInterface->addRay( d );
  991. }
  992. /**
  993. * Adds a polyline entity that was read from the file via the creation interface.
  994. */
  995. void DL_Dxf::addPolyline( DL_CreationInterface* creationInterface )
  996. {
  997. DL_PolylineData pd( maxVertices, getIntValue( 71, 0 ), getIntValue( 72, 0 ), getIntValue( 70,
  998. 0 ), getRealValue( 38, 0 ) );
  999. creationInterface->addPolyline( pd );
  1000. maxVertices = std::min( maxVertices, vertexIndex + 1 );
  1001. if( currentObjectType==DL_ENTITY_LWPOLYLINE )
  1002. {
  1003. for( int i = 0; i<maxVertices; i++ )
  1004. {
  1005. DL_VertexData d( vertices[i * 4],
  1006. vertices[i * 4 + 1],
  1007. vertices[i * 4 + 2],
  1008. vertices[i * 4 + 3] );
  1009. creationInterface->addVertex( d );
  1010. }
  1011. creationInterface->endEntity();
  1012. }
  1013. }
  1014. /**
  1015. * Adds a polyline vertex entity that was read from the file
  1016. * via the creation interface.
  1017. */
  1018. void DL_Dxf::addVertex( DL_CreationInterface* creationInterface )
  1019. {
  1020. // vertex defines a face of the mesh if its vertex flags group has the
  1021. // 128 bit set but not the 64 bit. 10, 20, 30 are irrelevant and set to
  1022. // 0 in this case
  1023. if( (getIntValue( 70, 0 ) & 128) && !(getIntValue( 70, 0 ) & 64) )
  1024. {
  1025. return;
  1026. }
  1027. DL_VertexData d( getRealValue( 10, 0.0 ),
  1028. getRealValue( 20, 0.0 ),
  1029. getRealValue( 30, 0.0 ),
  1030. getRealValue( 42, 0.0 ) );
  1031. creationInterface->addVertex( d );
  1032. }
  1033. /**
  1034. * Adds a spline entity that was read from the file via the creation interface.
  1035. */
  1036. void DL_Dxf::addSpline( DL_CreationInterface* creationInterface )
  1037. {
  1038. DL_SplineData sd( getIntValue( 71, 3 ),
  1039. maxKnots,
  1040. maxControlPoints,
  1041. maxFitPoints,
  1042. getIntValue( 70, 4 ) );
  1043. sd.tangentStartX = getRealValue( 12, 0.0 );
  1044. sd.tangentStartY = getRealValue( 22, 0.0 );
  1045. sd.tangentStartZ = getRealValue( 32, 0.0 );
  1046. sd.tangentEndX = getRealValue( 13, 0.0 );
  1047. sd.tangentEndY = getRealValue( 23, 0.0 );
  1048. sd.tangentEndZ = getRealValue( 33, 0.0 );
  1049. creationInterface->addSpline( sd );
  1050. int i;
  1051. for( i = 0; i<maxControlPoints; i++ )
  1052. {
  1053. DL_ControlPointData d( controlPoints[i * 3],
  1054. controlPoints[i * 3 + 1],
  1055. controlPoints[i * 3 + 2],
  1056. weights[i] );
  1057. creationInterface->addControlPoint( d );
  1058. }
  1059. for( i = 0; i<maxFitPoints; i++ )
  1060. {
  1061. DL_FitPointData d( fitPoints[i * 3],
  1062. fitPoints[i * 3 + 1],
  1063. fitPoints[i * 3 + 2] );
  1064. creationInterface->addFitPoint( d );
  1065. }
  1066. for( i = 0; i<maxKnots; i++ )
  1067. {
  1068. DL_KnotData k( knots[i] );
  1069. creationInterface->addKnot( k );
  1070. }
  1071. creationInterface->endEntity();
  1072. }
  1073. /**
  1074. * Adds an arc entity that was read from the file via the creation interface.
  1075. */
  1076. void DL_Dxf::addArc( DL_CreationInterface* creationInterface )
  1077. {
  1078. DL_ArcData d( getRealValue( 10, 0.0 ),
  1079. getRealValue( 20, 0.0 ),
  1080. getRealValue( 30, 0.0 ),
  1081. getRealValue( 40, 0.0 ),
  1082. getRealValue( 50, 0.0 ),
  1083. getRealValue( 51, 0.0 ) );
  1084. creationInterface->addArc( d );
  1085. }
  1086. /**
  1087. * Adds a circle entity that was read from the file via the creation interface.
  1088. */
  1089. void DL_Dxf::addCircle( DL_CreationInterface* creationInterface )
  1090. {
  1091. DL_CircleData d( getRealValue( 10, 0.0 ),
  1092. getRealValue( 20, 0.0 ),
  1093. getRealValue( 30, 0.0 ),
  1094. getRealValue( 40, 0.0 ) );
  1095. creationInterface->addCircle( d );
  1096. }
  1097. /**
  1098. * Adds an ellipse entity that was read from the file via the creation interface.
  1099. */
  1100. void DL_Dxf::addEllipse( DL_CreationInterface* creationInterface )
  1101. {
  1102. DL_EllipseData d( getRealValue( 10, 0.0 ),
  1103. getRealValue( 20, 0.0 ),
  1104. getRealValue( 30, 0.0 ),
  1105. getRealValue( 11, 0.0 ),
  1106. getRealValue( 21, 0.0 ),
  1107. getRealValue( 31, 0.0 ),
  1108. getRealValue( 40, 1.0 ),
  1109. getRealValue( 41, 0.0 ),
  1110. getRealValue( 42, 2 * M_PI ) );
  1111. creationInterface->addEllipse( d );
  1112. }
  1113. /**
  1114. * Adds an insert entity that was read from the file via the creation interface.
  1115. */
  1116. void DL_Dxf::addInsert( DL_CreationInterface* creationInterface )
  1117. {
  1118. // printf("addInsert\n");
  1119. // printf("code 50: %s\n", values[50]);
  1120. // printf("code 50 length: %d\n", strlen(values[50]));
  1121. // printf("code 50:\n");
  1122. // getRealValue(50, 0.0);
  1123. std::string name = getStringValue( 2, "" );
  1124. if( name.length()==0 )
  1125. {
  1126. return;
  1127. }
  1128. DL_InsertData d( name,
  1129. // insertion point
  1130. getRealValue( 10, 0.0 ),
  1131. getRealValue( 20, 0.0 ),
  1132. getRealValue( 30, 0.0 ),
  1133. // scale:
  1134. getRealValue( 41, 1.0 ),
  1135. getRealValue( 42, 1.0 ),
  1136. getRealValue( 43, 1.0 ),
  1137. // angle (deg):
  1138. getRealValue( 50, 0.0 ),
  1139. // cols / rows:
  1140. getIntValue( 70, 1 ),
  1141. getIntValue( 71, 1 ),
  1142. // spacing:
  1143. getRealValue( 44, 0.0 ),
  1144. getRealValue( 45, 0.0 ) );
  1145. creationInterface->addInsert( d );
  1146. }
  1147. /**
  1148. * Adds a trace entity (4 edge closed polyline) that was read from the file via the creation interface.
  1149. *
  1150. * @author AHM
  1151. */
  1152. void DL_Dxf::addTrace( DL_CreationInterface* creationInterface )
  1153. {
  1154. DL_TraceData td;
  1155. for( int k = 0; k < 4; k++ )
  1156. {
  1157. td.x[k] = getRealValue( 10 + k, 0.0 );
  1158. td.y[k] = getRealValue( 20 + k, 0.0 );
  1159. td.z[k] = getRealValue( 30 + k, 0.0 );
  1160. }
  1161. creationInterface->addTrace( td );
  1162. }
  1163. /**
  1164. * Adds a 3dface entity that was read from the file via the creation interface.
  1165. */
  1166. void DL_Dxf::add3dFace( DL_CreationInterface* creationInterface )
  1167. {
  1168. DL_3dFaceData td;
  1169. for( int k = 0; k < 4; k++ )
  1170. {
  1171. td.x[k] = getRealValue( 10 + k, 0.0 );
  1172. td.y[k] = getRealValue( 20 + k, 0.0 );
  1173. td.z[k] = getRealValue( 30 + k, 0.0 );
  1174. }
  1175. creationInterface->add3dFace( td );
  1176. }
  1177. /**
  1178. * Adds a solid entity (filled trace) that was read from the file via the creation interface.
  1179. *
  1180. * @author AHM
  1181. */
  1182. void DL_Dxf::addSolid( DL_CreationInterface* creationInterface )
  1183. {
  1184. DL_SolidData sd;
  1185. for( int k = 0; k < 4; k++ )
  1186. {
  1187. sd.x[k] = getRealValue( 10 + k, 0.0 );
  1188. sd.y[k] = getRealValue( 20 + k, 0.0 );
  1189. sd.z[k] = getRealValue( 30 + k, 0.0 );
  1190. }
  1191. creationInterface->addSolid( sd );
  1192. }
  1193. /**
  1194. * Adds an MText entity that was read from the file via the creation interface.
  1195. */
  1196. void DL_Dxf::addMText( DL_CreationInterface* creationInterface )
  1197. {
  1198. double angle = 0.0;
  1199. if( hasValue( 50 ) )
  1200. {
  1201. if( libVersion<=0x02000200 )
  1202. {
  1203. // wrong but compatible with dxflib <=2.0.2.0 (angle stored in rad):
  1204. angle = getRealValue( 50, 0.0 );
  1205. }
  1206. else
  1207. {
  1208. angle = (getRealValue( 50, 0.0 ) * 2 * M_PI) / 360.0;
  1209. }
  1210. }
  1211. else if( hasValue( 11 ) && hasValue( 21 ) )
  1212. {
  1213. double x = getRealValue( 11, 0.0 );
  1214. double y = getRealValue( 21, 0.0 );
  1215. if( fabs( x )<1.0e-6 )
  1216. {
  1217. if( y>0.0 )
  1218. {
  1219. angle = M_PI / 2.0;
  1220. }
  1221. else
  1222. {
  1223. angle = M_PI / 2.0 * 3.0;
  1224. }
  1225. }
  1226. else
  1227. {
  1228. angle = atan( y / x );
  1229. }
  1230. }
  1231. DL_MTextData d(
  1232. // insertion point
  1233. getRealValue( 10, 0.0 ),
  1234. getRealValue( 20, 0.0 ),
  1235. getRealValue( 30, 0.0 ),
  1236. // X direction vector
  1237. getRealValue( 11, 0.0 ),
  1238. getRealValue( 21, 0.0 ),
  1239. getRealValue( 31, 0.0 ),
  1240. // height
  1241. getRealValue( 40, 2.5 ),
  1242. // width
  1243. getRealValue( 41, 0.0 ),
  1244. // attachment point
  1245. getIntValue( 71, 1 ),
  1246. // drawing direction
  1247. getIntValue( 72, 1 ),
  1248. // line spacing style
  1249. getIntValue( 73, 1 ),
  1250. // line spacing factor
  1251. getRealValue( 44, 1.0 ),
  1252. // text
  1253. getStringValue( 1, "" ),
  1254. // style
  1255. getStringValue( 7, "" ),
  1256. // angle
  1257. angle );
  1258. creationInterface->addMText( d );
  1259. }
  1260. /**
  1261. * Handles all XRecord data.
  1262. */
  1263. bool DL_Dxf::handleXRecordData( DL_CreationInterface* creationInterface )
  1264. {
  1265. if( groupCode==105 )
  1266. {
  1267. return false;
  1268. }
  1269. if( groupCode==5 )
  1270. {
  1271. creationInterface->addXRecord( groupValue );
  1272. return true;
  1273. }
  1274. if( groupCode==280 )
  1275. {
  1276. xRecordValues = true;
  1277. return true;
  1278. }
  1279. if( !xRecordValues )
  1280. {
  1281. return false;
  1282. }
  1283. // string:
  1284. if( groupCode<=9
  1285. || groupCode==100 || groupCode==102 || groupCode==105
  1286. || (groupCode>=300 && groupCode<=369)
  1287. || (groupCode>=1000 && groupCode<=1009) )
  1288. {
  1289. creationInterface->addXRecordString( groupCode, groupValue );
  1290. return true;
  1291. }
  1292. // int:
  1293. else if( (groupCode>=60 && groupCode<=99) || (groupCode>=160 && groupCode<=179)
  1294. || (groupCode>=270 && groupCode<=289) )
  1295. {
  1296. creationInterface->addXRecordInt( groupCode, toInt( groupValue ) );
  1297. return true;
  1298. }
  1299. // bool:
  1300. else if( groupCode>=290 && groupCode<=299 )
  1301. {
  1302. creationInterface->addXRecordBool( groupCode, toBool( groupValue ) );
  1303. return true;
  1304. }
  1305. // double:
  1306. else if( (groupCode>=10 && groupCode<=59) || (groupCode>=110 && groupCode<=149)
  1307. || (groupCode>=210 && groupCode<=239) )
  1308. {
  1309. creationInterface->addXRecordReal( groupCode, toReal( groupValue ) );
  1310. return true;
  1311. }
  1312. return false;
  1313. }
  1314. /**
  1315. * Handles all dictionary data.
  1316. */
  1317. bool DL_Dxf::handleDictionaryData( DL_CreationInterface* creationInterface )
  1318. {
  1319. if( groupCode==3 )
  1320. {
  1321. return true;
  1322. }
  1323. if( groupCode==5 )
  1324. {
  1325. creationInterface->addDictionary( DL_DictionaryData( groupValue ) );
  1326. return true;
  1327. }
  1328. if( groupCode==350 )
  1329. {
  1330. creationInterface->addDictionaryEntry( DL_DictionaryEntryData( getStringValue( 3, "" ),
  1331. groupValue ) );
  1332. return true;
  1333. }
  1334. return false;
  1335. }
  1336. /**
  1337. * Handles XData for all object types.
  1338. */
  1339. bool DL_Dxf::handleXData( DL_CreationInterface* creationInterface )
  1340. {
  1341. if( groupCode==1001 )
  1342. {
  1343. creationInterface->addXDataApp( groupValue );
  1344. return true;
  1345. }
  1346. else if( groupCode>=1000 && groupCode<=1009 )
  1347. {
  1348. creationInterface->addXDataString( groupCode, groupValue );
  1349. return true;
  1350. }
  1351. else if( groupCode>=1010 && groupCode<=1059 )
  1352. {
  1353. creationInterface->addXDataReal( groupCode, toReal( groupValue ) );
  1354. return true;
  1355. }
  1356. else if( groupCode>=1060 && groupCode<=1070 )
  1357. {
  1358. creationInterface->addXDataInt( groupCode, toInt( groupValue ) );
  1359. return true;
  1360. }
  1361. else if( groupCode==1071 )
  1362. {
  1363. creationInterface->addXDataInt( groupCode, toInt( groupValue ) );
  1364. return true;
  1365. }
  1366. return false;
  1367. }
  1368. /**
  1369. * Handles additional MText data.
  1370. */
  1371. bool DL_Dxf::handleMTextData( DL_CreationInterface* creationInterface )
  1372. {
  1373. // Special handling of text chunks for MTEXT entities:
  1374. if( groupCode==3 )
  1375. {
  1376. creationInterface->addMTextChunk( groupValue );
  1377. return true;
  1378. }
  1379. return false;
  1380. }
  1381. /**
  1382. * Handles additional polyline data.
  1383. */
  1384. bool DL_Dxf::handleLWPolylineData( DL_CreationInterface* /*creationInterface*/ )
  1385. {
  1386. // Allocate LWPolyline vertices (group code 90):
  1387. if( groupCode==90 )
  1388. {
  1389. maxVertices = toInt( groupValue );
  1390. if( maxVertices>0 )
  1391. {
  1392. if( vertices!=NULL )
  1393. {
  1394. delete[] vertices;
  1395. }
  1396. vertices = new double[4 * maxVertices];
  1397. for( int i = 0; i<maxVertices; ++i )
  1398. {
  1399. vertices[i * 4] = 0.0;
  1400. vertices[i * 4 + 1] = 0.0;
  1401. vertices[i * 4 + 2] = 0.0;
  1402. vertices[i * 4 + 3] = 0.0;
  1403. }
  1404. }
  1405. vertexIndex = -1;
  1406. return true;
  1407. }
  1408. // Process LWPolylines vertices (group codes 10/20/30/42):
  1409. else if( groupCode==10 || groupCode==20
  1410. || groupCode==30 || groupCode==42 )
  1411. {
  1412. if( vertexIndex<maxVertices - 1 && groupCode==10 )
  1413. {
  1414. vertexIndex++;
  1415. }
  1416. if( groupCode<=30 )
  1417. {
  1418. if( vertexIndex>=0 && vertexIndex<maxVertices )
  1419. {
  1420. vertices[4 * vertexIndex + (groupCode / 10 - 1)] = toReal( groupValue );
  1421. }
  1422. }
  1423. else if( groupCode==42 && vertexIndex<maxVertices )
  1424. {
  1425. vertices[4 * vertexIndex + 3] = toReal( groupValue );
  1426. }
  1427. return true;
  1428. }
  1429. return false;
  1430. }
  1431. /**
  1432. * Handles additional spline data.
  1433. */
  1434. bool DL_Dxf::handleSplineData( DL_CreationInterface* /*creationInterface*/ )
  1435. {
  1436. // Allocate Spline knots (group code 72):
  1437. if( groupCode==72 )
  1438. {
  1439. maxKnots = toInt( groupValue );
  1440. if( maxKnots>0 )
  1441. {
  1442. if( knots!=NULL )
  1443. {
  1444. delete[] knots;
  1445. }
  1446. knots = new double[maxKnots];
  1447. for( int i = 0; i<maxKnots; ++i )
  1448. {
  1449. knots[i] = 0.0;
  1450. }
  1451. }
  1452. knotIndex = -1;
  1453. return true;
  1454. }
  1455. // Allocate Spline control points / weights (group code 73):
  1456. else if( groupCode==73 )
  1457. {
  1458. maxControlPoints = toInt( groupValue );
  1459. if( maxControlPoints>0 )
  1460. {
  1461. if( controlPoints!=NULL )
  1462. {
  1463. delete[] controlPoints;
  1464. }
  1465. if( weights!=NULL )
  1466. {
  1467. delete[] weights;
  1468. }
  1469. controlPoints = new double[3 * maxControlPoints];
  1470. weights = new double[maxControlPoints];
  1471. for( int i = 0; i<maxControlPoints; ++i )
  1472. {
  1473. controlPoints[i * 3] = 0.0;
  1474. controlPoints[i * 3 + 1] = 0.0;
  1475. controlPoints[i * 3 + 2] = 0.0;
  1476. weights[i] = 1.0;
  1477. }
  1478. }
  1479. controlPointIndex = -1;
  1480. weightIndex = -1;
  1481. return true;
  1482. }
  1483. // Allocate Spline fit points (group code 74):
  1484. else if( groupCode==74 )
  1485. {
  1486. maxFitPoints = toInt( groupValue );
  1487. if( maxFitPoints>0 )
  1488. {
  1489. if( fitPoints!=NULL )
  1490. {
  1491. delete[] fitPoints;
  1492. }
  1493. fitPoints = new double[3 * maxFitPoints];
  1494. for( int i = 0; i<maxFitPoints; ++i )
  1495. {
  1496. fitPoints[i * 3] = 0.0;
  1497. fitPoints[i * 3 + 1] = 0.0;
  1498. fitPoints[i * 3 + 2] = 0.0;
  1499. }
  1500. }
  1501. fitPointIndex = -1;
  1502. return true;
  1503. }
  1504. // Process spline knot vertices (group code 40):
  1505. else if( groupCode==40 )
  1506. {
  1507. if( knotIndex<maxKnots - 1 )
  1508. {
  1509. knotIndex++;
  1510. knots[knotIndex] = toReal( groupValue );
  1511. }
  1512. return true;
  1513. }
  1514. // Process spline control points (group codes 10/20/30):
  1515. else if( groupCode==10 || groupCode==20
  1516. || groupCode==30 )
  1517. {
  1518. if( controlPointIndex<maxControlPoints - 1 && groupCode==10 )
  1519. {
  1520. controlPointIndex++;
  1521. }
  1522. if( controlPointIndex>=0 && controlPointIndex<maxControlPoints )
  1523. {
  1524. controlPoints[3 * controlPointIndex + (groupCode / 10 - 1)] = toReal( groupValue );
  1525. }
  1526. return true;
  1527. }
  1528. // Process spline fit points (group codes 11/21/31):
  1529. else if( groupCode==11 || groupCode==21 || groupCode==31 )
  1530. {
  1531. if( fitPointIndex<maxFitPoints - 1 && groupCode==11 )
  1532. {
  1533. fitPointIndex++;
  1534. }
  1535. if( fitPointIndex>=0 && fitPointIndex<maxFitPoints )
  1536. {
  1537. fitPoints[3 * fitPointIndex + ( (groupCode - 1) / 10 - 1 )] = toReal( groupValue );
  1538. }
  1539. return true;
  1540. }
  1541. // Process spline weights (group code 41)
  1542. else if( groupCode==41 )
  1543. {
  1544. if( weightIndex<maxControlPoints - 1 )
  1545. {
  1546. weightIndex++;
  1547. }
  1548. if( weightIndex>=0 && weightIndex<maxControlPoints )
  1549. {
  1550. weights[weightIndex] = toReal( groupValue );
  1551. }
  1552. return true;
  1553. }
  1554. return false;
  1555. }
  1556. /**
  1557. * Handles additional leader data.
  1558. */
  1559. bool DL_Dxf::handleLeaderData( DL_CreationInterface* /*creationInterface*/ )
  1560. {
  1561. // Allocate Leader vertices (group code 76):
  1562. if( groupCode==76 )
  1563. {
  1564. maxLeaderVertices = toInt( groupValue );
  1565. if( maxLeaderVertices>0 )
  1566. {
  1567. if( leaderVertices!=NULL )
  1568. {
  1569. delete[] leaderVertices;
  1570. }
  1571. leaderVertices = new double[3 * maxLeaderVertices];
  1572. for( int i = 0; i<maxLeaderVertices; ++i )
  1573. {
  1574. leaderVertices[i * 3] = 0.0;
  1575. leaderVertices[i * 3 + 1] = 0.0;
  1576. leaderVertices[i * 3 + 2] = 0.0;
  1577. }
  1578. }
  1579. leaderVertexIndex = -1;
  1580. return true;
  1581. }
  1582. // Process Leader vertices (group codes 10/20/30):
  1583. else if( groupCode==10 || groupCode==20 || groupCode==30 )
  1584. {
  1585. if( leaderVertexIndex<maxLeaderVertices - 1 && groupCode==10 )
  1586. {
  1587. leaderVertexIndex++;
  1588. }
  1589. if( groupCode<=30 )
  1590. {
  1591. if( leaderVertexIndex>=0
  1592. && leaderVertexIndex<maxLeaderVertices )
  1593. {
  1594. leaderVertices[3 * leaderVertexIndex + (groupCode / 10 - 1)]
  1595. = toReal( groupValue );
  1596. }
  1597. }
  1598. return true;
  1599. }
  1600. return false;
  1601. }
  1602. /**
  1603. * Adds an text entity that was read from the file via the creation interface.
  1604. */
  1605. void DL_Dxf::addText( DL_CreationInterface* creationInterface )
  1606. {
  1607. DL_TextData d(
  1608. // insertion point
  1609. getRealValue( 10, 0.0 ),
  1610. getRealValue( 20, 0.0 ),
  1611. getRealValue( 30, 0.0 ),
  1612. // alignment point
  1613. getRealValue( 11, DL_NANDOUBLE ),
  1614. getRealValue( 21, DL_NANDOUBLE ),
  1615. getRealValue( 31, DL_NANDOUBLE ),
  1616. // height
  1617. getRealValue( 40, 2.5 ),
  1618. // x scale
  1619. getRealValue( 41, 1.0 ),
  1620. // generation flags
  1621. getIntValue( 71, 0 ),
  1622. // h just
  1623. getIntValue( 72, 0 ),
  1624. // v just
  1625. getIntValue( 73, 0 ),
  1626. // text
  1627. getStringValue( 1, "" ),
  1628. // style
  1629. getStringValue( 7, "" ),
  1630. // angle
  1631. (getRealValue( 50, 0.0 ) * 2 * M_PI) / 360.0 );
  1632. creationInterface->addText( d );
  1633. }
  1634. /**
  1635. * Adds an arc aligned text entity that was read from the file via the creation interface.
  1636. */
  1637. void DL_Dxf::addArcAlignedText( DL_CreationInterface* creationInterface )
  1638. {
  1639. DL_ArcAlignedTextData d;
  1640. d.text = getStringValue( 1, "" );
  1641. d.font = getStringValue( 2, "" );
  1642. d.style = getStringValue( 7, "" );
  1643. d.cx = getRealValue( 10, 0.0 );
  1644. d.cy = getRealValue( 20, 0.0 );
  1645. d.cz = getRealValue( 30, 0.0 );
  1646. d.radius = getRealValue( 40, 0.0 );
  1647. d.xScaleFactor = getRealValue( 41, 0.0 );
  1648. d.height = getRealValue( 42, 0.0 );
  1649. d.spacing = getRealValue( 43, 0.0 );
  1650. d.offset = getRealValue( 44, 0.0 );
  1651. d.rightOffset = getRealValue( 45, 0.0 );
  1652. d.leftOffset = getRealValue( 46, 0.0 );
  1653. d.startAngle = getRealValue( 50, 0.0 );
  1654. d.endAngle = getRealValue( 51, 0.0 );
  1655. d.reversedCharacterOrder = getIntValue( 70, 0 );
  1656. d.direction = getIntValue( 71, 0 );
  1657. d.alignment = getIntValue( 72, 0 );
  1658. d.side = getIntValue( 73, 0 );
  1659. d.bold = getIntValue( 74, 0 );
  1660. d.italic = getIntValue( 75, 0 );
  1661. d.underline = getIntValue( 76, 0 );
  1662. d.characerSet = getIntValue( 77, 0 );
  1663. d.pitch = getIntValue( 78, 0 );
  1664. d.shxFont = getIntValue( 79, 0 );
  1665. d.wizard = getIntValue( 280, 0 );
  1666. d.arcHandle = getIntValue( 330, 0 );
  1667. creationInterface->addArcAlignedText( d );
  1668. }
  1669. /**
  1670. * Adds an attrib entity that was read from the file via the creation interface.
  1671. * @todo add attrib instead of normal text
  1672. */
  1673. void DL_Dxf::addAttribute( DL_CreationInterface* creationInterface )
  1674. {
  1675. DL_AttributeData d(
  1676. // insertion point
  1677. getRealValue( 10, 0.0 ),
  1678. getRealValue( 20, 0.0 ),
  1679. getRealValue( 30, 0.0 ),
  1680. // alignment point
  1681. getRealValue( 11, 0.0 ),
  1682. getRealValue( 21, 0.0 ),
  1683. getRealValue( 31, 0.0 ),
  1684. // height
  1685. getRealValue( 40, 2.5 ),
  1686. // x scale
  1687. getRealValue( 41, 1.0 ),
  1688. // generation flags
  1689. getIntValue( 71, 0 ),
  1690. // h just
  1691. getIntValue( 72, 0 ),
  1692. // v just
  1693. getIntValue( 74, 0 ),
  1694. // tag
  1695. getStringValue( 2, "" ),
  1696. // text
  1697. getStringValue( 1, "" ),
  1698. // style
  1699. getStringValue( 7, "" ),
  1700. // angle
  1701. (getRealValue( 50, 0.0 ) * 2 * M_PI) / 360.0 );
  1702. creationInterface->addAttribute( d );
  1703. }
  1704. /**
  1705. * @return dimension data from current values.
  1706. */
  1707. DL_DimensionData DL_Dxf::getDimData()
  1708. {
  1709. // generic dimension data:
  1710. return DL_DimensionData(
  1711. // def point
  1712. getRealValue( 10, 0.0 ),
  1713. getRealValue( 20, 0.0 ),
  1714. getRealValue( 30, 0.0 ),
  1715. // text middle point
  1716. getRealValue( 11, 0.0 ),
  1717. getRealValue( 21, 0.0 ),
  1718. getRealValue( 31, 0.0 ),
  1719. // type
  1720. getIntValue( 70, 0 ),
  1721. // attachment point
  1722. getIntValue( 71, 5 ),
  1723. // line sp. style
  1724. getIntValue( 72, 1 ),
  1725. // line sp. factor
  1726. getRealValue( 41, 1.0 ),
  1727. // text
  1728. getStringValue( 1, "" ),
  1729. // style
  1730. getStringValue( 3, "" ),
  1731. // angle
  1732. getRealValue( 53, 0.0 ) );
  1733. }
  1734. /**
  1735. * Adds a linear dimension entity that was read from the file via the creation interface.
  1736. */
  1737. void DL_Dxf::addDimLinear( DL_CreationInterface* creationInterface )
  1738. {
  1739. DL_DimensionData d = getDimData();
  1740. // horizontal / vertical / rotated dimension:
  1741. DL_DimLinearData dl(
  1742. // definition point 1
  1743. getRealValue( 13, 0.0 ),
  1744. getRealValue( 23, 0.0 ),
  1745. getRealValue( 33, 0.0 ),
  1746. // definition point 2
  1747. getRealValue( 14, 0.0 ),
  1748. getRealValue( 24, 0.0 ),
  1749. getRealValue( 34, 0.0 ),
  1750. // angle
  1751. getRealValue( 50, 0.0 ),
  1752. // oblique
  1753. getRealValue( 52, 0.0 ) );
  1754. creationInterface->addDimLinear( d, dl );
  1755. }
  1756. /**
  1757. * Adds an aligned dimension entity that was read from the file via the creation interface.
  1758. */
  1759. void DL_Dxf::addDimAligned( DL_CreationInterface* creationInterface )
  1760. {
  1761. DL_DimensionData d = getDimData();
  1762. // aligned dimension:
  1763. DL_DimAlignedData da(
  1764. // extension point 1
  1765. getRealValue( 13, 0.0 ),
  1766. getRealValue( 23, 0.0 ),
  1767. getRealValue( 33, 0.0 ),
  1768. // extension point 2
  1769. getRealValue( 14, 0.0 ),
  1770. getRealValue( 24, 0.0 ),
  1771. getRealValue( 34, 0.0 ) );
  1772. creationInterface->addDimAlign( d, da );
  1773. }
  1774. /**
  1775. * Adds a radial dimension entity that was read from the file via the creation interface.
  1776. */
  1777. void DL_Dxf::addDimRadial( DL_CreationInterface* creationInterface )
  1778. {
  1779. DL_DimensionData d = getDimData();
  1780. DL_DimRadialData dr(
  1781. // definition point
  1782. getRealValue( 15, 0.0 ),
  1783. getRealValue( 25, 0.0 ),
  1784. getRealValue( 35, 0.0 ),
  1785. // leader length:
  1786. getRealValue( 40, 0.0 ) );
  1787. creationInterface->addDimRadial( d, dr );
  1788. }
  1789. /**
  1790. * Adds a diametric dimension entity that was read from the file via the creation interface.
  1791. */
  1792. void DL_Dxf::addDimDiametric( DL_CreationInterface* creationInterface )
  1793. {
  1794. DL_DimensionData d = getDimData();
  1795. // diametric dimension:
  1796. DL_DimDiametricData dr(
  1797. // definition point
  1798. getRealValue( 15, 0.0 ),
  1799. getRealValue( 25, 0.0 ),
  1800. getRealValue( 35, 0.0 ),
  1801. // leader length:
  1802. getRealValue( 40, 0.0 ) );
  1803. creationInterface->addDimDiametric( d, dr );
  1804. }
  1805. /**
  1806. * Adds an angular dimension entity that was read from the file via the creation interface.
  1807. */
  1808. void DL_Dxf::addDimAngular( DL_CreationInterface* creationInterface )
  1809. {
  1810. DL_DimensionData d = getDimData();
  1811. // angular dimension:
  1812. DL_DimAngularData da(
  1813. // definition point 1
  1814. getRealValue( 13, 0.0 ),
  1815. getRealValue( 23, 0.0 ),
  1816. getRealValue( 33, 0.0 ),
  1817. // definition point 2
  1818. getRealValue( 14, 0.0 ),
  1819. getRealValue( 24, 0.0 ),
  1820. getRealValue( 34, 0.0 ),
  1821. // definition point 3
  1822. getRealValue( 15, 0.0 ),
  1823. getRealValue( 25, 0.0 ),
  1824. getRealValue( 35, 0.0 ),
  1825. // definition point 4
  1826. getRealValue( 16, 0.0 ),
  1827. getRealValue( 26, 0.0 ),
  1828. getRealValue( 36, 0.0 ) );
  1829. creationInterface->addDimAngular( d, da );
  1830. }
  1831. /**
  1832. * Adds an angular dimension entity that was read from the file via the creation interface.
  1833. */
  1834. void DL_Dxf::addDimAngular3P( DL_CreationInterface* creationInterface )
  1835. {
  1836. DL_DimensionData d = getDimData();
  1837. // angular dimension (3P):
  1838. DL_DimAngular3PData da(
  1839. // definition point 1
  1840. getRealValue( 13, 0.0 ),
  1841. getRealValue( 23, 0.0 ),
  1842. getRealValue( 33, 0.0 ),
  1843. // definition point 2
  1844. getRealValue( 14, 0.0 ),
  1845. getRealValue( 24, 0.0 ),
  1846. getRealValue( 34, 0.0 ),
  1847. // definition point 3
  1848. getRealValue( 15, 0.0 ),
  1849. getRealValue( 25, 0.0 ),
  1850. getRealValue( 35, 0.0 ) );
  1851. creationInterface->addDimAngular3P( d, da );
  1852. }
  1853. /**
  1854. * Adds an ordinate dimension entity that was read from the file via the creation interface.
  1855. */
  1856. void DL_Dxf::addDimOrdinate( DL_CreationInterface* creationInterface )
  1857. {
  1858. DL_DimensionData d = getDimData();
  1859. // ordinate dimension:
  1860. DL_DimOrdinateData dl(
  1861. // definition point 1
  1862. getRealValue( 13, 0.0 ),
  1863. getRealValue( 23, 0.0 ),
  1864. getRealValue( 33, 0.0 ),
  1865. // definition point 2
  1866. getRealValue( 14, 0.0 ),
  1867. getRealValue( 24, 0.0 ),
  1868. getRealValue( 34, 0.0 ),
  1869. (getIntValue( 70, 0 ) & 64)==64 // true: X-type, false: Y-type
  1870. );
  1871. creationInterface->addDimOrdinate( d, dl );
  1872. }
  1873. /**
  1874. * Adds a leader entity that was read from the file via the creation interface.
  1875. */
  1876. void DL_Dxf::addLeader( DL_CreationInterface* creationInterface )
  1877. {
  1878. // leader (arrow)
  1879. DL_LeaderData le(
  1880. // arrow head flag
  1881. getIntValue( 71, 1 ),
  1882. // leader path type
  1883. getIntValue( 72, 0 ),
  1884. // Leader creation flag
  1885. getIntValue( 73, 3 ),
  1886. // Hookline direction flag
  1887. getIntValue( 74, 1 ),
  1888. // Hookline flag
  1889. getIntValue( 75, 0 ),
  1890. // Text annotation height
  1891. getRealValue( 40, 1.0 ),
  1892. // Text annotation width
  1893. getRealValue( 41, 1.0 ),
  1894. // Number of vertices in leader
  1895. getIntValue( 76, 0 )
  1896. );
  1897. creationInterface->addLeader( le );
  1898. for( int i = 0; i<maxLeaderVertices; i++ )
  1899. {
  1900. DL_LeaderVertexData d( leaderVertices[i * 3],
  1901. leaderVertices[i * 3 + 1],
  1902. leaderVertices[i * 3 + 2] );
  1903. creationInterface->addLeaderVertex( d );
  1904. }
  1905. creationInterface->endEntity();
  1906. }
  1907. /**
  1908. * Adds a hatch entity that was read from the file via the creation interface.
  1909. */
  1910. void DL_Dxf::addHatch( DL_CreationInterface* creationInterface )
  1911. {
  1912. DL_HatchData hd( getIntValue( 91, 1 ),
  1913. getIntValue( 70, 0 ),
  1914. getRealValue( 41, 1.0 ),
  1915. getRealValue( 52, 0.0 ),
  1916. getStringValue( 2, "" ) );
  1917. creationInterface->addHatch( hd );
  1918. for( unsigned int i = 0; i<hatchEdges.size(); i++ )
  1919. {
  1920. creationInterface->addHatchLoop( DL_HatchLoopData( hatchEdges[i].size() ) );
  1921. for( unsigned int k = 0; k<hatchEdges[i].size(); k++ )
  1922. {
  1923. creationInterface->addHatchEdge( DL_HatchEdgeData( hatchEdges[i][k] ) );
  1924. }
  1925. }
  1926. creationInterface->endEntity();
  1927. }
  1928. void DL_Dxf::addHatchLoop()
  1929. {
  1930. addHatchEdge();
  1931. hatchEdges.push_back( std::vector<DL_HatchEdgeData>() );
  1932. }
  1933. void DL_Dxf::addHatchEdge()
  1934. {
  1935. if( hatchEdge.defined )
  1936. {
  1937. if( hatchEdges.size()>0 )
  1938. {
  1939. hatchEdges.back().push_back( hatchEdge );
  1940. }
  1941. hatchEdge = DL_HatchEdgeData();
  1942. }
  1943. }
  1944. /**
  1945. * Handles all hatch data.
  1946. */
  1947. bool DL_Dxf::handleHatchData( DL_CreationInterface* creationInterface )
  1948. {
  1949. // New polyline loop, group code 92
  1950. // or new loop with individual edges, group code 93
  1951. if( groupCode==92 || groupCode==93 )
  1952. {
  1953. if( firstHatchLoop )
  1954. {
  1955. hatchEdges.clear();
  1956. firstHatchLoop = false;
  1957. }
  1958. if( groupCode==92 && (toInt( groupValue ) & 2)==2 )
  1959. {
  1960. addHatchLoop();
  1961. }
  1962. if( groupCode==93 )
  1963. {
  1964. addHatchLoop();
  1965. }
  1966. return true;
  1967. }
  1968. // New hatch edge or new section / entity: add last hatch edge:
  1969. if( groupCode==72 || groupCode==0 || groupCode==78 || groupCode==98 )
  1970. {
  1971. // polyline boundaries use code 72 for bulge flag:
  1972. if( groupCode!=72 || (getIntValue( 92, 0 ) & 2)==0 )
  1973. {
  1974. addHatchEdge();
  1975. }
  1976. if( groupCode==0 /*|| groupCode==78*/ )
  1977. {
  1978. addHatch( creationInterface );
  1979. }
  1980. else
  1981. {
  1982. hatchEdge.type = toInt( groupValue );
  1983. }
  1984. return true;
  1985. }
  1986. // polyline boundary:
  1987. if( (getIntValue( 92, 0 ) & 2)==2 )
  1988. {
  1989. switch( groupCode )
  1990. {
  1991. case 10:
  1992. hatchEdge.type = 0;
  1993. hatchEdge.vertices.push_back( std::vector<double>() );
  1994. hatchEdge.vertices.back().push_back( toReal( groupValue ) );
  1995. return true;
  1996. case 20:
  1997. if( !hatchEdge.vertices.empty() )
  1998. {
  1999. hatchEdge.vertices.back().push_back( toReal( groupValue ) );
  2000. hatchEdge.defined = true;
  2001. }
  2002. return true;
  2003. case 42:
  2004. if( !hatchEdge.vertices.empty() )
  2005. {
  2006. hatchEdge.vertices.back().push_back( toReal( groupValue ) );
  2007. hatchEdge.defined = true;
  2008. }
  2009. return true;
  2010. }
  2011. }
  2012. else
  2013. {
  2014. // Line edge:
  2015. if( hatchEdge.type==1 )
  2016. {
  2017. switch( groupCode )
  2018. {
  2019. case 10:
  2020. hatchEdge.x1 = toReal( groupValue );
  2021. return true;
  2022. case 20:
  2023. hatchEdge.y1 = toReal( groupValue );
  2024. return true;
  2025. case 11:
  2026. hatchEdge.x2 = toReal( groupValue );
  2027. return true;
  2028. case 21:
  2029. hatchEdge.y2 = toReal( groupValue );
  2030. hatchEdge.defined = true;
  2031. return true;
  2032. }
  2033. }
  2034. // Arc edge:
  2035. if( hatchEdge.type==2 )
  2036. {
  2037. switch( groupCode )
  2038. {
  2039. case 10:
  2040. hatchEdge.cx = toReal( groupValue );
  2041. return true;
  2042. case 20:
  2043. hatchEdge.cy = toReal( groupValue );
  2044. return true;
  2045. case 40:
  2046. hatchEdge.radius = toReal( groupValue );
  2047. return true;
  2048. case 50:
  2049. hatchEdge.angle1 = toReal( groupValue ) / 360.0 * 2 * M_PI;
  2050. return true;
  2051. case 51:
  2052. hatchEdge.angle2 = toReal( groupValue ) / 360.0 * 2 * M_PI;
  2053. return true;
  2054. case 73:
  2055. hatchEdge.ccw = (bool) toInt( groupValue );
  2056. hatchEdge.defined = true;
  2057. return true;
  2058. }
  2059. }
  2060. // Ellipse arc edge:
  2061. if( hatchEdge.type==3 )
  2062. {
  2063. switch( groupCode )
  2064. {
  2065. case 10:
  2066. hatchEdge.cx = toReal( groupValue );
  2067. return true;
  2068. case 20:
  2069. hatchEdge.cy = toReal( groupValue );
  2070. return true;
  2071. case 11:
  2072. hatchEdge.mx = toReal( groupValue );
  2073. return true;
  2074. case 21:
  2075. hatchEdge.my = toReal( groupValue );
  2076. return true;
  2077. case 40:
  2078. hatchEdge.ratio = toReal( groupValue );
  2079. return true;
  2080. case 50:
  2081. hatchEdge.angle1 = toReal( groupValue ) / 360.0 * 2 * M_PI;
  2082. return true;
  2083. case 51:
  2084. hatchEdge.angle2 = toReal( groupValue ) / 360.0 * 2 * M_PI;
  2085. return true;
  2086. case 73:
  2087. hatchEdge.ccw = (bool) toInt( groupValue );
  2088. hatchEdge.defined = true;
  2089. return true;
  2090. }
  2091. }
  2092. // Spline edge:
  2093. if( hatchEdge.type==4 )
  2094. {
  2095. switch( groupCode )
  2096. {
  2097. case 94:
  2098. hatchEdge.degree = toInt( groupValue );
  2099. return true;
  2100. case 73:
  2101. hatchEdge.rational = toBool( groupValue );
  2102. return true;
  2103. case 74:
  2104. hatchEdge.periodic = toBool( groupValue );
  2105. return true;
  2106. case 95:
  2107. hatchEdge.nKnots = toInt( groupValue );
  2108. return true;
  2109. case 96:
  2110. hatchEdge.nControl = toInt( groupValue );
  2111. return true;
  2112. case 97:
  2113. hatchEdge.nFit = toInt( groupValue );
  2114. return true;
  2115. case 40:
  2116. if( hatchEdge.knots.size() < hatchEdge.nKnots )
  2117. {
  2118. hatchEdge.knots.push_back( toReal( groupValue ) );
  2119. }
  2120. return true;
  2121. case 10:
  2122. if( hatchEdge.controlPoints.size() < hatchEdge.nControl )
  2123. {
  2124. std::vector<double> v;
  2125. v.push_back( toReal( groupValue ) );
  2126. hatchEdge.controlPoints.push_back( v );
  2127. }
  2128. return true;
  2129. case 20:
  2130. if( !hatchEdge.controlPoints.empty() && hatchEdge.controlPoints.back().size()==1 )
  2131. {
  2132. hatchEdge.controlPoints.back().push_back( toReal( groupValue ) );
  2133. }
  2134. hatchEdge.defined = true;
  2135. return true;
  2136. case 42:
  2137. if( hatchEdge.weights.size() < hatchEdge.nControl )
  2138. {
  2139. hatchEdge.weights.push_back( toReal( groupValue ) );
  2140. }
  2141. return true;
  2142. case 11:
  2143. if( hatchEdge.fitPoints.size() < hatchEdge.nFit )
  2144. {
  2145. std::vector<double> v;
  2146. v.push_back( toReal( groupValue ) );
  2147. hatchEdge.fitPoints.push_back( v );
  2148. }
  2149. return true;
  2150. case 21:
  2151. if( !hatchEdge.fitPoints.empty() && hatchEdge.fitPoints.back().size()==1 )
  2152. {
  2153. hatchEdge.fitPoints.back().push_back( toReal( groupValue ) );
  2154. }
  2155. hatchEdge.defined = true;
  2156. return true;
  2157. case 12:
  2158. hatchEdge.startTangentX = toReal( groupValue );
  2159. return true;
  2160. case 22:
  2161. hatchEdge.startTangentY = toReal( groupValue );
  2162. return true;
  2163. case 13:
  2164. hatchEdge.endTangentX = toReal( groupValue );
  2165. return true;
  2166. case 23:
  2167. hatchEdge.endTangentY = toReal( groupValue );
  2168. return true;
  2169. }
  2170. }
  2171. }
  2172. return false;
  2173. }
  2174. /**
  2175. * Adds an image entity that was read from the file via the creation interface.
  2176. */
  2177. void DL_Dxf::addImage( DL_CreationInterface* creationInterface )
  2178. {
  2179. DL_ImageData id( // pass ref insead of name we don't have yet
  2180. getStringValue( 340, "" ),
  2181. // ins point:
  2182. getRealValue( 10, 0.0 ),
  2183. getRealValue( 20, 0.0 ),
  2184. getRealValue( 30, 0.0 ),
  2185. // u vector:
  2186. getRealValue( 11, 1.0 ),
  2187. getRealValue( 21, 0.0 ),
  2188. getRealValue( 31, 0.0 ),
  2189. // v vector:
  2190. getRealValue( 12, 0.0 ),
  2191. getRealValue( 22, 1.0 ),
  2192. getRealValue( 32, 0.0 ),
  2193. // image size (pixel):
  2194. getIntValue( 13, 1 ),
  2195. getIntValue( 23, 1 ),
  2196. // brightness, contrast, fade
  2197. getIntValue( 281, 50 ),
  2198. getIntValue( 282, 50 ),
  2199. getIntValue( 283, 0 ) );
  2200. creationInterface->addImage( id );
  2201. creationInterface->endEntity();
  2202. currentObjectType = DL_UNKNOWN;
  2203. }
  2204. /**
  2205. * Adds an image definition that was read from the file via the creation interface.
  2206. */
  2207. void DL_Dxf::addImageDef( DL_CreationInterface* creationInterface )
  2208. {
  2209. DL_ImageDefData id( // handle
  2210. getStringValue( 5, "" ),
  2211. getStringValue( 1, "" ) );
  2212. creationInterface->linkImage( id );
  2213. creationInterface->endEntity();
  2214. currentObjectType = DL_UNKNOWN;
  2215. }
  2216. /**
  2217. * Ends some special entities like hatches or old style polylines.
  2218. */
  2219. void DL_Dxf::endEntity( DL_CreationInterface* creationInterface )
  2220. {
  2221. creationInterface->endEntity();
  2222. }
  2223. /**
  2224. * Ends a sequence and notifies the creation interface.
  2225. */
  2226. void DL_Dxf::endSequence( DL_CreationInterface* creationInterface )
  2227. {
  2228. creationInterface->endSequence();
  2229. }
  2230. /**
  2231. * Converts the given string into an int.
  2232. * ok is set to false if there was an error.
  2233. */
  2234. // int DL_Dxf::stringToInt(const char* s, bool* ok) {
  2235. // if (ok!=NULL) {
  2236. //// check string:
  2237. // *ok = true;
  2238. // int i=0;
  2239. // bool dot = false;
  2240. // do {
  2241. // if (s[i]=='\0') {
  2242. // break;
  2243. // } else if (s[i]=='.') {
  2244. // if (dot==true) {
  2245. ////std::cerr << "two dots\n";
  2246. // *ok = false;
  2247. // } else {
  2248. // dot = true;
  2249. // }
  2250. // } else if (s[i]<'0' || s[i]>'9') {
  2251. ////std::cerr << "NaN: '" << s[i] << "'\n";
  2252. // *ok = false;
  2253. // }
  2254. // i++;
  2255. // } while(s[i]!='\0' && *ok==true);
  2256. // }
  2257. // return atoi(s);
  2258. // }
  2259. /**
  2260. * @brief Opens the given file for writing and returns a pointer
  2261. * to the dxf writer. This pointer needs to be passed on to other
  2262. * writing functions.
  2263. *
  2264. * @param file Full path of the file to open.
  2265. *
  2266. * @return Pointer to an ascii dxf writer object.
  2267. */
  2268. DL_WriterA* DL_Dxf::out( const char* file, DL_Codes::version aVersion )
  2269. {
  2270. char* f = new char[strlen( file ) + 1];
  2271. strcpy( f, file );
  2272. this->version = aVersion;
  2273. DL_WriterA* dw = new DL_WriterA( f, aVersion );
  2274. if( dw->openFailed() )
  2275. {
  2276. delete dw;
  2277. delete[] f;
  2278. return NULL;
  2279. }
  2280. else
  2281. {
  2282. delete[] f;
  2283. return dw;
  2284. }
  2285. }
  2286. /**
  2287. * @brief Writes a DXF header to the file currently opened
  2288. * by the given DXF writer object.
  2289. */
  2290. void DL_Dxf::writeHeader( DL_WriterA& dw )
  2291. {
  2292. dw.comment( "dxflib " DL_VERSION );
  2293. dw.sectionHeader();
  2294. dw.dxfString( 9, "$ACADVER" );
  2295. switch( version )
  2296. {
  2297. case DL_Codes::AC1009:
  2298. dw.dxfString( 1, "AC1009" );
  2299. break;
  2300. case DL_Codes::AC1012:
  2301. dw.dxfString( 1, "AC1012" );
  2302. break;
  2303. case DL_Codes::AC1014:
  2304. dw.dxfString( 1, "AC1014" );
  2305. break;
  2306. case DL_Codes::AC1015:
  2307. dw.dxfString( 1, "AC1015" );
  2308. break;
  2309. case DL_Codes::AC1009_MIN:
  2310. // minimalistic DXF version is unidentified in file:
  2311. break;
  2312. }
  2313. // Newer version require that (otherwise a*cad crashes..)
  2314. if( version==DL_VERSION_2000 )
  2315. {
  2316. dw.dxfString( 9, "$HANDSEED" );
  2317. dw.dxfHex( 5, 0xFFFF );
  2318. }
  2319. // commented out: more variables can be added after that by caller:
  2320. // dw.sectionEnd();
  2321. }
  2322. /**
  2323. * Writes a point entity to the file.
  2324. *
  2325. * @param dw DXF writer
  2326. * @param data Entity data from the file
  2327. * @param aAttrib Attributes
  2328. */
  2329. void DL_Dxf::writePoint( DL_WriterA& dw,
  2330. const DL_PointData& data,
  2331. const DL_Attributes& aAttrib )
  2332. {
  2333. dw.entity( "POINT" );
  2334. if( version==DL_VERSION_2000 )
  2335. {
  2336. dw.dxfString( 100, "AcDbEntity" );
  2337. }
  2338. dw.entityAttributes( aAttrib );
  2339. if( version==DL_VERSION_2000 )
  2340. {
  2341. dw.dxfString( 100, "AcDbPoint" );
  2342. }
  2343. dw.coord( DL_POINT_COORD_CODE, data.x, data.y, data.z );
  2344. }
  2345. /**
  2346. * Writes a line entity to the file.
  2347. *
  2348. * @param dw DXF writer
  2349. * @param data Entity data from the file
  2350. * @param aAttrib Attributes
  2351. */
  2352. void DL_Dxf::writeLine( DL_WriterA& dw,
  2353. const DL_LineData& data,
  2354. const DL_Attributes& aAttrib )
  2355. {
  2356. dw.entity( "LINE" );
  2357. if( version==DL_VERSION_2000 )
  2358. {
  2359. dw.dxfString( 100, "AcDbEntity" );
  2360. }
  2361. dw.entityAttributes( aAttrib );
  2362. if( version==DL_VERSION_2000 )
  2363. {
  2364. dw.dxfString( 100, "AcDbLine" );
  2365. }
  2366. dw.coord( DL_LINE_START_CODE, data.x1, data.y1, data.z1 );
  2367. dw.coord( DL_LINE_END_CODE, data.x2, data.y2, data.z2 );
  2368. }
  2369. /**
  2370. * Writes an x line entity to the file.
  2371. *
  2372. * @param dw DXF writer
  2373. * @param data Entity data from the file
  2374. * @param aAttrib Attributes
  2375. */
  2376. void DL_Dxf::writeXLine( DL_WriterA& dw,
  2377. const DL_XLineData& data,
  2378. const DL_Attributes& aAttrib )
  2379. {
  2380. dw.entity( "XLINE" );
  2381. if( version==DL_VERSION_2000 )
  2382. {
  2383. dw.dxfString( 100, "AcDbEntity" );
  2384. }
  2385. dw.entityAttributes( aAttrib );
  2386. if( version==DL_VERSION_2000 )
  2387. {
  2388. dw.dxfString( 100, "AcDbLine" );
  2389. }
  2390. dw.coord( DL_LINE_START_CODE, data.bx, data.by, data.bz );
  2391. dw.coord( DL_LINE_END_CODE, data.dx, data.dy, data.dz );
  2392. }
  2393. /**
  2394. * Writes a ray entity to the file.
  2395. *
  2396. * @param dw DXF writer
  2397. * @param data Entity data from the file
  2398. * @param aAttrib Attributes
  2399. */
  2400. void DL_Dxf::writeRay( DL_WriterA& dw,
  2401. const DL_RayData& data,
  2402. const DL_Attributes& aAttrib )
  2403. {
  2404. dw.entity( "RAY" );
  2405. if( version==DL_VERSION_2000 )
  2406. {
  2407. dw.dxfString( 100, "AcDbEntity" );
  2408. }
  2409. dw.entityAttributes( aAttrib );
  2410. if( version==DL_VERSION_2000 )
  2411. {
  2412. dw.dxfString( 100, "AcDbLine" );
  2413. }
  2414. dw.coord( DL_LINE_START_CODE, data.bx, data.by, data.bz );
  2415. dw.coord( DL_LINE_END_CODE, data.dx, data.dy, data.dz );
  2416. }
  2417. /**
  2418. * Writes a polyline entity to the file.
  2419. *
  2420. * @param dw DXF writer
  2421. * @param data Entity data from the file
  2422. * @param aAttrib Attributes
  2423. * @see writeVertex
  2424. */
  2425. void DL_Dxf::writePolyline( DL_WriterA& dw,
  2426. const DL_PolylineData& data,
  2427. const DL_Attributes& aAttrib )
  2428. {
  2429. if( version==DL_VERSION_2000 )
  2430. {
  2431. dw.entity( "LWPOLYLINE" );
  2432. dw.dxfString( 100, "AcDbEntity" );
  2433. dw.entityAttributes( attrib );
  2434. dw.dxfString( 100, "AcDbPolyline" );
  2435. dw.dxfInt( 90, (int) data.number );
  2436. dw.dxfInt( 70, data.flags );
  2437. }
  2438. else
  2439. {
  2440. dw.entity( "POLYLINE" );
  2441. dw.entityAttributes( attrib );
  2442. polylineLayer = attrib.getLayer();
  2443. dw.dxfInt( 66, 1 );
  2444. dw.dxfInt( 70, data.flags );
  2445. dw.coord( DL_VERTEX_COORD_CODE, 0.0, 0.0, 0.0 );
  2446. }
  2447. }
  2448. /**
  2449. * Writes a single vertex of a polyline to the file.
  2450. *
  2451. * @param dw DXF writer
  2452. * @param data Entity data from the file
  2453. * @param aAttrib Attributes
  2454. */
  2455. void DL_Dxf::writeVertex( DL_WriterA& dw,
  2456. const DL_VertexData& data )
  2457. {
  2458. if( version==DL_VERSION_2000 )
  2459. {
  2460. dw.dxfReal( 10, data.x );
  2461. dw.dxfReal( 20, data.y );
  2462. dw.dxfReal( 30, data.z );
  2463. if( fabs( data.bulge )>1.0e-10 )
  2464. {
  2465. dw.dxfReal( 42, data.bulge );
  2466. }
  2467. }
  2468. else
  2469. {
  2470. dw.entity( "VERTEX" );
  2471. // dw.entityAttributes(aAttrib);
  2472. dw.dxfString( 8, polylineLayer );
  2473. dw.coord( DL_VERTEX_COORD_CODE, data.x, data.y, data.z );
  2474. if( fabs( data.bulge )>1.0e-10 )
  2475. {
  2476. dw.dxfReal( 42, data.bulge );
  2477. }
  2478. }
  2479. }
  2480. /**
  2481. * Writes the polyline end. Only needed for DXF R12.
  2482. */
  2483. void DL_Dxf::writePolylineEnd( DL_WriterA& dw )
  2484. {
  2485. if( version==DL_VERSION_2000 )
  2486. {
  2487. }
  2488. else
  2489. {
  2490. dw.entity( "SEQEND" );
  2491. }
  2492. }
  2493. /**
  2494. * Writes a spline entity to the file.
  2495. *
  2496. * @param dw DXF writer
  2497. * @param data Entity data from the file
  2498. * @param aAttrib Attributes
  2499. * @see writeControlPoint
  2500. */
  2501. void DL_Dxf::writeSpline( DL_WriterA& dw,
  2502. const DL_SplineData& data,
  2503. const DL_Attributes& aAttrib )
  2504. {
  2505. dw.entity( "SPLINE" );
  2506. if( version==DL_VERSION_2000 )
  2507. {
  2508. dw.dxfString( 100, "AcDbEntity" );
  2509. }
  2510. dw.entityAttributes( aAttrib );
  2511. if( version==DL_VERSION_2000 )
  2512. {
  2513. dw.dxfString( 100, "AcDbSpline" );
  2514. }
  2515. dw.dxfInt( 70, data.flags );
  2516. dw.dxfInt( 71, data.degree );
  2517. dw.dxfInt( 72, data.nKnots ); // number of knots
  2518. dw.dxfInt( 73, data.nControl ); // number of control points
  2519. dw.dxfInt( 74, data.nFit ); // number of fit points
  2520. }
  2521. /**
  2522. * Writes a single control point of a spline to the file.
  2523. *
  2524. * @param dw DXF writer
  2525. * @param data Entity data from the file
  2526. * @param aAttrib Attributes
  2527. */
  2528. void DL_Dxf::writeControlPoint( DL_WriterA& dw,
  2529. const DL_ControlPointData& data )
  2530. {
  2531. dw.dxfReal( 10, data.x );
  2532. dw.dxfReal( 20, data.y );
  2533. dw.dxfReal( 30, data.z );
  2534. }
  2535. /**
  2536. * Writes a single fit point of a spline to the file.
  2537. *
  2538. * @param dw DXF writer
  2539. * @param data Entity data from the file
  2540. */
  2541. void DL_Dxf::writeFitPoint( DL_WriterA& dw,
  2542. const DL_FitPointData& data )
  2543. {
  2544. dw.dxfReal( 11, data.x );
  2545. dw.dxfReal( 21, data.y );
  2546. dw.dxfReal( 31, data.z );
  2547. }
  2548. /**
  2549. * Writes a single knot of a spline to the file.
  2550. *
  2551. * @param dw DXF writer
  2552. * @param data Entity data from the file
  2553. */
  2554. void DL_Dxf::writeKnot( DL_WriterA& dw,
  2555. const DL_KnotData& data )
  2556. {
  2557. dw.dxfReal( 40, data.k );
  2558. }
  2559. /**
  2560. * Writes a circle entity to the file.
  2561. *
  2562. * @param dw DXF writer
  2563. * @param data Entity data from the file
  2564. * @param aAttrib Attributes
  2565. */
  2566. void DL_Dxf::writeCircle( DL_WriterA& dw,
  2567. const DL_CircleData& data,
  2568. const DL_Attributes& aAttrib )
  2569. {
  2570. dw.entity( "CIRCLE" );
  2571. if( version==DL_VERSION_2000 )
  2572. {
  2573. dw.dxfString( 100, "AcDbEntity" );
  2574. }
  2575. dw.entityAttributes( aAttrib );
  2576. if( version==DL_VERSION_2000 )
  2577. {
  2578. dw.dxfString( 100, "AcDbCircle" );
  2579. }
  2580. dw.coord( 10, data.cx, data.cy, data.cz );
  2581. dw.dxfReal( 40, data.radius );
  2582. }
  2583. /**
  2584. * Writes an arc entity to the file.
  2585. *
  2586. * @param dw DXF writer
  2587. * @param data Entity data from the file
  2588. * @param aAttrib Attributes
  2589. */
  2590. void DL_Dxf::writeArc( DL_WriterA& dw,
  2591. const DL_ArcData& data,
  2592. const DL_Attributes& aAttrib )
  2593. {
  2594. dw.entity( "ARC" );
  2595. if( version==DL_VERSION_2000 )
  2596. {
  2597. dw.dxfString( 100, "AcDbEntity" );
  2598. }
  2599. dw.entityAttributes( aAttrib );
  2600. if( version==DL_VERSION_2000 )
  2601. {
  2602. dw.dxfString( 100, "AcDbCircle" );
  2603. }
  2604. dw.coord( 10, data.cx, data.cy, data.cz );
  2605. dw.dxfReal( 40, data.radius );
  2606. if( version==DL_VERSION_2000 )
  2607. {
  2608. dw.dxfString( 100, "AcDbArc" );
  2609. }
  2610. dw.dxfReal( 50, data.angle1 );
  2611. dw.dxfReal( 51, data.angle2 );
  2612. }
  2613. /**
  2614. * Writes an ellipse entity to the file.
  2615. *
  2616. * @param dw DXF writer
  2617. * @param data Entity data from the file
  2618. * @param aAttrib Attributes
  2619. */
  2620. void DL_Dxf::writeEllipse( DL_WriterA& dw,
  2621. const DL_EllipseData& data,
  2622. const DL_Attributes& aAttrib )
  2623. {
  2624. if( version>DL_VERSION_R12 )
  2625. {
  2626. dw.entity( "ELLIPSE" );
  2627. if( version==DL_VERSION_2000 )
  2628. {
  2629. dw.dxfString( 100, "AcDbEntity" );
  2630. }
  2631. dw.entityAttributes( aAttrib );
  2632. if( version==DL_VERSION_2000 )
  2633. {
  2634. dw.dxfString( 100, "AcDbEllipse" );
  2635. }
  2636. dw.coord( 10, data.cx, data.cy, data.cz );
  2637. dw.coord( 11, data.mx, data.my, data.mz );
  2638. dw.dxfReal( 40, data.ratio );
  2639. dw.dxfReal( 41, data.angle1 );
  2640. dw.dxfReal( 42, data.angle2 );
  2641. }
  2642. }
  2643. /**
  2644. * Writes a solid entity to the file.
  2645. *
  2646. * @param dw DXF writer
  2647. * @param data Entity data from the file
  2648. * @param aAttrib Attributes
  2649. */
  2650. void DL_Dxf::writeSolid( DL_WriterA& dw,
  2651. const DL_SolidData& data,
  2652. const DL_Attributes& aAttrib )
  2653. {
  2654. dw.entity( "SOLID" );
  2655. if( version==DL_VERSION_2000 )
  2656. {
  2657. dw.dxfString( 100, "AcDbEntity" );
  2658. }
  2659. dw.entityAttributes( aAttrib );
  2660. if( version==DL_VERSION_2000 )
  2661. {
  2662. dw.dxfString( 100, "AcDbTrace" );
  2663. }
  2664. dw.coord( 10, data.x[0], data.y[0], data.z[0] );
  2665. dw.coord( 11, data.x[1], data.y[1], data.z[1] );
  2666. dw.coord( 12, data.x[2], data.y[2], data.z[2] );
  2667. dw.coord( 13, data.x[3], data.y[3], data.z[3] );
  2668. dw.dxfReal( 39, data.thickness );
  2669. }
  2670. /**
  2671. * Writes a trace entity to the file.
  2672. *
  2673. * @param dw DXF writer
  2674. * @param data Entity data from the file
  2675. * @param aAttrib Attributes
  2676. */
  2677. void DL_Dxf::writeTrace( DL_WriterA& dw,
  2678. const DL_TraceData& data,
  2679. const DL_Attributes& aAttrib )
  2680. {
  2681. dw.entity( "TRACE" );
  2682. if( version==DL_VERSION_2000 )
  2683. {
  2684. dw.dxfString( 100, "AcDbEntity" );
  2685. }
  2686. dw.entityAttributes( aAttrib );
  2687. if( version==DL_VERSION_2000 )
  2688. {
  2689. dw.dxfString( 100, "AcDbTrace" );
  2690. }
  2691. dw.coord( 10, data.x[0], data.y[0], data.z[0] );
  2692. dw.coord( 11, data.x[1], data.y[1], data.z[1] );
  2693. dw.coord( 12, data.x[2], data.y[2], data.z[2] );
  2694. dw.coord( 13, data.x[3], data.y[3], data.z[3] );
  2695. dw.dxfReal( 39, data.thickness );
  2696. }
  2697. /**
  2698. * Writes a 3d face entity to the file.
  2699. *
  2700. * @param dw DXF writer
  2701. * @param data Entity data from the file
  2702. * @param aAttrib Attributes
  2703. */
  2704. void DL_Dxf::write3dFace( DL_WriterA& dw,
  2705. const DL_3dFaceData& data,
  2706. const DL_Attributes& aAttrib )
  2707. {
  2708. dw.entity( "3DFACE" );
  2709. if( version==DL_VERSION_2000 )
  2710. {
  2711. dw.dxfString( 100, "AcDbEntity" );
  2712. }
  2713. dw.entityAttributes( aAttrib );
  2714. if( version==DL_VERSION_2000 )
  2715. {
  2716. dw.dxfString( 100, "AcDbFace" );
  2717. }
  2718. dw.coord( 10, data.x[0], data.y[0], data.z[0] );
  2719. dw.coord( 11, data.x[1], data.y[1], data.z[1] );
  2720. dw.coord( 12, data.x[2], data.y[2], data.z[2] );
  2721. dw.coord( 13, data.x[3], data.y[3], data.z[3] );
  2722. }
  2723. /**
  2724. * Writes an insert to the file.
  2725. *
  2726. * @param dw DXF writer
  2727. * @param data Entity data from the file
  2728. * @param aAttrib Attributes
  2729. */
  2730. void DL_Dxf::writeInsert( DL_WriterA& dw,
  2731. const DL_InsertData& data,
  2732. const DL_Attributes& aAttrib )
  2733. {
  2734. if( data.name.empty() )
  2735. {
  2736. std::cerr << "DL_Dxf::writeInsert: "
  2737. << "Block name must not be empty\n";
  2738. return;
  2739. }
  2740. dw.entity( "INSERT" );
  2741. if( version==DL_VERSION_2000 )
  2742. {
  2743. dw.dxfString( 100, "AcDbEntity" );
  2744. }
  2745. dw.entityAttributes( aAttrib );
  2746. if( version==DL_VERSION_2000 )
  2747. {
  2748. if( data.cols!=1 || data.rows!=1 )
  2749. {
  2750. dw.dxfString( 100, "AcDbMInsertBlock" );
  2751. }
  2752. else
  2753. {
  2754. dw.dxfString( 100, "AcDbBlockReference" );
  2755. }
  2756. }
  2757. dw.dxfString( 2, data.name );
  2758. dw.dxfReal( 10, data.ipx );
  2759. dw.dxfReal( 20, data.ipy );
  2760. dw.dxfReal( 30, data.ipz );
  2761. if( data.sx!=1.0 || data.sy!=1.0 )
  2762. {
  2763. dw.dxfReal( 41, data.sx );
  2764. dw.dxfReal( 42, data.sy );
  2765. dw.dxfReal( 43, 1.0 );
  2766. }
  2767. if( data.angle!=0.0 )
  2768. {
  2769. dw.dxfReal( 50, data.angle );
  2770. }
  2771. if( data.cols!=1 || data.rows!=1 )
  2772. {
  2773. dw.dxfInt( 70, data.cols );
  2774. dw.dxfInt( 71, data.rows );
  2775. }
  2776. if( data.colSp!=0.0 || data.rowSp!=0.0 )
  2777. {
  2778. dw.dxfReal( 44, data.colSp );
  2779. dw.dxfReal( 45, data.rowSp );
  2780. }
  2781. }
  2782. /**
  2783. * Writes a multi text entity to the file.
  2784. *
  2785. * @param dw DXF writer
  2786. * @param data Entity data from the file
  2787. * @param aAttrib Attributes
  2788. */
  2789. void DL_Dxf::writeMText( DL_WriterA& dw,
  2790. const DL_MTextData& data,
  2791. const DL_Attributes& aAttrib )
  2792. {
  2793. dw.entity( "MTEXT" );
  2794. if( version==DL_VERSION_2000 )
  2795. {
  2796. dw.dxfString( 100, "AcDbEntity" );
  2797. }
  2798. dw.entityAttributes( aAttrib );
  2799. if( version==DL_VERSION_2000 )
  2800. {
  2801. dw.dxfString( 100, "AcDbMText" );
  2802. }
  2803. dw.dxfReal( 10, data.ipx );
  2804. dw.dxfReal( 20, data.ipy );
  2805. dw.dxfReal( 30, data.ipz );
  2806. dw.dxfReal( 40, data.height );
  2807. dw.dxfReal( 41, data.width );
  2808. dw.dxfInt( 71, data.attachmentPoint );
  2809. dw.dxfInt( 72, data.drawingDirection );
  2810. // Creare text chunks of 250 characters each:
  2811. int length = data.text.length();
  2812. char chunk[251];
  2813. int i;
  2814. for( i = 250; i<length; i += 250 )
  2815. {
  2816. strncpy( chunk, &data.text.c_str()[i - 250], 250 );
  2817. chunk[250] = '\0';
  2818. dw.dxfString( 3, chunk );
  2819. }
  2820. strncpy( chunk, &data.text.c_str()[i - 250], 250 );
  2821. chunk[250] = '\0';
  2822. dw.dxfString( 1, chunk );
  2823. dw.dxfString( 7, data.style );
  2824. // since dxflib 2.0.2.1: degrees not rad (error in autodesk dxf doc)
  2825. dw.dxfReal( 50, data.angle / (2.0 * M_PI) * 360.0 );
  2826. dw.dxfInt( 73, data.lineSpacingStyle );
  2827. dw.dxfReal( 44, data.lineSpacingFactor );
  2828. }
  2829. /**
  2830. * Writes a text entity to the file.
  2831. *
  2832. * @param dw DXF writer
  2833. * @param data Entity data from the file
  2834. * @param aAttrib Attributes
  2835. */
  2836. void DL_Dxf::writeText( DL_WriterA& dw,
  2837. const DL_TextData& data,
  2838. const DL_Attributes& aAttrib )
  2839. {
  2840. dw.entity( "TEXT" );
  2841. if( version==DL_VERSION_2000 )
  2842. {
  2843. dw.dxfString( 100, "AcDbEntity" );
  2844. }
  2845. dw.entityAttributes( aAttrib );
  2846. if( version==DL_VERSION_2000 )
  2847. {
  2848. dw.dxfString( 100, "AcDbText" );
  2849. }
  2850. dw.dxfReal( 10, data.ipx );
  2851. dw.dxfReal( 20, data.ipy );
  2852. dw.dxfReal( 30, data.ipz );
  2853. dw.dxfReal( 40, data.height );
  2854. dw.dxfString( 1, data.text );
  2855. dw.dxfReal( 50, data.angle / (2 * M_PI) * 360.0 );
  2856. dw.dxfReal( 41, data.xScaleFactor );
  2857. dw.dxfString( 7, data.style );
  2858. dw.dxfInt( 71, data.textGenerationFlags );
  2859. dw.dxfInt( 72, data.hJustification );
  2860. dw.dxfReal( 11, data.apx );
  2861. dw.dxfReal( 21, data.apy );
  2862. dw.dxfReal( 31, data.apz );
  2863. if( version==DL_VERSION_2000 )
  2864. {
  2865. // required twice for some reason:
  2866. dw.dxfString( 100, "AcDbText" );
  2867. }
  2868. dw.dxfInt( 73, data.vJustification );
  2869. }
  2870. void DL_Dxf::writeAttribute( DL_WriterA& dw,
  2871. const DL_AttributeData& data,
  2872. const DL_Attributes& aAttrib )
  2873. {
  2874. dw.entity( "ATTRIB" );
  2875. if( version==DL_VERSION_2000 )
  2876. {
  2877. dw.dxfString( 100, "AcDbEntity" );
  2878. }
  2879. dw.entityAttributes( aAttrib );
  2880. if( version==DL_VERSION_2000 )
  2881. {
  2882. dw.dxfString( 100, "AcDbText" );
  2883. }
  2884. dw.dxfReal( 10, data.ipx );
  2885. dw.dxfReal( 20, data.ipy );
  2886. dw.dxfReal( 30, data.ipz );
  2887. dw.dxfReal( 40, data.height );
  2888. dw.dxfString( 1, data.text );
  2889. dw.dxfReal( 50, data.angle / (2 * M_PI) * 360.0 );
  2890. dw.dxfReal( 41, data.xScaleFactor );
  2891. dw.dxfString( 7, data.style );
  2892. dw.dxfInt( 71, data.textGenerationFlags );
  2893. dw.dxfInt( 72, data.hJustification );
  2894. dw.dxfReal( 11, data.apx );
  2895. dw.dxfReal( 21, data.apy );
  2896. dw.dxfReal( 31, data.apz );
  2897. if( version==DL_VERSION_2000 )
  2898. {
  2899. dw.dxfString( 100, "AcDbAttribute" );
  2900. }
  2901. dw.dxfString( 2, data.tag );
  2902. dw.dxfInt( 74, data.vJustification );
  2903. }
  2904. void DL_Dxf::writeDimStyleOverrides( DL_WriterA& dw,
  2905. const DL_DimensionData& data )
  2906. {
  2907. if( version==DL_VERSION_2000 )
  2908. {
  2909. dw.dxfString( 1001, "ACAD" );
  2910. dw.dxfString( 1000, "DSTYLE" );
  2911. dw.dxfString( 1002, "{" );
  2912. dw.dxfInt( 1070, 144 );
  2913. dw.dxfReal( 1040, data.linearFactor );
  2914. dw.dxfInt( 1070, 40 );
  2915. dw.dxfReal( 1040, data.dimScale );
  2916. dw.dxfString( 1002, "}" );
  2917. }
  2918. }
  2919. /**
  2920. * Writes an aligned dimension entity to the file.
  2921. *
  2922. * @param dw DXF writer
  2923. * @param data Generic dimension data for from the file
  2924. * @param data Specific aligned dimension data from the file
  2925. * @param aAttrib Attributes
  2926. */
  2927. void DL_Dxf::writeDimAligned( DL_WriterA& dw,
  2928. const DL_DimensionData& data,
  2929. const DL_DimAlignedData& edata,
  2930. const DL_Attributes& aAttrib )
  2931. {
  2932. dw.entity( "DIMENSION" );
  2933. if( version==DL_VERSION_2000 )
  2934. {
  2935. dw.dxfString( 100, "AcDbEntity" );
  2936. }
  2937. dw.entityAttributes( aAttrib );
  2938. if( version==DL_VERSION_2000 )
  2939. {
  2940. dw.dxfString( 100, "AcDbDimension" );
  2941. }
  2942. dw.dxfReal( 10, data.dpx );
  2943. dw.dxfReal( 20, data.dpy );
  2944. dw.dxfReal( 30, data.dpz );
  2945. dw.dxfReal( 11, data.mpx );
  2946. dw.dxfReal( 21, data.mpy );
  2947. dw.dxfReal( 31, 0.0 );
  2948. dw.dxfInt( 70, data.type );
  2949. if( version>DL_VERSION_R12 )
  2950. {
  2951. dw.dxfInt( 71, data.attachmentPoint );
  2952. dw.dxfInt( 72, data.lineSpacingStyle ); // opt
  2953. dw.dxfReal( 41, data.lineSpacingFactor ); // opt
  2954. }
  2955. dw.dxfReal( 42, data.angle );
  2956. dw.dxfString( 1, data.text ); // opt
  2957. // dw.dxfString(3, data.style);
  2958. dw.dxfString( 3, "Standard" );
  2959. if( version==DL_VERSION_2000 )
  2960. {
  2961. dw.dxfString( 100, "AcDbAlignedDimension" );
  2962. }
  2963. dw.dxfReal( 13, edata.epx1 );
  2964. dw.dxfReal( 23, edata.epy1 );
  2965. dw.dxfReal( 33, 0.0 );
  2966. dw.dxfReal( 14, edata.epx2 );
  2967. dw.dxfReal( 24, edata.epy2 );
  2968. dw.dxfReal( 34, 0.0 );
  2969. writeDimStyleOverrides( dw, data );
  2970. }
  2971. /**
  2972. * Writes a linear dimension entity to the file.
  2973. *
  2974. * @param dw DXF writer
  2975. * @param data Generic dimension data for from the file
  2976. * @param data Specific linear dimension data from the file
  2977. * @param aAttrib Attributes
  2978. */
  2979. void DL_Dxf::writeDimLinear( DL_WriterA& dw,
  2980. const DL_DimensionData& data,
  2981. const DL_DimLinearData& edata,
  2982. const DL_Attributes& aAttrib )
  2983. {
  2984. dw.entity( "DIMENSION" );
  2985. if( version==DL_VERSION_2000 )
  2986. {
  2987. dw.dxfString( 100, "AcDbEntity" );
  2988. }
  2989. dw.entityAttributes( aAttrib );
  2990. if( version==DL_VERSION_2000 )
  2991. {
  2992. dw.dxfString( 100, "AcDbDimension" );
  2993. }
  2994. dw.dxfReal( 10, data.dpx );
  2995. dw.dxfReal( 20, data.dpy );
  2996. dw.dxfReal( 30, data.dpz );
  2997. dw.dxfReal( 11, data.mpx );
  2998. dw.dxfReal( 21, data.mpy );
  2999. dw.dxfReal( 31, 0.0 );
  3000. dw.dxfInt( 70, data.type );
  3001. if( version>DL_VERSION_R12 )
  3002. {
  3003. dw.dxfInt( 71, data.attachmentPoint );
  3004. dw.dxfInt( 72, data.lineSpacingStyle ); // opt
  3005. dw.dxfReal( 41, data.lineSpacingFactor ); // opt
  3006. }
  3007. dw.dxfReal( 42, data.angle );
  3008. dw.dxfString( 1, data.text ); // opt
  3009. // dw.dxfString(3, data.style);
  3010. dw.dxfString( 3, "Standard" );
  3011. if( version==DL_VERSION_2000 )
  3012. {
  3013. dw.dxfString( 100, "AcDbAlignedDimension" );
  3014. }
  3015. dw.dxfReal( 13, edata.dpx1 );
  3016. dw.dxfReal( 23, edata.dpy1 );
  3017. dw.dxfReal( 33, 0.0 );
  3018. dw.dxfReal( 14, edata.dpx2 );
  3019. dw.dxfReal( 24, edata.dpy2 );
  3020. dw.dxfReal( 34, 0.0 );
  3021. dw.dxfReal( 50, edata.angle / (2.0 * M_PI) * 360.0 );
  3022. if( version==DL_VERSION_2000 )
  3023. {
  3024. dw.dxfString( 100, "AcDbRotatedDimension" );
  3025. }
  3026. writeDimStyleOverrides( dw, data );
  3027. }
  3028. /**
  3029. * Writes a radial dimension entity to the file.
  3030. *
  3031. * @param dw DXF writer
  3032. * @param data Generic dimension data for from the file
  3033. * @param data Specific radial dimension data from the file
  3034. * @param aAttrib Attributes
  3035. */
  3036. void DL_Dxf::writeDimRadial( DL_WriterA& dw,
  3037. const DL_DimensionData& data,
  3038. const DL_DimRadialData& edata,
  3039. const DL_Attributes& aAttrib )
  3040. {
  3041. dw.entity( "DIMENSION" );
  3042. if( version==DL_VERSION_2000 )
  3043. {
  3044. dw.dxfString( 100, "AcDbEntity" );
  3045. }
  3046. dw.entityAttributes( aAttrib );
  3047. if( version==DL_VERSION_2000 )
  3048. {
  3049. dw.dxfString( 100, "AcDbDimension" );
  3050. }
  3051. dw.dxfReal( 10, data.dpx );
  3052. dw.dxfReal( 20, data.dpy );
  3053. dw.dxfReal( 30, data.dpz );
  3054. dw.dxfReal( 11, data.mpx );
  3055. dw.dxfReal( 21, data.mpy );
  3056. dw.dxfReal( 31, 0.0 );
  3057. dw.dxfInt( 70, data.type );
  3058. if( version>DL_VERSION_R12 )
  3059. {
  3060. dw.dxfInt( 71, data.attachmentPoint );
  3061. dw.dxfInt( 72, data.lineSpacingStyle ); // opt
  3062. dw.dxfReal( 41, data.lineSpacingFactor ); // opt
  3063. }
  3064. dw.dxfReal( 42, data.angle );
  3065. dw.dxfString( 1, data.text ); // opt
  3066. // dw.dxfString(3, data.style);
  3067. dw.dxfString( 3, "Standard" );
  3068. if( version==DL_VERSION_2000 )
  3069. {
  3070. dw.dxfString( 100, "AcDbRadialDimension" );
  3071. }
  3072. dw.dxfReal( 15, edata.dpx );
  3073. dw.dxfReal( 25, edata.dpy );
  3074. dw.dxfReal( 35, 0.0 );
  3075. dw.dxfReal( 40, edata.leader );
  3076. writeDimStyleOverrides( dw, data );
  3077. }
  3078. /**
  3079. * Writes a diametric dimension entity to the file.
  3080. *
  3081. * @param dw DXF writer
  3082. * @param data Generic dimension data for from the file
  3083. * @param data Specific diametric dimension data from the file
  3084. * @param aAttrib Attributes
  3085. */
  3086. void DL_Dxf::writeDimDiametric( DL_WriterA& dw,
  3087. const DL_DimensionData& data,
  3088. const DL_DimDiametricData& edata,
  3089. const DL_Attributes& aAttrib )
  3090. {
  3091. dw.entity( "DIMENSION" );
  3092. if( version==DL_VERSION_2000 )
  3093. {
  3094. dw.dxfString( 100, "AcDbEntity" );
  3095. }
  3096. dw.entityAttributes( aAttrib );
  3097. if( version==DL_VERSION_2000 )
  3098. {
  3099. dw.dxfString( 100, "AcDbDimension" );
  3100. }
  3101. dw.dxfReal( 10, data.dpx );
  3102. dw.dxfReal( 20, data.dpy );
  3103. dw.dxfReal( 30, data.dpz );
  3104. dw.dxfReal( 11, data.mpx );
  3105. dw.dxfReal( 21, data.mpy );
  3106. dw.dxfReal( 31, 0.0 );
  3107. dw.dxfInt( 70, data.type );
  3108. if( version>DL_VERSION_R12 )
  3109. {
  3110. dw.dxfInt( 71, data.attachmentPoint );
  3111. dw.dxfInt( 72, data.lineSpacingStyle ); // opt
  3112. dw.dxfReal( 41, data.lineSpacingFactor ); // opt
  3113. }
  3114. dw.dxfReal( 42, data.angle );
  3115. dw.dxfString( 1, data.text ); // opt
  3116. // dw.dxfString(3, data.style);
  3117. dw.dxfString( 3, "Standard" );
  3118. if( version==DL_VERSION_2000 )
  3119. {
  3120. dw.dxfString( 100, "AcDbDiametricDimension" );
  3121. }
  3122. dw.dxfReal( 15, edata.dpx );
  3123. dw.dxfReal( 25, edata.dpy );
  3124. dw.dxfReal( 35, 0.0 );
  3125. dw.dxfReal( 40, edata.leader );
  3126. writeDimStyleOverrides( dw, data );
  3127. }
  3128. /**
  3129. * Writes an angular dimension entity to the file.
  3130. *
  3131. * @param dw DXF writer
  3132. * @param data Generic dimension data for from the file
  3133. * @param data Specific angular dimension data from the file
  3134. * @param aAttrib Attributes
  3135. */
  3136. void DL_Dxf::writeDimAngular( DL_WriterA& dw,
  3137. const DL_DimensionData& data,
  3138. const DL_DimAngularData& edata,
  3139. const DL_Attributes& aAttrib )
  3140. {
  3141. dw.entity( "DIMENSION" );
  3142. if( version==DL_VERSION_2000 )
  3143. {
  3144. dw.dxfString( 100, "AcDbEntity" );
  3145. }
  3146. dw.entityAttributes( aAttrib );
  3147. if( version==DL_VERSION_2000 )
  3148. {
  3149. dw.dxfString( 100, "AcDbDimension" );
  3150. }
  3151. dw.dxfReal( 10, data.dpx );
  3152. dw.dxfReal( 20, data.dpy );
  3153. dw.dxfReal( 30, data.dpz );
  3154. dw.dxfReal( 11, data.mpx );
  3155. dw.dxfReal( 21, data.mpy );
  3156. dw.dxfReal( 31, 0.0 );
  3157. dw.dxfInt( 70, data.type );
  3158. if( version>DL_VERSION_R12 )
  3159. {
  3160. dw.dxfInt( 71, data.attachmentPoint );
  3161. dw.dxfInt( 72, data.lineSpacingStyle ); // opt
  3162. dw.dxfReal( 41, data.lineSpacingFactor ); // opt
  3163. }
  3164. dw.dxfReal( 42, data.angle );
  3165. dw.dxfString( 1, data.text ); // opt
  3166. // dw.dxfString(3, data.style);
  3167. dw.dxfString( 3, "Standard" );
  3168. if( version==DL_VERSION_2000 )
  3169. {
  3170. dw.dxfString( 100, "AcDb2LineAngularDimension" );
  3171. }
  3172. dw.dxfReal( 13, edata.dpx1 );
  3173. dw.dxfReal( 23, edata.dpy1 );
  3174. dw.dxfReal( 33, 0.0 );
  3175. dw.dxfReal( 14, edata.dpx2 );
  3176. dw.dxfReal( 24, edata.dpy2 );
  3177. dw.dxfReal( 34, 0.0 );
  3178. dw.dxfReal( 15, edata.dpx3 );
  3179. dw.dxfReal( 25, edata.dpy3 );
  3180. dw.dxfReal( 35, 0.0 );
  3181. dw.dxfReal( 16, edata.dpx4 );
  3182. dw.dxfReal( 26, edata.dpy4 );
  3183. dw.dxfReal( 36, 0.0 );
  3184. }
  3185. /**
  3186. * Writes an angular dimension entity (3 points version) to the file.
  3187. *
  3188. * @param dw DXF writer
  3189. * @param data Generic dimension data for from the file
  3190. * @param data Specific angular dimension data from the file
  3191. * @param aAttrib Attributes
  3192. */
  3193. void DL_Dxf::writeDimAngular3P( DL_WriterA& dw,
  3194. const DL_DimensionData& data,
  3195. const DL_DimAngular3PData& edata,
  3196. const DL_Attributes& aAttrib )
  3197. {
  3198. dw.entity( "DIMENSION" );
  3199. if( version==DL_VERSION_2000 )
  3200. {
  3201. dw.dxfString( 100, "AcDbEntity" );
  3202. }
  3203. dw.entityAttributes( aAttrib );
  3204. if( version==DL_VERSION_2000 )
  3205. {
  3206. dw.dxfString( 100, "AcDbDimension" );
  3207. }
  3208. dw.dxfReal( 10, data.dpx );
  3209. dw.dxfReal( 20, data.dpy );
  3210. dw.dxfReal( 30, data.dpz );
  3211. dw.dxfReal( 11, data.mpx );
  3212. dw.dxfReal( 21, data.mpy );
  3213. dw.dxfReal( 31, 0.0 );
  3214. dw.dxfInt( 70, data.type );
  3215. if( version>DL_VERSION_R12 )
  3216. {
  3217. dw.dxfInt( 71, data.attachmentPoint );
  3218. dw.dxfInt( 72, data.lineSpacingStyle ); // opt
  3219. dw.dxfReal( 41, data.lineSpacingFactor ); // opt
  3220. }
  3221. dw.dxfReal( 42, data.angle );
  3222. dw.dxfString( 1, data.text ); // opt
  3223. // dw.dxfString(3, data.style);
  3224. dw.dxfString( 3, "Standard" );
  3225. if( version==DL_VERSION_2000 )
  3226. {
  3227. dw.dxfString( 100, "AcDb3PointAngularDimension" );
  3228. }
  3229. dw.dxfReal( 13, edata.dpx1 );
  3230. dw.dxfReal( 23, edata.dpy1 );
  3231. dw.dxfReal( 33, 0.0 );
  3232. dw.dxfReal( 14, edata.dpx2 );
  3233. dw.dxfReal( 24, edata.dpy2 );
  3234. dw.dxfReal( 34, 0.0 );
  3235. dw.dxfReal( 15, edata.dpx3 );
  3236. dw.dxfReal( 25, edata.dpy3 );
  3237. dw.dxfReal( 35, 0.0 );
  3238. }
  3239. /**
  3240. * Writes an ordinate dimension entity to the file.
  3241. *
  3242. * @param dw DXF writer
  3243. * @param data Generic dimension data for from the file
  3244. * @param data Specific ordinate dimension data from the file
  3245. * @param aAttrib Attributes
  3246. */
  3247. void DL_Dxf::writeDimOrdinate( DL_WriterA& dw,
  3248. const DL_DimensionData& data,
  3249. const DL_DimOrdinateData& edata,
  3250. const DL_Attributes& aAttrib )
  3251. {
  3252. dw.entity( "DIMENSION" );
  3253. if( version==DL_VERSION_2000 )
  3254. {
  3255. dw.dxfString( 100, "AcDbEntity" );
  3256. }
  3257. dw.entityAttributes( aAttrib );
  3258. if( version==DL_VERSION_2000 )
  3259. {
  3260. dw.dxfString( 100, "AcDbDimension" );
  3261. }
  3262. dw.dxfReal( 10, data.dpx );
  3263. dw.dxfReal( 20, data.dpy );
  3264. dw.dxfReal( 30, data.dpz );
  3265. dw.dxfReal( 11, data.mpx );
  3266. dw.dxfReal( 21, data.mpy );
  3267. dw.dxfReal( 31, 0.0 );
  3268. int type = data.type;
  3269. if( edata.xtype )
  3270. {
  3271. type |= 0x40;
  3272. }
  3273. dw.dxfInt( 70, type );
  3274. if( version>DL_VERSION_R12 )
  3275. {
  3276. dw.dxfInt( 71, data.attachmentPoint );
  3277. dw.dxfInt( 72, data.lineSpacingStyle ); // opt
  3278. dw.dxfReal( 41, data.lineSpacingFactor ); // opt
  3279. }
  3280. dw.dxfString( 1, data.text ); // opt
  3281. // dw.dxfString(3, data.style);
  3282. dw.dxfString( 3, "Standard" );
  3283. if( version==DL_VERSION_2000 )
  3284. {
  3285. dw.dxfString( 100, "AcDbOrdinateDimension" );
  3286. }
  3287. dw.dxfReal( 13, edata.dpx1 );
  3288. dw.dxfReal( 23, edata.dpy1 );
  3289. dw.dxfReal( 33, 0.0 );
  3290. dw.dxfReal( 14, edata.dpx2 );
  3291. dw.dxfReal( 24, edata.dpy2 );
  3292. dw.dxfReal( 34, 0.0 );
  3293. }
  3294. /**
  3295. * Writes a leader entity to the file.
  3296. *
  3297. * @param dw DXF writer
  3298. * @param data Entity data from the file
  3299. * @param aAttrib Attributes
  3300. * @see writeVertex
  3301. */
  3302. void DL_Dxf::writeLeader( DL_WriterA& dw,
  3303. const DL_LeaderData& data,
  3304. const DL_Attributes& aAttrib )
  3305. {
  3306. if( version>DL_VERSION_R12 )
  3307. {
  3308. dw.entity( "LEADER" );
  3309. if( version==DL_VERSION_2000 )
  3310. {
  3311. dw.dxfString( 100, "AcDbEntity" );
  3312. }
  3313. dw.entityAttributes( aAttrib );
  3314. if( version==DL_VERSION_2000 )
  3315. {
  3316. dw.dxfString( 100, "AcDbLeader" );
  3317. }
  3318. dw.dxfString( 3, "Standard" );
  3319. dw.dxfInt( 71, data.arrowHeadFlag );
  3320. dw.dxfInt( 72, data.leaderPathType );
  3321. dw.dxfInt( 73, data.leaderCreationFlag );
  3322. dw.dxfInt( 74, data.hooklineDirectionFlag );
  3323. dw.dxfInt( 75, data.hooklineFlag );
  3324. dw.dxfReal( 40, data.textAnnotationHeight );
  3325. dw.dxfReal( 41, data.textAnnotationWidth );
  3326. dw.dxfInt( 76, data.number );
  3327. }
  3328. }
  3329. /**
  3330. * Writes a single vertex of a leader to the file.
  3331. *
  3332. * @param dw DXF writer
  3333. * @param data Entity data
  3334. */
  3335. void DL_Dxf::writeLeaderVertex( DL_WriterA& dw,
  3336. const DL_LeaderVertexData& data )
  3337. {
  3338. if( version>DL_VERSION_R12 )
  3339. {
  3340. dw.dxfReal( 10, data.x );
  3341. dw.dxfReal( 20, data.y );
  3342. }
  3343. }
  3344. /**
  3345. * Writes the beginning of a hatch entity to the file.
  3346. * This must be followed by one or more writeHatchLoop()
  3347. * calls and a writeHatch2() call.
  3348. *
  3349. * @param dw DXF writer
  3350. * @param data Entity data.
  3351. * @param aAttrib Attributes
  3352. */
  3353. void DL_Dxf::writeHatch1( DL_WriterA& dw,
  3354. const DL_HatchData& data,
  3355. const DL_Attributes& aAttrib )
  3356. {
  3357. dw.entity( "HATCH" );
  3358. if( version==DL_VERSION_2000 )
  3359. {
  3360. dw.dxfString( 100, "AcDbEntity" );
  3361. }
  3362. dw.entityAttributes( aAttrib );
  3363. if( version==DL_VERSION_2000 )
  3364. {
  3365. dw.dxfString( 100, "AcDbHatch" );
  3366. }
  3367. dw.dxfReal( 10, 0.0 ); // elevation
  3368. dw.dxfReal( 20, 0.0 );
  3369. dw.dxfReal( 30, 0.0 );
  3370. dw.dxfReal( 210, 0.0 ); // extrusion dir.
  3371. dw.dxfReal( 220, 0.0 );
  3372. dw.dxfReal( 230, 1.0 );
  3373. if( data.solid==false )
  3374. {
  3375. dw.dxfString( 2, data.pattern );
  3376. }
  3377. else
  3378. {
  3379. dw.dxfString( 2, "SOLID" );
  3380. }
  3381. dw.dxfInt( 70, (int) data.solid );
  3382. dw.dxfInt( 71, 0 ); // non-associative
  3383. dw.dxfInt( 91, data.numLoops );
  3384. }
  3385. /**
  3386. * Writes the end of a hatch entity to the file.
  3387. *
  3388. * @param dw DXF writer
  3389. * @param data Entity data.
  3390. * @param aAttrib Attributes
  3391. */
  3392. void DL_Dxf::writeHatch2( DL_WriterA& dw,
  3393. const DL_HatchData& data,
  3394. const DL_Attributes& /*aAttrib*/ )
  3395. {
  3396. dw.dxfInt( 75, 0 ); // odd parity
  3397. dw.dxfInt( 76, 1 ); // pattern type
  3398. if( data.solid==false )
  3399. {
  3400. dw.dxfReal( 52, data.angle );
  3401. dw.dxfReal( 41, data.scale );
  3402. dw.dxfInt( 77, 0 ); // not double
  3403. // dw.dxfInt(78, 0);
  3404. dw.dxfInt( 78, 1 );
  3405. dw.dxfReal( 53, 45.0 );
  3406. dw.dxfReal( 43, 0.0 );
  3407. dw.dxfReal( 44, 0.0 );
  3408. dw.dxfReal( 45, -0.0883883476483184 );
  3409. dw.dxfReal( 46, 0.0883883476483185 );
  3410. dw.dxfInt( 79, 0 );
  3411. }
  3412. dw.dxfInt( 98, 0 );
  3413. if( version==DL_VERSION_2000 )
  3414. {
  3415. dw.dxfString( 1001, "ACAD" );
  3416. dw.dxfReal( 1010, data.originX );
  3417. dw.dxfReal( 1020, data.originY );
  3418. dw.dxfInt( 1030, 0.0 );
  3419. }
  3420. }
  3421. /**
  3422. * Writes the beginning of a hatch loop to the file. This
  3423. * must happen after writing the beginning of a hatch entity.
  3424. *
  3425. * @param dw DXF writer
  3426. * @param data Entity data.
  3427. */
  3428. void DL_Dxf::writeHatchLoop1( DL_WriterA& dw,
  3429. const DL_HatchLoopData& data )
  3430. {
  3431. dw.dxfInt( 92, 1 );
  3432. dw.dxfInt( 93, data.numEdges );
  3433. // dw.dxfInt(97, 0);
  3434. }
  3435. /**
  3436. * Writes the end of a hatch loop to the file.
  3437. *
  3438. * @param dw DXF writer
  3439. * @param data Entity data.
  3440. */
  3441. void DL_Dxf::writeHatchLoop2( DL_WriterA& dw,
  3442. const DL_HatchLoopData& /*data*/ )
  3443. {
  3444. dw.dxfInt( 97, 0 );
  3445. }
  3446. /**
  3447. * Writes the beginning of a hatch entity to the file.
  3448. *
  3449. * @param dw DXF writer
  3450. * @param data Entity data.
  3451. */
  3452. void DL_Dxf::writeHatchEdge( DL_WriterA& dw,
  3453. const DL_HatchEdgeData& data )
  3454. {
  3455. if( data.type<1 || data.type>4 )
  3456. {
  3457. printf( "WARNING: unsupported hatch edge type: %d", data.type );
  3458. }
  3459. dw.dxfInt( 72, data.type );
  3460. switch( data.type )
  3461. {
  3462. // line:
  3463. case 1:
  3464. dw.dxfReal( 10, data.x1 );
  3465. dw.dxfReal( 20, data.y1 );
  3466. dw.dxfReal( 11, data.x2 );
  3467. dw.dxfReal( 21, data.y2 );
  3468. break;
  3469. // arc:
  3470. case 2:
  3471. dw.dxfReal( 10, data.cx );
  3472. dw.dxfReal( 20, data.cy );
  3473. dw.dxfReal( 40, data.radius );
  3474. dw.dxfReal( 50, data.angle1 / (2 * M_PI) * 360.0 );
  3475. dw.dxfReal( 51, data.angle2 / (2 * M_PI) * 360.0 );
  3476. dw.dxfInt( 73, (int) (data.ccw) );
  3477. break;
  3478. // ellipse arc:
  3479. case 3:
  3480. dw.dxfReal( 10, data.cx );
  3481. dw.dxfReal( 20, data.cy );
  3482. dw.dxfReal( 11, data.mx );
  3483. dw.dxfReal( 21, data.my );
  3484. dw.dxfReal( 40, data.ratio );
  3485. dw.dxfReal( 50, data.angle1 / (2 * M_PI) * 360.0 );
  3486. dw.dxfReal( 51, data.angle2 / (2 * M_PI) * 360.0 );
  3487. dw.dxfInt( 73, (int) (data.ccw) );
  3488. break;
  3489. // spline:
  3490. case 4:
  3491. dw.dxfInt( 94, data.degree );
  3492. dw.dxfBool( 73, data.rational );
  3493. dw.dxfBool( 74, data.periodic );
  3494. dw.dxfInt( 95, data.nKnots );
  3495. dw.dxfInt( 96, data.nControl );
  3496. for( unsigned int i = 0; i<data.knots.size(); i++ )
  3497. {
  3498. dw.dxfReal( 40, data.knots[i] );
  3499. }
  3500. for( unsigned int i = 0; i<data.controlPoints.size(); i++ )
  3501. {
  3502. dw.dxfReal( 10, data.controlPoints[i][0] );
  3503. dw.dxfReal( 20, data.controlPoints[i][1] );
  3504. }
  3505. for( unsigned int i = 0; i<data.weights.size(); i++ )
  3506. {
  3507. dw.dxfReal( 42, data.weights[i] );
  3508. }
  3509. if( data.nFit>0 )
  3510. {
  3511. dw.dxfInt( 97, data.nFit );
  3512. for( unsigned int i = 0; i<data.fitPoints.size(); i++ )
  3513. {
  3514. dw.dxfReal( 11, data.fitPoints[i][0] );
  3515. dw.dxfReal( 21, data.fitPoints[i][1] );
  3516. }
  3517. }
  3518. if( fabs( data.startTangentX )>1.0e-4 || fabs( data.startTangentY )>1.0e-4 )
  3519. {
  3520. dw.dxfReal( 12, data.startTangentX );
  3521. dw.dxfReal( 22, data.startTangentY );
  3522. }
  3523. if( fabs( data.endTangentX )>1.0e-4 || fabs( data.endTangentY )>1.0e-4 )
  3524. {
  3525. dw.dxfReal( 13, data.endTangentX );
  3526. dw.dxfReal( 23, data.endTangentY );
  3527. }
  3528. break;
  3529. default:
  3530. break;
  3531. }
  3532. }
  3533. /**
  3534. * Writes an image entity.
  3535. *
  3536. * @return IMAGEDEF handle. Needed for the IMAGEDEF counterpart.
  3537. */
  3538. int DL_Dxf::writeImage( DL_WriterA& dw,
  3539. const DL_ImageData& data,
  3540. const DL_Attributes& aAttrib )
  3541. {
  3542. /*if (data.file.empty()) {
  3543. * std::cerr << "DL_Dxf::writeImage: "
  3544. * << "Image file must not be empty\n";
  3545. * return;
  3546. * }*/
  3547. dw.entity( "IMAGE" );
  3548. if( version==DL_VERSION_2000 )
  3549. {
  3550. dw.dxfString( 100, "AcDbEntity" );
  3551. }
  3552. dw.entityAttributes( aAttrib );
  3553. if( version==DL_VERSION_2000 )
  3554. {
  3555. dw.dxfString( 100, "AcDbRasterImage" );
  3556. dw.dxfInt( 90, 0 );
  3557. }
  3558. // insertion point
  3559. dw.dxfReal( 10, data.ipx );
  3560. dw.dxfReal( 20, data.ipy );
  3561. dw.dxfReal( 30, data.ipz );
  3562. // vector along bottom side (1 pixel long)
  3563. dw.dxfReal( 11, data.ux );
  3564. dw.dxfReal( 21, data.uy );
  3565. dw.dxfReal( 31, data.uz );
  3566. // vector along left side (1 pixel long)
  3567. dw.dxfReal( 12, data.vx );
  3568. dw.dxfReal( 22, data.vy );
  3569. dw.dxfReal( 32, data.vz );
  3570. // image size in pixel
  3571. dw.dxfReal( 13, data.width );
  3572. dw.dxfReal( 23, data.height );
  3573. // handle of IMAGEDEF object
  3574. int handle = dw.incHandle();
  3575. dw.dxfHex( 340, handle );
  3576. // flags
  3577. dw.dxfInt( 70, 15 );
  3578. // clipping:
  3579. dw.dxfInt( 280, 0 );
  3580. // brightness, contrast, fade
  3581. dw.dxfInt( 281, data.brightness );
  3582. dw.dxfInt( 282, data.contrast );
  3583. dw.dxfInt( 283, data.fade );
  3584. return handle;
  3585. }
  3586. /**
  3587. * Writes an image definiition entity.
  3588. */
  3589. void DL_Dxf::writeImageDef( DL_WriterA& dw,
  3590. int handle,
  3591. const DL_ImageData& data )
  3592. {
  3593. /*if (data.file.empty()) {
  3594. * std::cerr << "DL_Dxf::writeImage: "
  3595. * << "Image file must not be empty\n";
  3596. * return;
  3597. * }*/
  3598. dw.dxfString( 0, "IMAGEDEF" );
  3599. if( version==DL_VERSION_2000 )
  3600. {
  3601. dw.dxfHex( 5, handle );
  3602. }
  3603. if( version==DL_VERSION_2000 )
  3604. {
  3605. dw.dxfString( 100, "AcDbRasterImageDef" );
  3606. dw.dxfInt( 90, 0 );
  3607. }
  3608. // file name:
  3609. dw.dxfString( 1, data.ref );
  3610. // image size in pixel
  3611. dw.dxfReal( 10, data.width );
  3612. dw.dxfReal( 20, data.height );
  3613. dw.dxfReal( 11, 1.0 );
  3614. dw.dxfReal( 21, 1.0 );
  3615. // loaded:
  3616. dw.dxfInt( 280, 1 );
  3617. // units:
  3618. dw.dxfInt( 281, 0 );
  3619. }
  3620. /**
  3621. * Writes a layer to the file. Layers are stored in the
  3622. * tables section of a DXF file.
  3623. *
  3624. * @param dw DXF writer
  3625. * @param data Entity data from the file
  3626. * @param aAttrib Attributes
  3627. */
  3628. void DL_Dxf::writeLayer( DL_WriterA& dw,
  3629. const DL_LayerData& data,
  3630. const DL_Attributes& aAttrib )
  3631. {
  3632. if( data.name.empty() )
  3633. {
  3634. std::cerr << "DL_Dxf::writeLayer: "
  3635. << "Layer name must not be empty\n";
  3636. return;
  3637. }
  3638. int color = aAttrib.getColor();
  3639. if( color>=256 )
  3640. {
  3641. std::cerr << "Layer color cannot be " << color << ". Changed to 7.\n";
  3642. color = 7;
  3643. }
  3644. if( data.off )
  3645. {
  3646. // negative color value means layer is off:
  3647. color = -color;
  3648. }
  3649. if( data.name == "0" )
  3650. {
  3651. dw.tableLayerEntry( 0x10 );
  3652. }
  3653. else
  3654. {
  3655. dw.tableLayerEntry();
  3656. }
  3657. dw.dxfString( 2, data.name );
  3658. dw.dxfInt( 70, data.flags );
  3659. dw.dxfInt( 62, color );
  3660. if( version>=DL_VERSION_2000 && aAttrib.getColor24()!=-1 )
  3661. {
  3662. dw.dxfInt( 420, attrib.getColor24() );
  3663. }
  3664. dw.dxfString( 6, ( attrib.getLinetype().length()==0 ?
  3665. std::string( "CONTINUOUS" ) : attrib.getLinetype() ) );
  3666. if( version>=DL_VERSION_2000 )
  3667. {
  3668. // layer defpoints cannot be plotted
  3669. std::string lstr = data.name;
  3670. std::transform( lstr.begin(), lstr.end(), lstr.begin(), tolower );
  3671. if( lstr=="defpoints" )
  3672. {
  3673. dw.dxfInt( 290, 0 );
  3674. }
  3675. }
  3676. if( version>=DL_VERSION_2000 && attrib.getWidth()!=-1 )
  3677. {
  3678. dw.dxfInt( 370, attrib.getWidth() );
  3679. }
  3680. if( version>=DL_VERSION_2000 )
  3681. {
  3682. dw.dxfHex( 390, 0xF );
  3683. }
  3684. }
  3685. /**
  3686. * Writes a line type to the file. Line types are stored in the
  3687. * tables section of a DXF file.
  3688. */
  3689. void DL_Dxf::writeLinetype( DL_WriterA& dw,
  3690. const DL_LinetypeData& data )
  3691. {
  3692. std::string nameUpper = data.name;
  3693. std::transform( nameUpper.begin(), nameUpper.end(), nameUpper.begin(), ::toupper );
  3694. if( data.name.empty() )
  3695. {
  3696. std::cerr << "DL_Dxf::writeLinetype: "
  3697. << "Line type name must not be empty\n";
  3698. return;
  3699. }
  3700. // ignore BYLAYER, BYBLOCK for R12
  3701. if( version<DL_VERSION_2000 )
  3702. {
  3703. if( nameUpper=="BYBLOCK" || nameUpper=="BYLAYER" )
  3704. {
  3705. return;
  3706. }
  3707. }
  3708. // write id (not for R12)
  3709. if( nameUpper=="BYBLOCK" )
  3710. {
  3711. dw.tableLinetypeEntry( 0x14 );
  3712. }
  3713. else if( nameUpper=="BYLAYER" )
  3714. {
  3715. dw.tableLinetypeEntry( 0x15 );
  3716. }
  3717. else if( nameUpper=="CONTINUOUS" )
  3718. {
  3719. dw.tableLinetypeEntry( 0x16 );
  3720. }
  3721. else
  3722. {
  3723. dw.tableLinetypeEntry();
  3724. }
  3725. dw.dxfString( 2, data.name );
  3726. dw.dxfInt( 70, data.flags );
  3727. if( nameUpper=="BYBLOCK" )
  3728. {
  3729. dw.dxfString( 3, "" );
  3730. dw.dxfInt( 72, 65 );
  3731. dw.dxfInt( 73, 0 );
  3732. dw.dxfReal( 40, 0.0 );
  3733. }
  3734. else if( nameUpper=="BYLAYER" )
  3735. {
  3736. dw.dxfString( 3, "" );
  3737. dw.dxfInt( 72, 65 );
  3738. dw.dxfInt( 73, 0 );
  3739. dw.dxfReal( 40, 0.0 );
  3740. }
  3741. else if( nameUpper=="CONTINUOUS" )
  3742. {
  3743. dw.dxfString( 3, "Solid line" );
  3744. dw.dxfInt( 72, 65 );
  3745. dw.dxfInt( 73, 0 );
  3746. dw.dxfReal( 40, 0.0 );
  3747. }
  3748. else
  3749. {
  3750. dw.dxfString( 3, data.description );
  3751. dw.dxfInt( 72, 65 );
  3752. dw.dxfInt( 73, data.numberOfDashes );
  3753. dw.dxfReal( 40, data.patternLength );
  3754. for( int i = 0; i < data.numberOfDashes; i++ )
  3755. {
  3756. dw.dxfReal( 49, data.pattern[i] );
  3757. if( version>=DL_VERSION_R13 )
  3758. {
  3759. dw.dxfInt( 74, 0 );
  3760. }
  3761. }
  3762. }
  3763. }
  3764. /**
  3765. * Writes the APPID section to the DXF file.
  3766. *
  3767. * @param name Application name
  3768. */
  3769. void DL_Dxf::writeAppid( DL_WriterA& dw, const std::string& name )
  3770. {
  3771. if( name.empty() )
  3772. {
  3773. std::cerr << "DL_Dxf::writeAppid: "
  3774. << "Application name must not be empty\n";
  3775. return;
  3776. }
  3777. std::string n = name;
  3778. std::transform( n.begin(), n.end(), n.begin(), ::toupper );
  3779. if( n=="ACAD" )
  3780. {
  3781. dw.tableAppidEntry( 0x12 );
  3782. }
  3783. else
  3784. {
  3785. dw.tableAppidEntry();
  3786. }
  3787. dw.dxfString( 2, name );
  3788. dw.dxfInt( 70, 0 );
  3789. }
  3790. /**
  3791. * Writes a block's definition (no entities) to the DXF file.
  3792. */
  3793. void DL_Dxf::writeBlock( DL_WriterA& dw, const DL_BlockData& data )
  3794. {
  3795. if( data.name.empty() )
  3796. {
  3797. std::cerr << "DL_Dxf::writeBlock: "
  3798. << "Block name must not be empty\n";
  3799. return;
  3800. }
  3801. std::string n = data.name;
  3802. std::transform( n.begin(), n.end(), n.begin(), ::toupper );
  3803. if( n=="*PAPER_SPACE" )
  3804. {
  3805. dw.sectionBlockEntry( 0x1C );
  3806. }
  3807. else if( n=="*MODEL_SPACE" )
  3808. {
  3809. dw.sectionBlockEntry( 0x20 );
  3810. }
  3811. else if( n=="*PAPER_SPACE0" )
  3812. {
  3813. dw.sectionBlockEntry( 0x24 );
  3814. }
  3815. else
  3816. {
  3817. dw.sectionBlockEntry();
  3818. }
  3819. dw.dxfString( 2, data.name );
  3820. dw.dxfInt( 70, 0 );
  3821. dw.coord( 10, data.bpx, data.bpy, data.bpz );
  3822. dw.dxfString( 3, data.name );
  3823. dw.dxfString( 1, "" );
  3824. }
  3825. /**
  3826. * Writes a block end.
  3827. *
  3828. * @param name Block name
  3829. */
  3830. void DL_Dxf::writeEndBlock( DL_WriterA& dw, const std::string& name )
  3831. {
  3832. std::string n = name;
  3833. std::transform( n.begin(), n.end(), n.begin(), ::toupper );
  3834. if( n=="*PAPER_SPACE" )
  3835. {
  3836. dw.sectionBlockEntryEnd( 0x1D );
  3837. }
  3838. else if( n=="*MODEL_SPACE" )
  3839. {
  3840. dw.sectionBlockEntryEnd( 0x21 );
  3841. }
  3842. else if( n=="*PAPER_SPACE0" )
  3843. {
  3844. dw.sectionBlockEntryEnd( 0x25 );
  3845. }
  3846. else
  3847. {
  3848. dw.sectionBlockEntryEnd();
  3849. }
  3850. }
  3851. /**
  3852. * Writes a viewport section. This section is needed in DL_VERSION_R13.
  3853. * Note that this method currently only writes a faked VPORT section
  3854. * to make the file readable by Aut*cad.
  3855. */
  3856. void DL_Dxf::writeVPort( DL_WriterA& dw )
  3857. {
  3858. dw.dxfString( 0, "TABLE" );
  3859. dw.dxfString( 2, "VPORT" );
  3860. if( version==DL_VERSION_2000 )
  3861. {
  3862. dw.dxfHex( 5, 0x8 );
  3863. }
  3864. // dw.dxfHex(330, 0);
  3865. if( version==DL_VERSION_2000 )
  3866. {
  3867. dw.dxfString( 100, "AcDbSymbolTable" );
  3868. }
  3869. dw.dxfInt( 70, 1 );
  3870. dw.dxfString( 0, "VPORT" );
  3871. // dw.dxfHex(5, 0x2F);
  3872. if( version==DL_VERSION_2000 )
  3873. {
  3874. dw.handle();
  3875. }
  3876. // dw.dxfHex(330, 8);
  3877. if( version==DL_VERSION_2000 )
  3878. {
  3879. dw.dxfString( 100, "AcDbSymbolTableRecord" );
  3880. dw.dxfString( 100, "AcDbViewportTableRecord" );
  3881. }
  3882. dw.dxfString( 2, "*Active" );
  3883. dw.dxfInt( 70, 0 );
  3884. dw.dxfReal( 10, 0.0 );
  3885. dw.dxfReal( 20, 0.0 );
  3886. dw.dxfReal( 11, 1.0 );
  3887. dw.dxfReal( 21, 1.0 );
  3888. dw.dxfReal( 12, 286.3055555555555 );
  3889. dw.dxfReal( 22, 148.5 );
  3890. dw.dxfReal( 13, 0.0 );
  3891. dw.dxfReal( 23, 0.0 );
  3892. dw.dxfReal( 14, 10.0 );
  3893. dw.dxfReal( 24, 10.0 );
  3894. dw.dxfReal( 15, 10.0 );
  3895. dw.dxfReal( 25, 10.0 );
  3896. dw.dxfReal( 16, 0.0 );
  3897. dw.dxfReal( 26, 0.0 );
  3898. dw.dxfReal( 36, 1.0 );
  3899. dw.dxfReal( 17, 0.0 );
  3900. dw.dxfReal( 27, 0.0 );
  3901. dw.dxfReal( 37, 0.0 );
  3902. dw.dxfReal( 40, 297.0 );
  3903. dw.dxfReal( 41, 1.92798353909465 );
  3904. dw.dxfReal( 42, 50.0 );
  3905. dw.dxfReal( 43, 0.0 );
  3906. dw.dxfReal( 44, 0.0 );
  3907. dw.dxfReal( 50, 0.0 );
  3908. dw.dxfReal( 51, 0.0 );
  3909. dw.dxfInt( 71, 0 );
  3910. dw.dxfInt( 72, 100 );
  3911. dw.dxfInt( 73, 1 );
  3912. dw.dxfInt( 74, 3 );
  3913. dw.dxfInt( 75, 1 );
  3914. dw.dxfInt( 76, 1 );
  3915. dw.dxfInt( 77, 0 );
  3916. dw.dxfInt( 78, 0 );
  3917. if( version==DL_VERSION_2000 )
  3918. {
  3919. dw.dxfInt( 281, 0 );
  3920. dw.dxfInt( 65, 1 );
  3921. dw.dxfReal( 110, 0.0 );
  3922. dw.dxfReal( 120, 0.0 );
  3923. dw.dxfReal( 130, 0.0 );
  3924. dw.dxfReal( 111, 1.0 );
  3925. dw.dxfReal( 121, 0.0 );
  3926. dw.dxfReal( 131, 0.0 );
  3927. dw.dxfReal( 112, 0.0 );
  3928. dw.dxfReal( 122, 1.0 );
  3929. dw.dxfReal( 132, 0.0 );
  3930. dw.dxfInt( 79, 0 );
  3931. dw.dxfReal( 146, 0.0 );
  3932. }
  3933. dw.dxfString( 0, "ENDTAB" );
  3934. }
  3935. /**
  3936. * Writes a style section. This section is needed in DL_VERSION_R13.
  3937. */
  3938. void DL_Dxf::writeStyle( DL_WriterA& dw, const DL_StyleData& style )
  3939. {
  3940. // dw.dxfString( 0, "TABLE");
  3941. // dw.dxfString( 2, "STYLE");
  3942. // if (version==DL_VERSION_2000) {
  3943. // dw.dxfHex(5, 3);
  3944. // }
  3945. // dw.dxfHex(330, 0);
  3946. // if (version==DL_VERSION_2000) {
  3947. // dw.dxfString(100, "AcDbSymbolTable");
  3948. // }
  3949. // dw.dxfInt( 70, 1);
  3950. dw.dxfString( 0, "STYLE" );
  3951. if( version==DL_VERSION_2000 )
  3952. {
  3953. if( style.name=="Standard" )
  3954. {
  3955. // dw.dxfHex(5, 0x11);
  3956. styleHandleStd = dw.handle();
  3957. }
  3958. else
  3959. {
  3960. dw.handle();
  3961. }
  3962. }
  3963. // dw.dxfHex(330, 3);
  3964. if( version==DL_VERSION_2000 )
  3965. {
  3966. dw.dxfString( 100, "AcDbSymbolTableRecord" );
  3967. dw.dxfString( 100, "AcDbTextStyleTableRecord" );
  3968. }
  3969. dw.dxfString( 2, style.name );
  3970. dw.dxfInt( 70, style.flags );
  3971. dw.dxfReal( 40, style.fixedTextHeight );
  3972. dw.dxfReal( 41, style.widthFactor );
  3973. dw.dxfReal( 50, style.obliqueAngle );
  3974. dw.dxfInt( 71, style.textGenerationFlags );
  3975. dw.dxfReal( 42, style.lastHeightUsed );
  3976. if( version==DL_VERSION_2000 )
  3977. {
  3978. dw.dxfString( 3, "" );
  3979. dw.dxfString( 4, "" );
  3980. dw.dxfString( 1001, "ACAD" );
  3981. // dw.dxfString(1000, style.name);
  3982. dw.dxfString( 1000, style.primaryFontFile );
  3983. int xFlags = 0;
  3984. if( style.bold )
  3985. {
  3986. xFlags = xFlags | 0x2000000;
  3987. }
  3988. if( style.italic )
  3989. {
  3990. xFlags = xFlags | 0x1000000;
  3991. }
  3992. dw.dxfInt( 1071, xFlags );
  3993. }
  3994. else
  3995. {
  3996. dw.dxfString( 3, style.primaryFontFile );
  3997. dw.dxfString( 4, style.bigFontFile );
  3998. }
  3999. // dw.dxfString( 0, "ENDTAB");
  4000. }
  4001. /**
  4002. * Writes a view section. This section is needed in DL_VERSION_R13.
  4003. * Note that this method currently only writes a faked VIEW section
  4004. * to make the file readable by Aut*cad.
  4005. */
  4006. void DL_Dxf::writeView( DL_WriterA& dw )
  4007. {
  4008. dw.dxfString( 0, "TABLE" );
  4009. dw.dxfString( 2, "VIEW" );
  4010. if( version==DL_VERSION_2000 )
  4011. {
  4012. dw.dxfHex( 5, 6 );
  4013. }
  4014. // dw.dxfHex(330, 0);
  4015. if( version==DL_VERSION_2000 )
  4016. {
  4017. dw.dxfString( 100, "AcDbSymbolTable" );
  4018. }
  4019. dw.dxfInt( 70, 0 );
  4020. dw.dxfString( 0, "ENDTAB" );
  4021. }
  4022. /**
  4023. * Writes a ucs section. This section is needed in DL_VERSION_R13.
  4024. * Note that this method currently only writes a faked UCS section
  4025. * to make the file readable by Aut*cad.
  4026. */
  4027. void DL_Dxf::writeUcs( DL_WriterA& dw )
  4028. {
  4029. dw.dxfString( 0, "TABLE" );
  4030. dw.dxfString( 2, "UCS" );
  4031. if( version==DL_VERSION_2000 )
  4032. {
  4033. dw.dxfHex( 5, 7 );
  4034. }
  4035. // dw.dxfHex(330, 0);
  4036. if( version==DL_VERSION_2000 )
  4037. {
  4038. dw.dxfString( 100, "AcDbSymbolTable" );
  4039. }
  4040. dw.dxfInt( 70, 0 );
  4041. dw.dxfString( 0, "ENDTAB" );
  4042. }
  4043. /**
  4044. * Writes a dimstyle section. This section is needed in DL_VERSION_R13.
  4045. * Note that this method currently only writes a faked DIMSTYLE section
  4046. * to make the file readable by Aut*cad.
  4047. */
  4048. void DL_Dxf::writeDimStyle( DL_WriterA& dw,
  4049. double dimasz, double dimexe, double dimexo,
  4050. double dimgap, double dimtxt )
  4051. {
  4052. dw.dxfString( 0, "TABLE" );
  4053. dw.dxfString( 2, "DIMSTYLE" );
  4054. if( version==DL_VERSION_2000 )
  4055. {
  4056. dw.dxfHex( 5, 0xA );
  4057. dw.dxfString( 100, "AcDbSymbolTable" );
  4058. }
  4059. dw.dxfInt( 70, 1 );
  4060. if( version==DL_VERSION_2000 )
  4061. {
  4062. dw.dxfString( 100, "AcDbDimStyleTable" );
  4063. dw.dxfInt( 71, 0 );
  4064. }
  4065. dw.dxfString( 0, "DIMSTYLE" );
  4066. if( version==DL_VERSION_2000 )
  4067. {
  4068. dw.dxfHex( 105, 0x27 );
  4069. }
  4070. // dw.handle(105);
  4071. // dw.dxfHex(330, 0xA);
  4072. if( version==DL_VERSION_2000 )
  4073. {
  4074. dw.dxfString( 100, "AcDbSymbolTableRecord" );
  4075. dw.dxfString( 100, "AcDbDimStyleTableRecord" );
  4076. }
  4077. dw.dxfString( 2, "Standard" );
  4078. if( version==DL_VERSION_R12 )
  4079. {
  4080. dw.dxfString( 3, "" );
  4081. dw.dxfString( 4, "" );
  4082. dw.dxfString( 5, "" );
  4083. dw.dxfString( 6, "" );
  4084. dw.dxfString( 7, "" );
  4085. dw.dxfReal( 40, 1.0 );
  4086. }
  4087. dw.dxfReal( 41, dimasz );
  4088. dw.dxfReal( 42, dimexo );
  4089. dw.dxfReal( 43, 3.75 );
  4090. dw.dxfReal( 44, dimexe );
  4091. if( version==DL_VERSION_R12 )
  4092. {
  4093. dw.dxfReal( 45, 0.0 );
  4094. dw.dxfReal( 46, 0.0 );
  4095. dw.dxfReal( 47, 0.0 );
  4096. dw.dxfReal( 48, 0.0 );
  4097. }
  4098. dw.dxfInt( 70, 0 );
  4099. if( version==DL_VERSION_R12 )
  4100. {
  4101. dw.dxfInt( 71, 0 );
  4102. dw.dxfInt( 72, 0 );
  4103. }
  4104. dw.dxfInt( 73, 0 );
  4105. dw.dxfInt( 74, 0 );
  4106. if( version==DL_VERSION_R12 )
  4107. {
  4108. dw.dxfInt( 75, 0 );
  4109. dw.dxfInt( 76, 0 );
  4110. }
  4111. dw.dxfInt( 77, 1 );
  4112. dw.dxfInt( 78, 8 );
  4113. dw.dxfReal( 140, dimtxt );
  4114. dw.dxfReal( 141, 2.5 );
  4115. if( version==DL_VERSION_R12 )
  4116. {
  4117. dw.dxfReal( 142, 0.0 );
  4118. }
  4119. dw.dxfReal( 143, 0.03937007874016 );
  4120. if( version==DL_VERSION_R12 )
  4121. {
  4122. dw.dxfReal( 144, 1.0 );
  4123. dw.dxfReal( 145, 0.0 );
  4124. dw.dxfReal( 146, 1.0 );
  4125. }
  4126. dw.dxfReal( 147, dimgap );
  4127. if( version==DL_VERSION_R12 )
  4128. {
  4129. dw.dxfInt( 170, 0 );
  4130. }
  4131. dw.dxfInt( 171, 3 );
  4132. dw.dxfInt( 172, 1 );
  4133. if( version==DL_VERSION_R12 )
  4134. {
  4135. dw.dxfInt( 173, 0 );
  4136. dw.dxfInt( 174, 0 );
  4137. dw.dxfInt( 175, 0 );
  4138. dw.dxfInt( 176, 0 );
  4139. dw.dxfInt( 177, 0 );
  4140. dw.dxfInt( 178, 0 );
  4141. }
  4142. if( version==DL_VERSION_2000 )
  4143. {
  4144. dw.dxfInt( 271, 2 );
  4145. dw.dxfInt( 272, 2 );
  4146. dw.dxfInt( 274, 3 );
  4147. dw.dxfInt( 278, 44 );
  4148. dw.dxfInt( 283, 0 );
  4149. dw.dxfInt( 284, 8 );
  4150. dw.dxfHex( 340, styleHandleStd );
  4151. // dw.dxfHex(340, 0x11);
  4152. }
  4153. // * /
  4154. dw.dxfString( 0, "ENDTAB" );
  4155. }
  4156. /**
  4157. * Writes a blockrecord section. This section is needed in DL_VERSION_R13.
  4158. * Note that this method currently only writes a faked BLOCKRECORD section
  4159. * to make the file readable by Aut*cad.
  4160. */
  4161. void DL_Dxf::writeBlockRecord( DL_WriterA& dw )
  4162. {
  4163. dw.dxfString( 0, "TABLE" );
  4164. dw.dxfString( 2, "BLOCK_RECORD" );
  4165. if( version==DL_VERSION_2000 )
  4166. {
  4167. dw.dxfHex( 5, 1 );
  4168. }
  4169. // dw.dxfHex(330, 0);
  4170. if( version==DL_VERSION_2000 )
  4171. {
  4172. dw.dxfString( 100, "AcDbSymbolTable" );
  4173. }
  4174. dw.dxfInt( 70, 1 );
  4175. dw.dxfString( 0, "BLOCK_RECORD" );
  4176. if( version==DL_VERSION_2000 )
  4177. {
  4178. dw.dxfHex( 5, 0x1F );
  4179. }
  4180. // int msh = dw.handle();
  4181. // dw.setModelSpaceHandle(msh);
  4182. // dw.dxfHex(330, 1);
  4183. if( version==DL_VERSION_2000 )
  4184. {
  4185. dw.dxfString( 100, "AcDbSymbolTableRecord" );
  4186. dw.dxfString( 100, "AcDbBlockTableRecord" );
  4187. }
  4188. dw.dxfString( 2, "*Model_Space" );
  4189. dw.dxfHex( 340, 0x22 );
  4190. dw.dxfString( 0, "BLOCK_RECORD" );
  4191. if( version==DL_VERSION_2000 )
  4192. {
  4193. dw.dxfHex( 5, 0x1B );
  4194. }
  4195. // int psh = dw.handle();
  4196. // dw.setPaperSpaceHandle(psh);
  4197. // dw.dxfHex(330, 1);
  4198. if( version==DL_VERSION_2000 )
  4199. {
  4200. dw.dxfString( 100, "AcDbSymbolTableRecord" );
  4201. dw.dxfString( 100, "AcDbBlockTableRecord" );
  4202. }
  4203. dw.dxfString( 2, "*Paper_Space" );
  4204. dw.dxfHex( 340, 0x1E );
  4205. dw.dxfString( 0, "BLOCK_RECORD" );
  4206. if( version==DL_VERSION_2000 )
  4207. {
  4208. dw.dxfHex( 5, 0x23 );
  4209. }
  4210. // int ps0h = dw.handle();
  4211. // dw.setPaperSpace0Handle(ps0h);
  4212. // dw.dxfHex(330, 1);
  4213. if( version==DL_VERSION_2000 )
  4214. {
  4215. dw.dxfString( 100, "AcDbSymbolTableRecord" );
  4216. dw.dxfString( 100, "AcDbBlockTableRecord" );
  4217. }
  4218. dw.dxfString( 2, "*Paper_Space0" );
  4219. dw.dxfHex( 340, 0x26 );
  4220. // dw.dxfString( 0, "ENDTAB");
  4221. }
  4222. /**
  4223. * Writes a single block record with the given name.
  4224. */
  4225. void DL_Dxf::writeBlockRecord( DL_WriterA& dw, const std::string& name )
  4226. {
  4227. dw.dxfString( 0, "BLOCK_RECORD" );
  4228. if( version==DL_VERSION_2000 )
  4229. {
  4230. dw.handle();
  4231. }
  4232. // dw->dxfHex(330, 1);
  4233. if( version==DL_VERSION_2000 )
  4234. {
  4235. dw.dxfString( 100, "AcDbSymbolTableRecord" );
  4236. dw.dxfString( 100, "AcDbBlockTableRecord" );
  4237. }
  4238. dw.dxfString( 2, name );
  4239. dw.dxfHex( 340, 0 );
  4240. }
  4241. /**
  4242. * Writes a objects section. This section is needed in DL_VERSION_R13.
  4243. * Note that this method currently only writes a faked OBJECTS section
  4244. * to make the file readable by Aut*cad.
  4245. */
  4246. void DL_Dxf::writeObjects( DL_WriterA& dw, const std::string& appDictionaryName )
  4247. {
  4248. dw.dxfString( 0, "SECTION" );
  4249. dw.dxfString( 2, "OBJECTS" );
  4250. dw.dxfString( 0, "DICTIONARY" );
  4251. dw.dxfHex( 5, 0xC );
  4252. dw.dxfString( 100, "AcDbDictionary" );
  4253. dw.dxfInt( 280, 0 );
  4254. dw.dxfInt( 281, 1 );
  4255. dw.dxfString( 3, "ACAD_GROUP" );
  4256. dw.dxfHex( 350, 0xD );
  4257. dw.dxfString( 3, "ACAD_LAYOUT" );
  4258. dw.dxfHex( 350, 0x1A );
  4259. dw.dxfString( 3, "ACAD_MLINESTYLE" );
  4260. dw.dxfHex( 350, 0x17 );
  4261. dw.dxfString( 3, "ACAD_PLOTSETTINGS" );
  4262. dw.dxfHex( 350, 0x19 );
  4263. dw.dxfString( 3, "ACAD_PLOTSTYLENAME" );
  4264. dw.dxfHex( 350, 0xE );
  4265. dw.dxfString( 3, "AcDbVariableDictionary" );
  4266. int acDbVariableDictionaryHandle = dw.handle( 350 );
  4267. // int acDbVariableDictionaryHandle = dw.getNextHandle();
  4268. // dw.dxfHex(350, acDbVariableDictionaryHandle);
  4269. // dw.incHandle();
  4270. if( appDictionaryName.length()!=0 )
  4271. {
  4272. dw.dxfString( 3, appDictionaryName );
  4273. appDictionaryHandle = dw.handle( 350 );
  4274. // appDictionaryHandle = dw.getNextHandle();
  4275. // dw.dxfHex(350, appDictionaryHandle);
  4276. // dw.incHandle();
  4277. }
  4278. dw.dxfString( 0, "DICTIONARY" );
  4279. dw.dxfHex( 5, 0xD );
  4280. // dw.handle(); // D
  4281. // dw.dxfHex(330, 0xC);
  4282. dw.dxfString( 100, "AcDbDictionary" );
  4283. dw.dxfInt( 280, 0 );
  4284. dw.dxfInt( 281, 1 );
  4285. dw.dxfString( 0, "ACDBDICTIONARYWDFLT" );
  4286. dw.dxfHex( 5, 0xE );
  4287. // dicId4 = dw.handle(); // E
  4288. // dw.dxfHex(330, 0xC); // C
  4289. dw.dxfString( 100, "AcDbDictionary" );
  4290. dw.dxfInt( 281, 1 );
  4291. dw.dxfString( 3, "Normal" );
  4292. dw.dxfHex( 350, 0xF );
  4293. // dw.dxfHex(350, dw.getNextHandle()+5); // F
  4294. dw.dxfString( 100, "AcDbDictionaryWithDefault" );
  4295. dw.dxfHex( 340, 0xF );
  4296. // dw.dxfHex(340, dw.getNextHandle()+5); // F
  4297. dw.dxfString( 0, "ACDBPLACEHOLDER" );
  4298. dw.dxfHex( 5, 0xF );
  4299. // dw.handle(); // F
  4300. // dw.dxfHex(330, dicId4); // E
  4301. dw.dxfString( 0, "DICTIONARY" );
  4302. // dicId3 = dw.handle(); // 17
  4303. dw.dxfHex( 5, 0x17 );
  4304. // dw.dxfHex(330, 0xC); // C
  4305. dw.dxfString( 100, "AcDbDictionary" );
  4306. dw.dxfInt( 280, 0 );
  4307. dw.dxfInt( 281, 1 );
  4308. dw.dxfString( 3, "Standard" );
  4309. dw.dxfHex( 350, 0x18 );
  4310. // dw.dxfHex(350, dw.getNextHandle()+5); // 18
  4311. dw.dxfString( 0, "MLINESTYLE" );
  4312. dw.dxfHex( 5, 0x18 );
  4313. // dw.handle(); // 18
  4314. // dw.dxfHex(330, dicId3); // 17
  4315. dw.dxfString( 100, "AcDbMlineStyle" );
  4316. dw.dxfString( 2, "STANDARD" );
  4317. dw.dxfInt( 70, 0 );
  4318. dw.dxfString( 3, "" );
  4319. dw.dxfInt( 62, 256 );
  4320. dw.dxfReal( 51, 90.0 );
  4321. dw.dxfReal( 52, 90.0 );
  4322. dw.dxfInt( 71, 2 );
  4323. dw.dxfReal( 49, 0.5 );
  4324. dw.dxfInt( 62, 256 );
  4325. dw.dxfString( 6, "BYLAYER" );
  4326. dw.dxfReal( 49, -0.5 );
  4327. dw.dxfInt( 62, 256 );
  4328. dw.dxfString( 6, "BYLAYER" );
  4329. dw.dxfString( 0, "DICTIONARY" );
  4330. dw.dxfHex( 5, 0x19 );
  4331. // dw.handle(); // 17
  4332. // dw.dxfHex(330, 0xC); // C
  4333. dw.dxfString( 100, "AcDbDictionary" );
  4334. dw.dxfInt( 280, 0 );
  4335. dw.dxfInt( 281, 1 );
  4336. dw.dxfString( 0, "DICTIONARY" );
  4337. // dicId2 = dw.handle(); // 1A
  4338. dw.dxfHex( 5, 0x1A );
  4339. // dw.dxfHex(330, 0xC);
  4340. dw.dxfString( 100, "AcDbDictionary" );
  4341. dw.dxfInt( 281, 1 );
  4342. dw.dxfString( 3, "Layout1" );
  4343. dw.dxfHex( 350, 0x1E );
  4344. // dw.dxfHex(350, dw.getNextHandle()+2); // 1E
  4345. dw.dxfString( 3, "Layout2" );
  4346. dw.dxfHex( 350, 0x26 );
  4347. // dw.dxfHex(350, dw.getNextHandle()+4); // 26
  4348. dw.dxfString( 3, "Model" );
  4349. dw.dxfHex( 350, 0x22 );
  4350. // dw.dxfHex(350, dw.getNextHandle()+5); // 22
  4351. dw.dxfString( 0, "LAYOUT" );
  4352. dw.dxfHex( 5, 0x1E );
  4353. // dw.handle(); // 1E
  4354. // dw.dxfHex(330, dicId2); // 1A
  4355. dw.dxfString( 100, "AcDbPlotSettings" );
  4356. dw.dxfString( 1, "" );
  4357. dw.dxfString( 2, "none_device" );
  4358. dw.dxfString( 4, "" );
  4359. dw.dxfString( 6, "" );
  4360. dw.dxfReal( 40, 0.0 );
  4361. dw.dxfReal( 41, 0.0 );
  4362. dw.dxfReal( 42, 0.0 );
  4363. dw.dxfReal( 43, 0.0 );
  4364. dw.dxfReal( 44, 0.0 );
  4365. dw.dxfReal( 45, 0.0 );
  4366. dw.dxfReal( 46, 0.0 );
  4367. dw.dxfReal( 47, 0.0 );
  4368. dw.dxfReal( 48, 0.0 );
  4369. dw.dxfReal( 49, 0.0 );
  4370. dw.dxfReal( 140, 0.0 );
  4371. dw.dxfReal( 141, 0.0 );
  4372. dw.dxfReal( 142, 1.0 );
  4373. dw.dxfReal( 143, 1.0 );
  4374. dw.dxfInt( 70, 688 );
  4375. dw.dxfInt( 72, 0 );
  4376. dw.dxfInt( 73, 0 );
  4377. dw.dxfInt( 74, 5 );
  4378. dw.dxfString( 7, "" );
  4379. dw.dxfInt( 75, 16 );
  4380. dw.dxfReal( 147, 1.0 );
  4381. dw.dxfReal( 148, 0.0 );
  4382. dw.dxfReal( 149, 0.0 );
  4383. dw.dxfString( 100, "AcDbLayout" );
  4384. dw.dxfString( 1, "Layout1" );
  4385. dw.dxfInt( 70, 1 );
  4386. dw.dxfInt( 71, 1 );
  4387. dw.dxfReal( 10, 0.0 );
  4388. dw.dxfReal( 20, 0.0 );
  4389. dw.dxfReal( 11, 420.0 );
  4390. dw.dxfReal( 21, 297.0 );
  4391. dw.dxfReal( 12, 0.0 );
  4392. dw.dxfReal( 22, 0.0 );
  4393. dw.dxfReal( 32, 0.0 );
  4394. dw.dxfReal( 14, 1.000000000000000E+20 );
  4395. dw.dxfReal( 24, 1.000000000000000E+20 );
  4396. dw.dxfReal( 34, 1.000000000000000E+20 );
  4397. dw.dxfReal( 15, -1.000000000000000E+20 );
  4398. dw.dxfReal( 25, -1.000000000000000E+20 );
  4399. dw.dxfReal( 35, -1.000000000000000E+20 );
  4400. dw.dxfReal( 146, 0.0 );
  4401. dw.dxfReal( 13, 0.0 );
  4402. dw.dxfReal( 23, 0.0 );
  4403. dw.dxfReal( 33, 0.0 );
  4404. dw.dxfReal( 16, 1.0 );
  4405. dw.dxfReal( 26, 0.0 );
  4406. dw.dxfReal( 36, 0.0 );
  4407. dw.dxfReal( 17, 0.0 );
  4408. dw.dxfReal( 27, 1.0 );
  4409. dw.dxfReal( 37, 0.0 );
  4410. dw.dxfInt( 76, 0 );
  4411. // dw.dxfHex(330, dw.getPaperSpaceHandle()); // 1B
  4412. dw.dxfHex( 330, 0x1B );
  4413. dw.dxfString( 0, "LAYOUT" );
  4414. dw.dxfHex( 5, 0x22 );
  4415. // dw.handle(); // 22
  4416. // dw.dxfHex(330, dicId2); // 1A
  4417. dw.dxfString( 100, "AcDbPlotSettings" );
  4418. dw.dxfString( 1, "" );
  4419. dw.dxfString( 2, "none_device" );
  4420. dw.dxfString( 4, "" );
  4421. dw.dxfString( 6, "" );
  4422. dw.dxfReal( 40, 0.0 );
  4423. dw.dxfReal( 41, 0.0 );
  4424. dw.dxfReal( 42, 0.0 );
  4425. dw.dxfReal( 43, 0.0 );
  4426. dw.dxfReal( 44, 0.0 );
  4427. dw.dxfReal( 45, 0.0 );
  4428. dw.dxfReal( 46, 0.0 );
  4429. dw.dxfReal( 47, 0.0 );
  4430. dw.dxfReal( 48, 0.0 );
  4431. dw.dxfReal( 49, 0.0 );
  4432. dw.dxfReal( 140, 0.0 );
  4433. dw.dxfReal( 141, 0.0 );
  4434. dw.dxfReal( 142, 1.0 );
  4435. dw.dxfReal( 143, 1.0 );
  4436. dw.dxfInt( 70, 1712 );
  4437. dw.dxfInt( 72, 0 );
  4438. dw.dxfInt( 73, 0 );
  4439. dw.dxfInt( 74, 0 );
  4440. dw.dxfString( 7, "" );
  4441. dw.dxfInt( 75, 0 );
  4442. dw.dxfReal( 147, 1.0 );
  4443. dw.dxfReal( 148, 0.0 );
  4444. dw.dxfReal( 149, 0.0 );
  4445. dw.dxfString( 100, "AcDbLayout" );
  4446. dw.dxfString( 1, "Model" );
  4447. dw.dxfInt( 70, 1 );
  4448. dw.dxfInt( 71, 0 );
  4449. dw.dxfReal( 10, 0.0 );
  4450. dw.dxfReal( 20, 0.0 );
  4451. dw.dxfReal( 11, 12.0 );
  4452. dw.dxfReal( 21, 9.0 );
  4453. dw.dxfReal( 12, 0.0 );
  4454. dw.dxfReal( 22, 0.0 );
  4455. dw.dxfReal( 32, 0.0 );
  4456. dw.dxfReal( 14, 0.0 );
  4457. dw.dxfReal( 24, 0.0 );
  4458. dw.dxfReal( 34, 0.0 );
  4459. dw.dxfReal( 15, 0.0 );
  4460. dw.dxfReal( 25, 0.0 );
  4461. dw.dxfReal( 35, 0.0 );
  4462. dw.dxfReal( 146, 0.0 );
  4463. dw.dxfReal( 13, 0.0 );
  4464. dw.dxfReal( 23, 0.0 );
  4465. dw.dxfReal( 33, 0.0 );
  4466. dw.dxfReal( 16, 1.0 );
  4467. dw.dxfReal( 26, 0.0 );
  4468. dw.dxfReal( 36, 0.0 );
  4469. dw.dxfReal( 17, 0.0 );
  4470. dw.dxfReal( 27, 1.0 );
  4471. dw.dxfReal( 37, 0.0 );
  4472. dw.dxfInt( 76, 0 );
  4473. // dw.dxfHex(330, dw.getModelSpaceHandle()); // 1F
  4474. dw.dxfHex( 330, 0x1F );
  4475. dw.dxfString( 0, "LAYOUT" );
  4476. // dw.handle(); // 26
  4477. dw.dxfHex( 5, 0x26 );
  4478. // dw.dxfHex(330, dicId2); // 1A
  4479. dw.dxfString( 100, "AcDbPlotSettings" );
  4480. dw.dxfString( 1, "" );
  4481. dw.dxfString( 2, "none_device" );
  4482. dw.dxfString( 4, "" );
  4483. dw.dxfString( 6, "" );
  4484. dw.dxfReal( 40, 0.0 );
  4485. dw.dxfReal( 41, 0.0 );
  4486. dw.dxfReal( 42, 0.0 );
  4487. dw.dxfReal( 43, 0.0 );
  4488. dw.dxfReal( 44, 0.0 );
  4489. dw.dxfReal( 45, 0.0 );
  4490. dw.dxfReal( 46, 0.0 );
  4491. dw.dxfReal( 47, 0.0 );
  4492. dw.dxfReal( 48, 0.0 );
  4493. dw.dxfReal( 49, 0.0 );
  4494. dw.dxfReal( 140, 0.0 );
  4495. dw.dxfReal( 141, 0.0 );
  4496. dw.dxfReal( 142, 1.0 );
  4497. dw.dxfReal( 143, 1.0 );
  4498. dw.dxfInt( 70, 688 );
  4499. dw.dxfInt( 72, 0 );
  4500. dw.dxfInt( 73, 0 );
  4501. dw.dxfInt( 74, 5 );
  4502. dw.dxfString( 7, "" );
  4503. dw.dxfInt( 75, 16 );
  4504. dw.dxfReal( 147, 1.0 );
  4505. dw.dxfReal( 148, 0.0 );
  4506. dw.dxfReal( 149, 0.0 );
  4507. dw.dxfString( 100, "AcDbLayout" );
  4508. dw.dxfString( 1, "Layout2" );
  4509. dw.dxfInt( 70, 1 );
  4510. dw.dxfInt( 71, 2 );
  4511. dw.dxfReal( 10, 0.0 );
  4512. dw.dxfReal( 20, 0.0 );
  4513. dw.dxfReal( 11, 12.0 );
  4514. dw.dxfReal( 21, 9.0 );
  4515. dw.dxfReal( 12, 0.0 );
  4516. dw.dxfReal( 22, 0.0 );
  4517. dw.dxfReal( 32, 0.0 );
  4518. dw.dxfReal( 14, 0.0 );
  4519. dw.dxfReal( 24, 0.0 );
  4520. dw.dxfReal( 34, 0.0 );
  4521. dw.dxfReal( 15, 0.0 );
  4522. dw.dxfReal( 25, 0.0 );
  4523. dw.dxfReal( 35, 0.0 );
  4524. dw.dxfReal( 146, 0.0 );
  4525. dw.dxfReal( 13, 0.0 );
  4526. dw.dxfReal( 23, 0.0 );
  4527. dw.dxfReal( 33, 0.0 );
  4528. dw.dxfReal( 16, 1.0 );
  4529. dw.dxfReal( 26, 0.0 );
  4530. dw.dxfReal( 36, 0.0 );
  4531. dw.dxfReal( 17, 0.0 );
  4532. dw.dxfReal( 27, 1.0 );
  4533. dw.dxfReal( 37, 0.0 );
  4534. dw.dxfInt( 76, 0 );
  4535. // dw.dxfHex(330, dw.getPaperSpace0Handle()); // 23
  4536. dw.dxfHex( 330, 0x23 );
  4537. dw.dxfString( 0, "DICTIONARY" );
  4538. // dw.dxfHex(5, 0x2C);
  4539. // dicId5 =
  4540. dw.dxfHex( 5, acDbVariableDictionaryHandle );
  4541. // dw.handle(); // 2C
  4542. // dw.dxfHex(330, 0xC); // C
  4543. dw.dxfString( 100, "AcDbDictionary" );
  4544. dw.dxfInt( 281, 1 );
  4545. dw.dxfString( 3, "DIMASSOC" );
  4546. // dw.dxfHex(350, 0x2F);
  4547. dw.dxfHex( 350, dw.getNextHandle() + 1 ); // 2E
  4548. dw.dxfString( 3, "HIDETEXT" );
  4549. // dw.dxfHex(350, 0x2E);
  4550. dw.dxfHex( 350, dw.getNextHandle() ); // 2D
  4551. dw.dxfString( 0, "DICTIONARYVAR" );
  4552. // dw.dxfHex(5, 0x2E);
  4553. dw.handle(); // 2E
  4554. // dw.dxfHex(330, dicId5); // 2C
  4555. dw.dxfString( 100, "DictionaryVariables" );
  4556. dw.dxfInt( 280, 0 );
  4557. dw.dxfInt( 1, 2 );
  4558. dw.dxfString( 0, "DICTIONARYVAR" );
  4559. // dw.dxfHex(5, 0x2D);
  4560. dw.handle(); // 2D
  4561. // dw.dxfHex(330, dicId5); // 2C
  4562. dw.dxfString( 100, "DictionaryVariables" );
  4563. dw.dxfInt( 280, 0 );
  4564. dw.dxfInt( 1, 1 );
  4565. }
  4566. void DL_Dxf::writeAppDictionary( DL_WriterA& dw )
  4567. {
  4568. dw.dxfString( 0, "DICTIONARY" );
  4569. // dw.handle();
  4570. dw.dxfHex( 5, appDictionaryHandle );
  4571. dw.dxfString( 100, "AcDbDictionary" );
  4572. dw.dxfInt( 281, 1 );
  4573. }
  4574. int DL_Dxf::writeDictionaryEntry( DL_WriterA& dw, const std::string& name )
  4575. {
  4576. dw.dxfString( 3, name );
  4577. int handle = dw.getNextHandle();
  4578. dw.dxfHex( 350, handle );
  4579. dw.incHandle();
  4580. return handle;
  4581. }
  4582. void DL_Dxf::writeXRecord( DL_WriterA& dw, int handle, int value )
  4583. {
  4584. dw.dxfString( 0, "XRECORD" );
  4585. dw.dxfHex( 5, handle );
  4586. dw.dxfHex( 330, appDictionaryHandle );
  4587. dw.dxfString( 100, "AcDbXrecord" );
  4588. dw.dxfInt( 280, 1 );
  4589. dw.dxfInt( 90, value );
  4590. }
  4591. void DL_Dxf::writeXRecord( DL_WriterA& dw, int handle, double value )
  4592. {
  4593. dw.dxfString( 0, "XRECORD" );
  4594. dw.dxfHex( 5, handle );
  4595. dw.dxfHex( 330, appDictionaryHandle );
  4596. dw.dxfString( 100, "AcDbXrecord" );
  4597. dw.dxfInt( 280, 1 );
  4598. dw.dxfReal( 40, value );
  4599. }
  4600. void DL_Dxf::writeXRecord( DL_WriterA& dw, int handle, bool value )
  4601. {
  4602. dw.dxfString( 0, "XRECORD" );
  4603. dw.dxfHex( 5, handle );
  4604. dw.dxfHex( 330, appDictionaryHandle );
  4605. dw.dxfString( 100, "AcDbXrecord" );
  4606. dw.dxfInt( 280, 1 );
  4607. dw.dxfBool( 290, value );
  4608. }
  4609. void DL_Dxf::writeXRecord( DL_WriterA& dw, int handle, const std::string& value )
  4610. {
  4611. dw.dxfString( 0, "XRECORD" );
  4612. dw.dxfHex( 5, handle );
  4613. dw.dxfHex( 330, appDictionaryHandle );
  4614. dw.dxfString( 100, "AcDbXrecord" );
  4615. dw.dxfInt( 280, 1 );
  4616. dw.dxfString( 1000, value );
  4617. }
  4618. /**
  4619. * Writes the end of the objects section. This section is needed in DL_VERSION_R13.
  4620. * Note that this method currently only writes a faked OBJECTS section
  4621. * to make the file readable by Aut*cad.
  4622. */
  4623. void DL_Dxf::writeObjectsEnd( DL_WriterA& dw )
  4624. {
  4625. dw.dxfString( 0, "ENDSEC" );
  4626. }
  4627. /**
  4628. * Writes a comment to the DXF file.
  4629. */
  4630. void DL_Dxf::writeComment( DL_WriterA& dw, const std::string& comment )
  4631. {
  4632. dw.dxfString( 999, comment );
  4633. }
  4634. /**
  4635. * Checks if the given variable is known by the given DXF version.
  4636. */
  4637. bool DL_Dxf::checkVariable( const char* var, DL_Codes::version version )
  4638. {
  4639. if( version>=DL_VERSION_2000 )
  4640. {
  4641. return true;
  4642. }
  4643. else if( version==DL_VERSION_R12 )
  4644. {
  4645. // these are all the variables recognized by dxf r12:
  4646. if( !strcmp( var, "$ACADVER" ) )
  4647. {
  4648. return true;
  4649. }
  4650. if( !strcmp( var, "$ACADVER" ) )
  4651. {
  4652. return true;
  4653. }
  4654. if( !strcmp( var, "$ANGBASE" ) )
  4655. {
  4656. return true;
  4657. }
  4658. if( !strcmp( var, "$ANGDIR" ) )
  4659. {
  4660. return true;
  4661. }
  4662. if( !strcmp( var, "$ATTDIA" ) )
  4663. {
  4664. return true;
  4665. }
  4666. if( !strcmp( var, "$ATTMODE" ) )
  4667. {
  4668. return true;
  4669. }
  4670. if( !strcmp( var, "$ATTREQ" ) )
  4671. {
  4672. return true;
  4673. }
  4674. if( !strcmp( var, "$AUNITS" ) )
  4675. {
  4676. return true;
  4677. }
  4678. if( !strcmp( var, "$AUPREC" ) )
  4679. {
  4680. return true;
  4681. }
  4682. if( !strcmp( var, "$AXISMODE" ) )
  4683. {
  4684. return true;
  4685. }
  4686. if( !strcmp( var, "$AXISUNIT" ) )
  4687. {
  4688. return true;
  4689. }
  4690. if( !strcmp( var, "$BLIPMODE" ) )
  4691. {
  4692. return true;
  4693. }
  4694. if( !strcmp( var, "$CECOLOR" ) )
  4695. {
  4696. return true;
  4697. }
  4698. if( !strcmp( var, "$CELTYPE" ) )
  4699. {
  4700. return true;
  4701. }
  4702. if( !strcmp( var, "$CHAMFERA" ) )
  4703. {
  4704. return true;
  4705. }
  4706. if( !strcmp( var, "$CHAMFERB" ) )
  4707. {
  4708. return true;
  4709. }
  4710. if( !strcmp( var, "$CLAYER" ) )
  4711. {
  4712. return true;
  4713. }
  4714. if( !strcmp( var, "$COORDS" ) )
  4715. {
  4716. return true;
  4717. }
  4718. if( !strcmp( var, "$DIMALT" ) )
  4719. {
  4720. return true;
  4721. }
  4722. if( !strcmp( var, "$DIMALTD" ) )
  4723. {
  4724. return true;
  4725. }
  4726. if( !strcmp( var, "$DIMALTF" ) )
  4727. {
  4728. return true;
  4729. }
  4730. if( !strcmp( var, "$DIMAPOST" ) )
  4731. {
  4732. return true;
  4733. }
  4734. if( !strcmp( var, "$DIMASO" ) )
  4735. {
  4736. return true;
  4737. }
  4738. if( !strcmp( var, "$DIMASZ" ) )
  4739. {
  4740. return true;
  4741. }
  4742. if( !strcmp( var, "$DIMBLK" ) )
  4743. {
  4744. return true;
  4745. }
  4746. if( !strcmp( var, "$DIMBLK1" ) )
  4747. {
  4748. return true;
  4749. }
  4750. if( !strcmp( var, "$DIMBLK2" ) )
  4751. {
  4752. return true;
  4753. }
  4754. if( !strcmp( var, "$DIMCEN" ) )
  4755. {
  4756. return true;
  4757. }
  4758. if( !strcmp( var, "$DIMCLRD" ) )
  4759. {
  4760. return true;
  4761. }
  4762. if( !strcmp( var, "$DIMCLRE" ) )
  4763. {
  4764. return true;
  4765. }
  4766. if( !strcmp( var, "$DIMCLRT" ) )
  4767. {
  4768. return true;
  4769. }
  4770. if( !strcmp( var, "$DIMDLE" ) )
  4771. {
  4772. return true;
  4773. }
  4774. if( !strcmp( var, "$DIMDLI" ) )
  4775. {
  4776. return true;
  4777. }
  4778. if( !strcmp( var, "$DIMEXE" ) )
  4779. {
  4780. return true;
  4781. }
  4782. if( !strcmp( var, "$DIMEXO" ) )
  4783. {
  4784. return true;
  4785. }
  4786. if( !strcmp( var, "$DIMGAP" ) )
  4787. {
  4788. return true;
  4789. }
  4790. if( !strcmp( var, "$DIMLFAC" ) )
  4791. {
  4792. return true;
  4793. }
  4794. if( !strcmp( var, "$DIMLIM" ) )
  4795. {
  4796. return true;
  4797. }
  4798. if( !strcmp( var, "$DIMPOST" ) )
  4799. {
  4800. return true;
  4801. }
  4802. if( !strcmp( var, "$DIMRND" ) )
  4803. {
  4804. return true;
  4805. }
  4806. if( !strcmp( var, "$DIMSAH" ) )
  4807. {
  4808. return true;
  4809. }
  4810. if( !strcmp( var, "$DIMSCALE" ) )
  4811. {
  4812. return true;
  4813. }
  4814. if( !strcmp( var, "$DIMSE1" ) )
  4815. {
  4816. return true;
  4817. }
  4818. if( !strcmp( var, "$DIMSE2" ) )
  4819. {
  4820. return true;
  4821. }
  4822. if( !strcmp( var, "$DIMSHO" ) )
  4823. {
  4824. return true;
  4825. }
  4826. if( !strcmp( var, "$DIMSOXD" ) )
  4827. {
  4828. return true;
  4829. }
  4830. if( !strcmp( var, "$DIMSTYLE" ) )
  4831. {
  4832. return true;
  4833. }
  4834. if( !strcmp( var, "$DIMTAD" ) )
  4835. {
  4836. return true;
  4837. }
  4838. if( !strcmp( var, "$DIMTFAC" ) )
  4839. {
  4840. return true;
  4841. }
  4842. if( !strcmp( var, "$DIMTIH" ) )
  4843. {
  4844. return true;
  4845. }
  4846. if( !strcmp( var, "$DIMTIX" ) )
  4847. {
  4848. return true;
  4849. }
  4850. if( !strcmp( var, "$DIMTM" ) )
  4851. {
  4852. return true;
  4853. }
  4854. if( !strcmp( var, "$DIMTOFL" ) )
  4855. {
  4856. return true;
  4857. }
  4858. if( !strcmp( var, "$DIMTOH" ) )
  4859. {
  4860. return true;
  4861. }
  4862. if( !strcmp( var, "$DIMTOL" ) )
  4863. {
  4864. return true;
  4865. }
  4866. if( !strcmp( var, "$DIMTP" ) )
  4867. {
  4868. return true;
  4869. }
  4870. if( !strcmp( var, "$DIMTSZ" ) )
  4871. {
  4872. return true;
  4873. }
  4874. if( !strcmp( var, "$DIMTVP" ) )
  4875. {
  4876. return true;
  4877. }
  4878. if( !strcmp( var, "$DIMTXT" ) )
  4879. {
  4880. return true;
  4881. }
  4882. if( !strcmp( var, "$DIMZIN" ) )
  4883. {
  4884. return true;
  4885. }
  4886. if( !strcmp( var, "$DWGCODEPAGE" ) )
  4887. {
  4888. return true;
  4889. }
  4890. if( !strcmp( var, "$DRAGMODE" ) )
  4891. {
  4892. return true;
  4893. }
  4894. if( !strcmp( var, "$ELEVATION" ) )
  4895. {
  4896. return true;
  4897. }
  4898. if( !strcmp( var, "$EXTMAX" ) )
  4899. {
  4900. return true;
  4901. }
  4902. if( !strcmp( var, "$EXTMIN" ) )
  4903. {
  4904. return true;
  4905. }
  4906. if( !strcmp( var, "$FILLETRAD" ) )
  4907. {
  4908. return true;
  4909. }
  4910. if( !strcmp( var, "$FILLMODE" ) )
  4911. {
  4912. return true;
  4913. }
  4914. if( !strcmp( var, "$HANDLING" ) )
  4915. {
  4916. return true;
  4917. }
  4918. if( !strcmp( var, "$HANDSEED" ) )
  4919. {
  4920. return true;
  4921. }
  4922. if( !strcmp( var, "$INSBASE" ) )
  4923. {
  4924. return true;
  4925. }
  4926. if( !strcmp( var, "$LIMCHECK" ) )
  4927. {
  4928. return true;
  4929. }
  4930. if( !strcmp( var, "$LIMMAX" ) )
  4931. {
  4932. return true;
  4933. }
  4934. if( !strcmp( var, "$LIMMIN" ) )
  4935. {
  4936. return true;
  4937. }
  4938. if( !strcmp( var, "$LTSCALE" ) )
  4939. {
  4940. return true;
  4941. }
  4942. if( !strcmp( var, "$LUNITS" ) )
  4943. {
  4944. return true;
  4945. }
  4946. if( !strcmp( var, "$LUPREC" ) )
  4947. {
  4948. return true;
  4949. }
  4950. if( !strcmp( var, "$MAXACTVP" ) )
  4951. {
  4952. return true;
  4953. }
  4954. if( !strcmp( var, "$MENU" ) )
  4955. {
  4956. return true;
  4957. }
  4958. if( !strcmp( var, "$MIRRTEXT" ) )
  4959. {
  4960. return true;
  4961. }
  4962. if( !strcmp( var, "$ORTHOMODE" ) )
  4963. {
  4964. return true;
  4965. }
  4966. if( !strcmp( var, "$OSMODE" ) )
  4967. {
  4968. return true;
  4969. }
  4970. if( !strcmp( var, "$PDMODE" ) )
  4971. {
  4972. return true;
  4973. }
  4974. if( !strcmp( var, "$PDSIZE" ) )
  4975. {
  4976. return true;
  4977. }
  4978. if( !strcmp( var, "$PELEVATION" ) )
  4979. {
  4980. return true;
  4981. }
  4982. if( !strcmp( var, "$PEXTMAX" ) )
  4983. {
  4984. return true;
  4985. }
  4986. if( !strcmp( var, "$PEXTMIN" ) )
  4987. {
  4988. return true;
  4989. }
  4990. if( !strcmp( var, "$PLIMCHECK" ) )
  4991. {
  4992. return true;
  4993. }
  4994. if( !strcmp( var, "$PLIMMAX" ) )
  4995. {
  4996. return true;
  4997. }
  4998. if( !strcmp( var, "$PLIMMIN" ) )
  4999. {
  5000. return true;
  5001. }
  5002. if( !strcmp( var, "$PLINEGEN" ) )
  5003. {
  5004. return true;
  5005. }
  5006. if( !strcmp( var, "$PLINEWID" ) )
  5007. {
  5008. return true;
  5009. }
  5010. if( !strcmp( var, "$PSLTSCALE" ) )
  5011. {
  5012. return true;
  5013. }
  5014. if( !strcmp( var, "$PUCSNAME" ) )
  5015. {
  5016. return true;
  5017. }
  5018. if( !strcmp( var, "$PUCSORG" ) )
  5019. {
  5020. return true;
  5021. }
  5022. if( !strcmp( var, "$PUCSXDIR" ) )
  5023. {
  5024. return true;
  5025. }
  5026. if( !strcmp( var, "$PUCSYDIR" ) )
  5027. {
  5028. return true;
  5029. }
  5030. if( !strcmp( var, "$QTEXTMODE" ) )
  5031. {
  5032. return true;
  5033. }
  5034. if( !strcmp( var, "$REGENMODE" ) )
  5035. {
  5036. return true;
  5037. }
  5038. if( !strcmp( var, "$SHADEDGE" ) )
  5039. {
  5040. return true;
  5041. }
  5042. if( !strcmp( var, "$SHADEDIF" ) )
  5043. {
  5044. return true;
  5045. }
  5046. if( !strcmp( var, "$SKETCHINC" ) )
  5047. {
  5048. return true;
  5049. }
  5050. if( !strcmp( var, "$SKPOLY" ) )
  5051. {
  5052. return true;
  5053. }
  5054. if( !strcmp( var, "$SPLFRAME" ) )
  5055. {
  5056. return true;
  5057. }
  5058. if( !strcmp( var, "$SPLINESEGS" ) )
  5059. {
  5060. return true;
  5061. }
  5062. if( !strcmp( var, "$SPLINETYPE" ) )
  5063. {
  5064. return true;
  5065. }
  5066. if( !strcmp( var, "$SURFTAB1" ) )
  5067. {
  5068. return true;
  5069. }
  5070. if( !strcmp( var, "$SURFTAB2" ) )
  5071. {
  5072. return true;
  5073. }
  5074. if( !strcmp( var, "$SURFTYPE" ) )
  5075. {
  5076. return true;
  5077. }
  5078. if( !strcmp( var, "$SURFU" ) )
  5079. {
  5080. return true;
  5081. }
  5082. if( !strcmp( var, "$SURFV" ) )
  5083. {
  5084. return true;
  5085. }
  5086. if( !strcmp( var, "$TDCREATE" ) )
  5087. {
  5088. return true;
  5089. }
  5090. if( !strcmp( var, "$TDINDWG" ) )
  5091. {
  5092. return true;
  5093. }
  5094. if( !strcmp( var, "$TDUPDATE" ) )
  5095. {
  5096. return true;
  5097. }
  5098. if( !strcmp( var, "$TDUSRTIMER" ) )
  5099. {
  5100. return true;
  5101. }
  5102. if( !strcmp( var, "$TEXTSIZE" ) )
  5103. {
  5104. return true;
  5105. }
  5106. if( !strcmp( var, "$TEXTSTYLE" ) )
  5107. {
  5108. return true;
  5109. }
  5110. if( !strcmp( var, "$THICKNESS" ) )
  5111. {
  5112. return true;
  5113. }
  5114. if( !strcmp( var, "$TILEMODE" ) )
  5115. {
  5116. return true;
  5117. }
  5118. if( !strcmp( var, "$TRACEWID" ) )
  5119. {
  5120. return true;
  5121. }
  5122. if( !strcmp( var, "$UCSNAME" ) )
  5123. {
  5124. return true;
  5125. }
  5126. if( !strcmp( var, "$UCSORG" ) )
  5127. {
  5128. return true;
  5129. }
  5130. if( !strcmp( var, "$UCSXDIR" ) )
  5131. {
  5132. return true;
  5133. }
  5134. if( !strcmp( var, "$UCSYDIR" ) )
  5135. {
  5136. return true;
  5137. }
  5138. if( !strcmp( var, "$UNITMODE" ) )
  5139. {
  5140. return true;
  5141. }
  5142. if( !strcmp( var, "$USERI1" ) )
  5143. {
  5144. return true;
  5145. }
  5146. if( !strcmp( var, "$USERR1" ) )
  5147. {
  5148. return true;
  5149. }
  5150. if( !strcmp( var, "$USRTIMER" ) )
  5151. {
  5152. return true;
  5153. }
  5154. if( !strcmp( var, "$VISRETAIN" ) )
  5155. {
  5156. return true;
  5157. }
  5158. if( !strcmp( var, "$WORLDVIEW" ) )
  5159. {
  5160. return true;
  5161. }
  5162. if( !strcmp( var, "$FASTZOOM" ) )
  5163. {
  5164. return true;
  5165. }
  5166. if( !strcmp( var, "$GRIDMODE" ) )
  5167. {
  5168. return true;
  5169. }
  5170. if( !strcmp( var, "$GRIDUNIT" ) )
  5171. {
  5172. return true;
  5173. }
  5174. if( !strcmp( var, "$SNAPANG" ) )
  5175. {
  5176. return true;
  5177. }
  5178. if( !strcmp( var, "$SNAPBASE" ) )
  5179. {
  5180. return true;
  5181. }
  5182. if( !strcmp( var, "$SNAPISOPAIR" ) )
  5183. {
  5184. return true;
  5185. }
  5186. if( !strcmp( var, "$SNAPMODE" ) )
  5187. {
  5188. return true;
  5189. }
  5190. if( !strcmp( var, "$SNAPSTYLE" ) )
  5191. {
  5192. return true;
  5193. }
  5194. if( !strcmp( var, "$SNAPUNIT" ) )
  5195. {
  5196. return true;
  5197. }
  5198. if( !strcmp( var, "$VIEWCTR" ) )
  5199. {
  5200. return true;
  5201. }
  5202. if( !strcmp( var, "$VIEWDIR" ) )
  5203. {
  5204. return true;
  5205. }
  5206. if( !strcmp( var, "$VIEWSIZE" ) )
  5207. {
  5208. return true;
  5209. }
  5210. return false;
  5211. }
  5212. return false;
  5213. }
  5214. /**
  5215. * @returns the library version as int (4 bytes, each byte one version number).
  5216. * e.g. if str = "2.0.2.0" getLibVersion returns 0x02000200
  5217. */
  5218. int DL_Dxf::getLibVersion( const std::string& str )
  5219. {
  5220. int d[4];
  5221. int idx = 0;
  5222. // char v[4][5];
  5223. std::string v[4];
  5224. int ret = 0;
  5225. for( unsigned int i = 0; i<str.length() && idx<3; ++i )
  5226. {
  5227. if( str[i]=='.' )
  5228. {
  5229. d[idx] = i;
  5230. idx++;
  5231. }
  5232. }
  5233. if( idx>=2 )
  5234. {
  5235. d[3] = str.length();
  5236. v[0] = str.substr( 0, d[0] );
  5237. v[1] = str.substr( d[0] + 1, d[1] - d[0] - 1 );
  5238. v[2] = str.substr( d[1] + 1, d[2] - d[1] - 1 );
  5239. if( idx>=3 )
  5240. {
  5241. v[3] = str.substr( d[2] + 1, d[3] - d[2] - 1 );
  5242. }
  5243. else
  5244. {
  5245. v[3] = "0";
  5246. }
  5247. ret = ( atoi( v[0].c_str() ) << (3 * 8) ) +
  5248. ( atoi( v[1].c_str() ) << (2 * 8) ) +
  5249. ( atoi( v[2].c_str() ) << (1 * 8) ) +
  5250. ( atoi( v[3].c_str() ) << (0 * 8) );
  5251. return ret;
  5252. }
  5253. else
  5254. {
  5255. std::cerr << "DL_Dxf::getLibVersion: invalid version number: " << str << "\n";
  5256. return 0;
  5257. }
  5258. }
  5259. /**
  5260. * Converts the given string into a double or returns the given
  5261. * default valud (def) if value is NULL or empty.
  5262. */
  5263. // double DL_Dxf::toReal(const char* value, double def) {
  5264. // if (value!=NULL && value[0] != '\0') {
  5265. // printf("toReal: not empty: %s\n", value);
  5266. // printf("toReal: val: %f\n", atof(value));
  5267. // printf("toReal: 0: %d\n", value[0]);
  5268. // printf("toReal: 1: %d\n", value[1]);
  5269. // printf("toReal: 2: %d\n", value[2]);
  5270. // double ret;
  5271. // if (strchr(value, ',') != NULL) {
  5272. // char* tmp = new char[strlen(value)+1];
  5273. // strcpy(tmp, value);
  5274. // DL_WriterA::strReplace(tmp, ',', '.');
  5275. // ret = atof(tmp);
  5276. // delete[] tmp;
  5277. // }
  5278. // else {
  5279. // ret = atof(value);
  5280. // }
  5281. // return ret;
  5282. // } else {
  5283. // return def;
  5284. // }
  5285. // }
  5286. /**
  5287. * Some test routines.
  5288. */
  5289. void DL_Dxf::test()
  5290. {
  5291. char* buf1;
  5292. char* buf2;
  5293. char* buf3;
  5294. char* buf4;
  5295. char* buf5;
  5296. char* buf6;
  5297. buf1 = new char[10];
  5298. buf2 = new char[10];
  5299. buf3 = new char[10];
  5300. buf4 = new char[10];
  5301. buf5 = new char[10];
  5302. buf6 = new char[10];
  5303. strcpy( buf1, " 10\n" );
  5304. strcpy( buf2, "10" );
  5305. strcpy( buf3, "10\n" );
  5306. strcpy( buf4, " 10 \n" );
  5307. strcpy( buf5, " 10 \r" );
  5308. strcpy( buf6, "\t10 \n" );
  5309. std::cout << "1 buf1: '" << buf1 << "'\n";
  5310. stripWhiteSpace( &buf1 );
  5311. std::cout << "2 buf1: '" << buf1 << "'\n";
  5312. // assert(!strcmp(buf1, "10"));
  5313. std::cout << "1 buf2: '" << buf2 << "'\n";
  5314. stripWhiteSpace( &buf2 );
  5315. std::cout << "2 buf2: '" << buf2 << "'\n";
  5316. std::cout << "1 buf3: '" << buf3 << "'\n";
  5317. stripWhiteSpace( &buf3 );
  5318. std::cout << "2 buf3: '" << buf3 << "'\n";
  5319. std::cout << "1 buf4: '" << buf4 << "'\n";
  5320. stripWhiteSpace( &buf4 );
  5321. std::cout << "2 buf4: '" << buf4 << "'\n";
  5322. std::cout << "1 buf5: '" << buf5 << "'\n";
  5323. stripWhiteSpace( &buf5 );
  5324. std::cout << "2 buf5: '" << buf5 << "'\n";
  5325. std::cout << "1 buf6: '" << buf6 << "'\n";
  5326. stripWhiteSpace( &buf6 );
  5327. std::cout << "2 buf6: '" << buf6 << "'\n";
  5328. delete( buf1 );
  5329. delete( buf2 );
  5330. delete( buf3 );
  5331. delete( buf4 );
  5332. delete( buf5 );
  5333. delete( buf6 );
  5334. }