1 /* 2 * This program source code file is part of KiCad, a free EDA CAD application. 3 * 4 * Copyright (C) 2014-2017 Cirilo Bernardo 5 * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, you may find one here: 19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 20 * or you may search the http://www.gnu.org website for the version 2 license, 21 * or you may write to the Free Software Foundation, Inc., 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 23 */ 24 25 26 #ifndef IDF_OUTLINES_H 27 #define IDF_OUTLINES_H 28 29 #include <string> 30 #include <list> 31 #include <map> 32 33 #include <idf_common.h> 34 35 /* 36 * NOTES ON OUTLINE TYPES: 37 * 38 * BOARD_OUTLINE (PANEL_OUTLINE) 39 * .BOARD_OUTLINE [OWNER] 40 * [thickness] 41 * [outlines] 42 * 43 * OTHER_OUTLINE 44 * .OTHER_OUTLINE [OWNER] 45 * [outline identifier] [thickness] [board side: Top/Bot] 46 * [outline] 47 * 48 * ROUTE_OUTLINE 49 * .ROUTE_OUTLINE [OWNER] 50 * [layers] 51 * [outline] 52 * 53 * PLACE_OUTLINE 54 * .PLACE_OUTLINE [OWNER] 55 * [board side: Top/Bot/Both] [height] 56 * [outline] 57 * 58 * ROUTE_KEEPOUT 59 * .ROUTE_KEEPOUT [OWNER] 60 * [layers] 61 * [outline] 62 * 63 * VIA_KEEPOUT 64 * .VIA_KEEPOUT [OWNER] 65 * [outline] 66 * 67 * PLACE_KEEPOUT 68 * .PLACE_KEEPOUT [OWNER] 69 * [board side: Top/Bot/Both] [height] 70 * [outline] 71 * 72 * Placement Group 73 * .PLACE_REGION [OWNER] 74 * [side: Top/Bot/Both ] [component group name] 75 * [outline] 76 * 77 * Component Outline: 78 * .ELECTRICAL/.MECHANICAL 79 * [GEOM] [PART] [UNIT] [HEIGHT] 80 * [outline] 81 * [PROP] [prop name] [prop value] 82 */ 83 84 class IDF3_BOARD; 85 86 87 /** 88 * IDFv3 BOARD OUTLINE data and is the basis of other IDFv3 outline objects. 89 */ 90 class BOARD_OUTLINE 91 { 92 public: 93 BOARD_OUTLINE(); 94 virtual ~BOARD_OUTLINE(); 95 96 /** 97 * Function SetUnit 98 * sets the native unit of the outline; except for component outlines this must 99 * be the same as the native unit of the parent IDF_BOARD object 100 * 101 * @param aUnit is the native unit (UNIT_MM or UNIT_THOU) 102 */ 103 virtual bool SetUnit( IDF3::IDF_UNIT aUnit ); 104 105 /** 106 * Return the native unit type of the outline. 107 * 108 * @return IDF_UNIT is the native unit (UNIT_MM or UNIT_THOU). 109 */ 110 virtual IDF3::IDF_UNIT GetUnit( void ); 111 112 /** 113 * Set the thickness or height of the outline (mm). 114 * 115 * @param aThickness is the thickness or height of the outline in mm. 116 */ 117 virtual bool SetThickness( double aThickness ); 118 119 /** 120 * @return the thickness or height of an outline (mm). 121 */ 122 virtual double GetThickness( void ); 123 124 /** 125 * Free memory and reinitializes all internal data except for the parent pointer. 126 * 127 * @return true if OK, false on ownership violations. 128 */ 129 virtual bool Clear( void ); 130 131 /** 132 * @return the type of outline according to the IDFv3 classification. 133 */ 134 IDF3::OUTLINE_TYPE GetOutlineType( void ); 135 136 /** 137 * @return the parent IDF_BOARD object. 138 */ 139 IDF3_BOARD* GetParent( void ); 140 141 142 /** 143 * Add the specified outline to this object. 144 * 145 * @param aOutline is a valid IDF outline. 146 * @return true if the outline was added; false if the outline already existed or an 147 * ownership violation occurs. 148 */ 149 bool AddOutline( IDF_OUTLINE* aOutline ); 150 151 /** 152 * Remove the given outline, subject to IDF ownership rules, 153 * if it is owned by this object. 154 * 155 * The outline pointer remains valid and it is the user's responsibility to delete the 156 * object. The first outline in the list will never be deleted unless it is the sole 157 * remaining outline; this is to ensure that a board outline is not removed while the 158 * cutouts remain. 159 * 160 * @param aOutline is a pointer to the outline to remove from the list. 161 * @return true if the outline was found and removed; false if the outline was not found 162 * or an ownership violation occurs. 163 */ 164 bool DelOutline( IDF_OUTLINE* aOutline ); 165 166 /** 167 * Delete the outline specified by the given index, subject to IDF ownership rules. 168 * 169 * The outline data is destroyed. The first outline in the list will never be deleted 170 * unless it is the sole remaining outline; this is to ensure that a board outline is 171 * not removed while the cutouts remain. 172 * 173 * @param aIndex is an index to the outline to delete 174 * @return true if the outline was found and deleted; false if the outline was not found 175 * or an ownership violation or indexation error occurs. 176 */ 177 bool DelOutline( size_t aIndex ); 178 179 /** 180 * Return outlines list. 181 * 182 * It is up to the user to respect the IDFv3 specification and avoid changes to this 183 * list which are in violation of the specification. 184 */ 185 const std::list< IDF_OUTLINE* >*const GetOutlines( void ); 186 187 /** 188 * @return the number of items in the internal outline list. 189 */ 190 size_t OutlinesSize( void ); 191 192 /** 193 * Return a pointer to the outline as specified by aIndex. 194 * 195 * If the index is out of bounds NULL is returned and the error message is set. It is the 196 * responsibility of the user to observe IDF ownership rules. 197 */ 198 IDF_OUTLINE* GetOutline( size_t aIndex ); 199 200 /** 201 * @return the ownership status of the outline (ECAD, MCAD, UNOWNED). 202 */ 203 IDF3::KEY_OWNER GetOwner( void ); 204 205 /** 206 * Set the ownership status of the outline subject to IDF ownership rules. 207 * 208 * @return true if the ownership was changed and false if a specification violation occurred. 209 */ 210 bool SetOwner( IDF3::KEY_OWNER aOwner ); 211 212 /** 213 * @return true if this type of outline only supports a single outline. All outlines except 214 * for BOARD_OUTLINE are single. 215 */ 216 bool IsSingle( void ); 217 218 /** 219 * Clear internal data except for the parent pointer. 220 */ 221 void ClearOutlines( void ); 222 223 /** 224 * Add a comment to the outline data. 225 * 226 * This function is not subject to IDF ownership rules. 227 */ 228 void AddComment( const std::string& aComment ); 229 230 /** 231 * @return the number of comments in the internal list. 232 */ 233 size_t CommentsSize( void ); 234 235 /** 236 * @return the internal list of comments. 237 */ 238 std::list< std::string >* GetComments( void ); 239 240 /** 241 * @return indexed comment or NULL if the index is out of bounds. 242 */ 243 const std::string* GetComment( size_t aIndex ); 244 245 /** 246 * Deletes a comment based on the given index. 247 * 248 * @return true if a comment was deleted, false if the index is out of bounds. 249 */ 250 bool DeleteComment( size_t aIndex ); 251 252 /** 253 * Deletes all comments. 254 */ 255 void ClearComments( void ); 256 GetError(void)257 const std::string& GetError( void ) 258 { 259 return errormsg; 260 } 261 262 protected: 263 // Read outline data from a BOARD or LIBRARY file's outline section 264 void readOutlines( std::istream& aBoardFile, IDF3::IDF_VERSION aIdfVersion ); 265 266 // Write comments to a BOARD or LIBRARY file (must not be within a SECTION as per IDFv3 spec) 267 bool writeComments( std::ostream& aBoardFile ); 268 269 // Write the outline owner to a BOARD file 270 bool writeOwner( std::ostream& aBoardFile ); 271 272 // Write the data of a single outline object 273 void writeOutline( std::ostream& aBoardFile, IDF_OUTLINE* aOutline, size_t aIndex ); 274 275 // Iterate through the outlines and write out all data 276 void writeOutlines( std::ostream& aBoardFile ); // write outline data (no headers) 277 278 // Clear internal list of outlines 279 void clearOutlines( void ); 280 281 /** 282 * Set the parent IDF_BOARD object. 283 */ 284 void setParent( IDF3_BOARD* aParent ); 285 286 // Shadow routines used by friends to bypass ownership checks 287 bool addOutline( IDF_OUTLINE* aOutline ); 288 virtual bool setThickness( double aThickness ); 289 virtual void clear( void ); 290 291 /** 292 * Read data from a .BOARD_OUTLINE section. 293 * 294 * In case of an unrecoverable error an exception is thrown. On a successful 295 * return the file pointer will be at the line following .END_BOARD_OUTLINE 296 * 297 * @param aBoardFile is an IDFv3 file opened for reading. 298 * @param aHeader is the ".BOARD_OUTLINE" header line as read by FetchIDFLine. 299 */ 300 virtual void readData( std::istream& aBoardFile, const std::string& aHeader, 301 IDF3::IDF_VERSION aIdfVersion ); 302 303 /** 304 * Write the comments and .BOARD_OUTLINE section to an IDFv3 file. 305 * Throws exceptions. 306 * 307 * @param aBoardFile is an IDFv3 file opened for writing. 308 */ 309 virtual void writeData( std::ostream& aBoardFile ); 310 311 std::string errormsg; 312 std::list< IDF_OUTLINE* > outlines; 313 314 // indicates the owner of this outline (MCAD, ECAD, UNOWNED). 315 IDF3::KEY_OWNER owner; 316 IDF3::OUTLINE_TYPE outlineType; // type of IDF outline 317 bool single; // true if only a single outline is accepted 318 std::list< std::string > comments; // associated comment list 319 IDF3::IDF_UNIT unit; // outline's native unit (MM or THOU) 320 IDF3_BOARD* parent; // BOARD which contains this outline 321 double thickness; // Board/Extrude Thickness or Height (IDF spec) 322 323 private: 324 friend class IDF3_BOARD; 325 }; 326 327 328 /** 329 * Miscellaneous extrusions on the board 330 */ 331 class OTHER_OUTLINE : public BOARD_OUTLINE 332 { 333 public: 334 OTHER_OUTLINE( IDF3_BOARD* aParent ); 335 336 /** 337 * Function SetOutlineIdentifier 338 * sets the Outline Identifier string of this OTHER_OUTLINE object 339 * as per IDFv3 spec. 340 */ 341 virtual bool SetOutlineIdentifier( const std::string& aUniqueID ); 342 343 /** 344 * Function GetOutlineIdentifier 345 * returns the object's Outline Identifier 346 */ 347 virtual const std::string& GetOutlineIdentifier( void ); 348 349 /** 350 * Function SetSide 351 * sets the side which this outline is applicable to (TOP, BOTTOM). 352 * 353 * @return bool: true if the side was set, false if the side is invalid 354 * or there is a violation of IDF ownership rules. 355 */ 356 virtual bool SetSide( IDF3::IDF_LAYER aSide ); 357 358 /** 359 * Function GetSide 360 * returns the side which this outline is applicable to 361 */ 362 virtual IDF3::IDF_LAYER GetSide( void ); 363 364 /** 365 * Function Clear 366 * deletes internal data except for the parent object 367 */ 368 virtual bool Clear( void ) override; 369 370 private: 371 /** 372 * Read an OTHER_OUTLINE data from an IDFv3 file. 373 * If an unrecoverable error occurs an exception is thrown. 374 * 375 * @param aBoardFile is an IDFv3 file open for reading. 376 * @param aHeader is the .OTHER_OUTLINE header as read via FetchIDFLine. 377 */ 378 virtual void readData( std::istream& aBoardFile, const std::string& aHeader, 379 IDF3::IDF_VERSION aIdfVersion ) override; 380 381 /** 382 * Write the OTHER_OUTLINE data to an open IDFv3 file. 383 * 384 * @param aBoardFile is an IDFv3 file open for writing. 385 * @return true if the data was successfully written, otherwise false. 386 */ 387 virtual void writeData( std::ostream& aBoardFile ) override; 388 389 friend class IDF3_BOARD; 390 391 std::string uniqueID; // Outline Identifier (IDF spec) 392 IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM ONLY] (IDF spec) 393 }; 394 395 396 /** 397 * Routing areas on the board. 398 */ 399 class ROUTE_OUTLINE : public BOARD_OUTLINE 400 { 401 public: 402 ROUTE_OUTLINE( IDF3_BOARD* aParent ); 403 404 /** 405 * Function SetLayers 406 * sets the layer or group of layers this outline is applicable to. 407 * This function is subject to IDF ownership rules; true is returned 408 * on success, otherwise false is returned and the error message is set. 409 */ 410 virtual bool SetLayers( IDF3::IDF_LAYER aLayer ); 411 412 /** 413 * Function GetLayers 414 * returns the layer or group of layers which this outline is applicable to 415 */ 416 virtual IDF3::IDF_LAYER GetLayers( void ); 417 418 /** 419 * Function Clear 420 * deletes internal data except for the parent object 421 */ 422 virtual bool Clear( void ) override; 423 424 private: 425 friend class IDF3_BOARD; 426 427 /** 428 * Read ROUTE_OUTLINE data from an IDFv3 file. 429 * If an unrecoverable error occurs an exception is thrown. 430 * 431 * @param aBoardFile is an open IDFv3 board file. 432 * @param aHeader is the .ROUTE_OUTLINE header as returned by FetchIDFLine. 433 */ 434 virtual void readData( std::istream& aBoardFile, const std::string& aHeader, 435 IDF3::IDF_VERSION aIdfVersion ) override; 436 437 /** 438 * Write the ROUTE_OUTLINE data to an open IDFv3 file. 439 */ 440 virtual void writeData( std::ostream& aBoardFile ) override; 441 442 protected: 443 IDF3::IDF_LAYER layers; // Routing layers (IDF spec) 444 }; 445 446 447 /** 448 * Area on the board for placing components. 449 */ 450 class PLACE_OUTLINE : public BOARD_OUTLINE 451 { 452 public: 453 PLACE_OUTLINE( IDF3_BOARD* aParent ); 454 455 /** 456 * Function SetSide 457 * sets the side (TOP, BOTTOM, BOTH) which this outline applies to. 458 * This function is subject to IDF ownership rules; true is returned 459 * on success, otherwise false is returned and the error message is set. 460 */ 461 virtual bool SetSide( IDF3::IDF_LAYER aSide ); 462 463 /** 464 * Function GetSide 465 * returns the side which this outline is applicable to 466 */ 467 virtual IDF3::IDF_LAYER GetSide( void ); 468 469 /** 470 * Function SetMaxHeight 471 * sets the maximum height of a component within this outline. 472 * This function is subject to IDF ownership rules; true is returned 473 * on success, otherwise false is returned and the error message is set. 474 */ 475 virtual bool SetMaxHeight( double aHeight ); 476 477 /** 478 * Function GetMaxHeight 479 * returns the maximum allowable height for a component in this region 480 */ 481 virtual double GetMaxHeight( void ); 482 483 /** 484 * Function Clear 485 * deletes all internal data 486 */ 487 virtual bool Clear( void ) override; 488 489 private: 490 friend class IDF3_BOARD; 491 492 /** 493 * Read PLACE_OUTLINE data from an open IDFv3 file. 494 * 495 * If an unrecoverable error occurs an exception is thrown. 496 * 497 * @param aBoardFile is an IDFv3 file opened for reading. 498 * @param aHeader is the .PLACE_OUTLINE header as returned by FetchIDFLine. 499 */ 500 virtual void readData( std::istream& aBoardFile, const std::string& aHeader, 501 IDF3::IDF_VERSION aIdfVersion ) override; 502 503 /** 504 * Write the PLACE_OUTLINE data to an open IDFv3 file. 505 * 506 * @param aBoardFile is an IDFv3 file opened for writing. 507 * @return true if the data was successfully written, otherwise false. 508 */ 509 virtual void writeData( std::ostream& aBoardFile ) override; 510 511 protected: 512 IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM/BOTH ONLY] (IDF spec) 513 }; 514 515 516 /** 517 * Regions and layers where no electrical routing is permitted. 518 */ 519 class ROUTE_KO_OUTLINE : public ROUTE_OUTLINE 520 { 521 public: 522 ROUTE_KO_OUTLINE( IDF3_BOARD* aParent ); 523 }; 524 525 526 /** 527 * Region in which vias are prohibited. 528 * 529 * @note IDFv3 only considers thru-hole vias and makes no statement regarding behavior with 530 * blind or buried vias. 531 */ 532 class VIA_KO_OUTLINE : public OTHER_OUTLINE 533 { 534 public: 535 VIA_KO_OUTLINE( IDF3_BOARD* aParent ); 536 }; 537 538 539 /** 540 * Regions and layers in which no component may be placed or on which a maximum component height 541 * is in effect. 542 */ 543 class PLACE_KO_OUTLINE : public PLACE_OUTLINE 544 { 545 public: 546 PLACE_KO_OUTLINE( IDF3_BOARD* aParent ); 547 }; 548 549 550 /** 551 * Regions and layers in which user-specified features or components may be placed. 552 */ 553 class GROUP_OUTLINE : public BOARD_OUTLINE 554 { 555 public: 556 GROUP_OUTLINE( IDF3_BOARD* aParent ); 557 558 /** 559 * Set the side which this outline applies to (TOP, BOTTOM, BOTH). 560 * 561 * This function is subject to IDF ownership rules; true is returned 562 * on success, otherwise false is returned and the error message is set. 563 */ 564 virtual bool SetSide( IDF3::IDF_LAYER aSide ); 565 566 /** 567 * @return the side which this outline applies to. 568 */ 569 virtual IDF3::IDF_LAYER GetSide( void ); 570 571 /** 572 * Set the name of the group, subject to IDF ownership rules. 573 * 574 * This function is subject to IDF ownership rules; true is returned 575 * on success, otherwise false is returned and the error message is set. 576 */ 577 virtual bool SetGroupName( std::string aGroupName ); 578 579 /** 580 * Return a reference to the (non-unique) group name. 581 */ 582 virtual const std::string& GetGroupName( void ); 583 584 /** 585 * Delete internal data, subject to IDF ownership rules. 586 */ 587 virtual bool Clear( void ) override; 588 589 private: 590 friend class IDF3_BOARD; 591 592 /** 593 * Read GROUP_OUTLINE data from an open IDFv3 file. 594 * 595 * If an unrecoverable error occurs an exception is thrown. 596 * 597 * @param aBoardFile is an open IDFv3 file. 598 * @param aHeader is the .PLACE_REGION header as returned by FetchIDFLine. 599 */ 600 virtual void readData( std::istream& aBoardFile, const std::string& aHeader, 601 IDF3::IDF_VERSION aIdfVersion ) override; 602 603 /** 604 * Write the data to a .PLACE_REGION section of an IDFv3 file. 605 * 606 * @param aBoardFile is an IDFv3 file open for writing. 607 * @return true if the data is successfully written, otherwise false. 608 */ 609 virtual void writeData( std::ostream& aBoardFile ) override; 610 611 IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM/BOTH ONLY] (IDF spec) 612 std::string groupName; // non-unique string 613 }; 614 615 616 /** 617 * A component's outline as stored in an IDF library file. 618 */ 619 class IDF3_COMP_OUTLINE : public BOARD_OUTLINE 620 { 621 public: 622 IDF3_COMP_OUTLINE( IDF3_BOARD* aParent ); 623 624 /** 625 * Delete internal outline data. 626 */ 627 virtual bool Clear( void ) override; 628 629 /** 630 * Set the type of component outline (.ELECTRICAL or .MECHANICAL). 631 * 632 * @return true on success, otherwise false and the error message is set. 633 */ 634 bool SetComponentClass( IDF3::COMP_TYPE aCompClass ); 635 636 /** 637 * @return2 the class of component represented by this outline. 638 */ 639 IDF3::COMP_TYPE GetComponentClass( void ); 640 641 /** 642 * Set the Geometry Name (Package Name, IDFv3 spec) of the component outline. 643 */ 644 void SetGeomName( const std::string& aGeomName ); 645 646 /** 647 * @return the Geometry Name (Package Name) of the component outline. 648 */ 649 const std::string& GetGeomName( void ); 650 651 /** 652 * Set the Part Name (Part Number, IDFv3 spec) of the component outline. 653 */ 654 void SetPartName( const std::string& aPartName ); 655 656 /** 657 * Return the Part Name (Part Number) of the component outline. 658 */ 659 const std::string& GetPartName( void ); 660 661 /** 662 * @return the unique identifier for this component outline, this is equal to 663 * GEOM_NAME + "_" + PART_NAME. 664 */ 665 const std::string& GetUID( void ); 666 667 /** 668 * Create a default outline with the given Geometry and Part names. 669 * 670 * This outline is a star with outer radius 5mm and inner radius 2.5mm. 671 */ 672 bool CreateDefaultOutline( const std::string &aGeom, const std::string &aPart ); 673 674 // XXX: property manipulators 675 676 private: 677 friend class IDF3_BOARD; 678 friend class IDF3_COMP_OUTLINE_DATA; 679 680 void readProperties( std::istream& aLibFile ); 681 bool writeProperties( std::ostream& aLibFile ); 682 683 /** 684 * Read a component outline from an open IDFv3 file. 685 * 686 * If an unrecoverable error occurs, an exception is thrown. 687 * 688 * @param aLibFile is an open IDFv3 Library file. 689 * @param aHeader is the .ELECTRICAL or .MECHANICAL header as returned by FetchIDFLine. 690 */ 691 virtual void readData( std::istream& aLibFile, const std::string& aHeader, 692 IDF3::IDF_VERSION aIdfVersion ) override; 693 694 /** 695 * Write comments and component outline data to an IDFv3 Library file. 696 * 697 * @param aLibFile is an IDFv3 library file open for writing. 698 * @return true if the data was successfully written, otherwise false. 699 */ 700 virtual void writeData( std::ostream& aLibFile ) override; 701 702 /** 703 * Increment the internal reference counter to keep track of the number of 704 * components referring to this outline. 705 * 706 * @return the number of current references to this component outline. 707 */ 708 int incrementRef( void ); 709 710 /** 711 * Decrement the internal reference counter to keep track of the number of 712 * components referring to this outline. 713 * 714 * @return the number of remaining references or -1 if there were no references when the 715 * function was invoked, in which case the error message is also set. 716 */ 717 int decrementRef( void ); 718 719 std::string uid; // unique ID 720 std::string geometry; // geometry name (IDF) 721 std::string part; // part name (IDF) 722 IDF3::COMP_TYPE compType; // component type 723 int refNum; // number of components referring to this outline 724 725 std::map< std::string, std::string > props; // properties list 726 }; 727 728 #endif // IDF_OUTLINES_H 729