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.

176 lines
5.8 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2004-2020 KiCad Developers.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <common.h>
  24. #include <class_drawsegment.h>
  25. #include <geometry/seg.h>
  26. #include <geometry/shape_segment.h>
  27. #include <drc/drc_engine.h>
  28. #include <drc/drc_item.h>
  29. #include <drc/drc_rule.h>
  30. #include <drc/drc.h>
  31. #include <drc/drc_test_provider_clearance_base.h>
  32. /*
  33. Board edge clearance test. Checks all items for their mechanical clearances against the board edge.
  34. Errors generated:
  35. - DRCE_COPPER_EDGE_CLEARANCE
  36. TODO:
  37. - separate holes to edge check
  38. - tester only looks for edge crossings. it doesn't check if items are inside/outside the board area.
  39. */
  40. class DRC_TEST_PROVIDER_EDGE_CLEARANCE : public DRC_TEST_PROVIDER_CLEARANCE_BASE
  41. {
  42. public:
  43. DRC_TEST_PROVIDER_EDGE_CLEARANCE () :
  44. DRC_TEST_PROVIDER_CLEARANCE_BASE()
  45. {
  46. }
  47. virtual ~DRC_TEST_PROVIDER_EDGE_CLEARANCE()
  48. {
  49. }
  50. virtual bool Run() override;
  51. virtual const wxString GetName() const override
  52. {
  53. return "edge_clearance";
  54. }
  55. virtual const wxString GetDescription() const override
  56. {
  57. return "Tests items vs board edge clearance";
  58. }
  59. virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
  60. };
  61. bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
  62. {
  63. m_board = m_drcEngine->GetBoard();
  64. DRC_CONSTRAINT worstClearanceConstraint;
  65. if( m_drcEngine->QueryWorstConstraint( DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE,
  66. worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
  67. {
  68. m_largestClearance = worstClearanceConstraint.GetValue().Min();
  69. }
  70. else
  71. {
  72. ReportAux("No Clearance constraints found...");
  73. return false;
  74. }
  75. ReportAux( "Worst clearance : %d nm", m_largestClearance );
  76. ReportStage( _( "Testing all items <> Board Edge clearance" ), 0, 2 );
  77. std::vector<DRAWSEGMENT*> boardOutline;
  78. std::vector<BOARD_ITEM*> boardItems;
  79. auto queryBoardOutlineItems =
  80. [&]( BOARD_ITEM *item ) -> bool
  81. {
  82. boardOutline.push_back( dyn_cast<DRAWSEGMENT*>( item ) );
  83. return true;
  84. };
  85. auto queryBoardGeometryItems =
  86. [&]( BOARD_ITEM *item ) -> bool
  87. {
  88. boardItems.push_back( item );
  89. return true;
  90. };
  91. forEachGeometryItem( { PCB_LINE_T }, LSET( Edge_Cuts ), queryBoardOutlineItems );
  92. forEachGeometryItem( {}, LSET::AllTechMask() | LSET::AllCuMask(), queryBoardGeometryItems );
  93. wxString val;
  94. wxGetEnv( "WXTRACE", &val);
  95. drc_dbg( 2,"outline: %d items, board: %d items\n", boardOutline.size(), boardItems.size() );
  96. for( DRAWSEGMENT* outlineItem : boardOutline )
  97. {
  98. if( m_drcEngine->IsErrorLimitExceeded( DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE ) )
  99. break;
  100. const std::shared_ptr<SHAPE>& refShape = outlineItem->GetEffectiveShape();
  101. for( BOARD_ITEM* boardItem : boardItems )
  102. {
  103. if( m_drcEngine->IsErrorLimitExceeded( DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE ) )
  104. break;
  105. drc_dbg( 10, "RefT %d %p %s %d\n", outlineItem->Type(), outlineItem,
  106. outlineItem->GetClass(), outlineItem->GetLayer() );
  107. drc_dbg( 10, "BoardT %d %p %s %d\n", boardItem->Type(), boardItem,
  108. boardItem->GetClass(), boardItem->GetLayer() );
  109. const std::shared_ptr<SHAPE>& shape = boardItem->GetEffectiveShape();
  110. auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE,
  111. outlineItem, boardItem );
  112. int minClearance = constraint.GetValue().Min();
  113. int actual;
  114. accountCheck( constraint );
  115. if( refShape->Collide( shape.get(), minClearance, &actual ) )
  116. {
  117. std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_COPPER_EDGE_CLEARANCE );
  118. m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
  119. constraint.GetName(),
  120. MessageTextFromValue( userUnits(), minClearance, true ),
  121. MessageTextFromValue( userUnits(), actual, true ) );
  122. drcItem->SetErrorMessage( m_msg );
  123. drcItem->SetItems( outlineItem, boardItem );
  124. drcItem->SetViolatingRule( constraint.GetParentRule() );
  125. ReportViolation( drcItem, (wxPoint) refShape->Centre() );
  126. }
  127. }
  128. }
  129. reportRuleStatistics();
  130. return true;
  131. }
  132. std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetConstraintTypes() const
  133. {
  134. return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE };
  135. }
  136. namespace detail
  137. {
  138. static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_EDGE_CLEARANCE> dummy;
  139. }