diff --git a/common/io/easyedapro/easyedapro_parser.h b/common/io/easyedapro/easyedapro_parser.h index aaf8062770..870b702f5c 100644 --- a/common/io/easyedapro/easyedapro_parser.h +++ b/common/io/easyedapro/easyedapro_parser.h @@ -41,7 +41,8 @@ namespace EASYEDAPRO { -static const bool IMPORT_POURED = false; +static const bool IMPORT_POURED = true; +static const bool IMPORT_POURED_ECOP = false; enum class SYMBOL_TYPE { diff --git a/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro.cpp b/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro.cpp index 976cb39606..10d678e2a2 100644 --- a/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro.cpp +++ b/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro.cpp @@ -357,7 +357,7 @@ void PCB_IO_EASYEDAPRO::LoadAllDataFromProject( const wxString& aProjectPa } } } - else if( name.EndsWith( wxS( ".ecop" ) ) && EASYEDAPRO::IMPORT_POURED ) + else if( name.EndsWith( wxS( ".ecop" ) ) && EASYEDAPRO::IMPORT_POURED_ECOP ) { for( const nlohmann::json& line : lines ) { diff --git a/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro_parser.cpp b/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro_parser.cpp index 82f728395f..d1717e1173 100644 --- a/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro_parser.cpp +++ b/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro_parser.cpp @@ -956,6 +956,9 @@ void PCB_IO_EASYEDAPRO_PARSER::ParseBoard( std::map> componentLines; std::map> ruleLines; + std::multimap boardPouredMap = aPouredMap; + std::map poursToFill; + BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings(); for( const nlohmann::json& line : aLines ) @@ -1025,6 +1028,14 @@ void PCB_IO_EASYEDAPRO_PARSER::ParseBoard( ruleLines[ruleType].push_back( line ); } + else if( type == wxS( "POURED" ) ) + { + if( !line.at( 2 ).is_string() ) + continue; // Unknown type of POURED + + EASYEDAPRO::POURED poured = line; + boardPouredMap.emplace( poured.parentId, poured ); + } else if( type == wxS( "VIA" ) || type == wxS( "LINE" ) || type == wxS( "ARC" ) || type == wxS( "POLY" ) || type == wxS( "FILL" ) || type == wxS( "POUR" ) ) { @@ -1209,88 +1220,7 @@ void PCB_IO_EASYEDAPRO_PARSER::ParseBoard( wxASSERT( zone->Outline()->OutlineCount() == 1 ); - SHAPE_POLY_SET fillPolySet; - SHAPE_POLY_SET thermalSpokes; - int entryId = 0; - - if( EASYEDAPRO::IMPORT_POURED ) - { - auto range = aPouredMap.equal_range( uuid ); - for( auto& it = range.first; it != range.second; ++it ) - { - const EASYEDAPRO::POURED& poured = it->second; - int unki = poured.unki; - - SHAPE_POLY_SET thisPoly; - - for( int dataId = 0; dataId < poured.polyData.size(); dataId++ ) - { - const nlohmann::json& fillData = poured.polyData[dataId]; - const double ptScale = 10; - - SHAPE_LINE_CHAIN contour = - ParseContour( fillData, false, ARC_HIGH_DEF / ptScale ); - - // Scale the fill - for( int i = 0; i < contour.PointCount(); i++ ) - contour.SetPoint( i, contour.GetPoint( i ) * ptScale ); - - if( poured.isPoly ) - { - contour.SetClosed( true ); - - // The contour can be self-intersecting - SHAPE_POLY_SET simple( contour ); - simple.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); - - if( dataId == 0 ) - { - thisPoly.Append( simple ); - } - else - { - thisPoly.BooleanSubtract( simple, - SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); - } - } - else - { - const int thermalWidth = pcbIUScale.mmToIU( 0.2 ); // Generic - - for( int segId = 0; segId < contour.SegmentCount(); segId++ ) - { - const SEG& seg = contour.CSegment( segId ); - - TransformOvalToPolygon( thermalSpokes, seg.A, seg.B, - thermalWidth, ARC_LOW_DEF, - ERROR_INSIDE ); - } - } - } - - fillPolySet.Append( thisPoly ); - - entryId++; - } - - if( !fillPolySet.IsEmpty() ) - { - fillPolySet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); - - const int strokeWidth = pcbIUScale.MilsToIU( 8 ); // Seems to be 8 mils - - fillPolySet.Inflate( strokeWidth / 2, CORNER_STRATEGY::ROUND_ALL_CORNERS, - ARC_HIGH_DEF, false ); - - fillPolySet.BooleanAdd( thermalSpokes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); - - fillPolySet.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); - - zone->SetFilledPolysList( klayer, fillPolySet ); - zone->SetNeedRefill( false ); - zone->SetIsFilled( true ); - } - } + poursToFill.emplace( uuid, zone.get() ); aBoard->Add( zone.release(), ADD_MODE::APPEND ); } @@ -1715,6 +1645,88 @@ void PCB_IO_EASYEDAPRO_PARSER::ParseBoard( aBoard->Add( footprint.release(), ADD_MODE::APPEND ); } + // Set zone fills + if( EASYEDAPRO::IMPORT_POURED ) + { + for( auto& [uuid, zone] : poursToFill ) + { + SHAPE_POLY_SET fillPolySet; + SHAPE_POLY_SET thermalSpokes; + + auto range = boardPouredMap.equal_range( uuid ); + for( auto& it = range.first; it != range.second; ++it ) + { + const EASYEDAPRO::POURED& poured = it->second; + int unki = poured.unki; + + SHAPE_POLY_SET thisPoly; + + for( int dataId = 0; dataId < poured.polyData.size(); dataId++ ) + { + const nlohmann::json& fillData = poured.polyData[dataId]; + const double ptScale = 10; + + SHAPE_LINE_CHAIN contour = + ParseContour( fillData, false, ARC_HIGH_DEF / ptScale ); + + // Scale the fill + for( int i = 0; i < contour.PointCount(); i++ ) + contour.SetPoint( i, contour.GetPoint( i ) * ptScale ); + + if( poured.isPoly ) + { + contour.SetClosed( true ); + + // The contour can be self-intersecting + SHAPE_POLY_SET simple( contour ); + simple.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); + + if( dataId == 0 ) + { + thisPoly.Append( simple ); + } + else + { + thisPoly.BooleanSubtract( simple, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); + } + } + else + { + const int thermalWidth = pcbIUScale.mmToIU( 0.2 ); // Generic + + for( int segId = 0; segId < contour.SegmentCount(); segId++ ) + { + const SEG& seg = contour.CSegment( segId ); + + TransformOvalToPolygon( thermalSpokes, seg.A, seg.B, thermalWidth, + ARC_LOW_DEF, ERROR_INSIDE ); + } + } + } + + fillPolySet.Append( thisPoly ); + } + + if( !fillPolySet.IsEmpty() ) + { + fillPolySet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); + + const int strokeWidth = pcbIUScale.MilsToIU( 8 ); // Seems to be 8 mils + + fillPolySet.Inflate( strokeWidth / 2, CORNER_STRATEGY::ROUND_ALL_CORNERS, + ARC_HIGH_DEF, false ); + + fillPolySet.BooleanAdd( thermalSpokes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); + + fillPolySet.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); + + zone->SetFilledPolysList( zone->GetFirstLayer(), fillPolySet ); + zone->SetNeedRefill( false ); + zone->SetIsFilled( true ); + } + } + } + // Heal board outlines std::vector shapes; std::vector> newShapes;