200#ifdef PRINT_STATISTICS_3D_VIEWER
203 int64_t start_Time = stats_startCopperLayersTime;
221 std::vector<const PCB_TRACK*> trackList;
223 trackList.reserve(
m_board->Tracks().size() );
235 trackList.push_back( track );
257 std::vector<PCB_LAYER_ID> layer_ids;
266 layer_ids.push_back( layer );
293 if( aStatusReporter )
294 aStatusReporter->
Report(
_(
"Create tracks and vias" ) );
303 for(
const PCB_TRACK* track : trackList )
306 if( !track->IsOnLayer( layer ) )
322 unsigned int nTracks = trackList.size();
324 for(
unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
326 const PCB_TRACK *track = trackList[trackIdx];
341 const float thickness =
static_cast<float>( plating / 2.0f );
342 const float hole_inner_radius =
static_cast<float>( holediameter / 2.0f );
343 const float ring_radius =
static_cast<float>( viasize / 2.0f );
370 else if( layer == layer_ids[0] )
379 if( hole_inner_radius > 0.0 )
401 const unsigned int nTracks = trackList.size();
403 for(
unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
405 const PCB_TRACK *track = trackList[trackIdx];
446 const int holediameter =
via->GetDrillValue();
455 else if( layer == layer_ids[0] )
457 const int holediameter =
via->GetDrillValue();
459 const int hole_outer_ring_radius =
KiROUND(
via->GetWidth( layer ) / 2.0 );
489 unsigned int nTracks = trackList.size();
491 for(
unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
493 const PCB_TRACK *track = trackList[trackIdx];
511 for(
PAD*
pad : footprint->Pads() )
514 if( !
pad->HasHole() )
518 double holeDiameter = (
pad->GetDrillSize().x +
pad->GetDrillSize().y ) / 2.0;
548 for(
PAD*
pad : footprint->Pads() )
550 if( !
pad->HasHole() )
583 addPads( fp, layerContainer, layer );
591 fp->TransformPadsToPolySet( *layerPoly, layer, 0, fp->GetMaxError(),
ERROR_INSIDE );
603 fp->TransformPadsToPolySet( *layerPoly, layer, 0, fp->GetMaxError(),
ERROR_INSIDE );
620 if( !item->IsOnLayer( layer ) )
623 switch( item->Type() )
657 wxLogTrace(
m_logTrace, wxT(
"createLayers: item type: %d not implemented" ), item->Type() );
674 text_box->PCB_SHAPE::TransformShapeToPolygon( *copperPolys, layer, 0, text_box->
GetMaxError(),
684 item->TransformShapeToPolySet( *copperPolys, layer, 0, item->GetMaxError(),
ERROR_INSIDE );
695 switch( item->Type() )
698 item->TransformShapeToPolySet( *layerPoly, layer, 0, item->GetMaxError(),
ERROR_INSIDE );
715 textbox->PCB_SHAPE::TransformShapeToPolygon( *layerPoly, layer, 0, textbox->
GetMaxError(),
728 cell->TransformTextToPolySet( *layerPoly, 0, cell->GetMaxError(),
ERROR_INSIDE );
758 for(
const std::shared_ptr<SHAPE>& shape : dimension->
GetShapes() )
768 wxLogTrace(
m_logTrace, wxT(
"createLayers: item type: %d not implemented" ), item->Type() );
777 if( aStatusReporter )
778 aStatusReporter->
Report(
_(
"Create zones" ) );
780 std::vector<std::pair<ZONE*, PCB_LAYER_ID>> zones;
781 std::unordered_map<PCB_LAYER_ID, std::unique_ptr<std::mutex>> layer_lock;
787 zones.emplace_back( std::make_pair( zone, layer ) );
788 layer_lock.emplace( layer, std::make_unique<std::mutex>() );
794 zone->TransformShapeToPolygon( *copperPolys, layer, 0, zone->GetMaxError(),
ERROR_INSIDE );
800 std::atomic<size_t> nextZone( 0 );
801 std::atomic<size_t> threadsFinished( 0 );
803 size_t parallelThreadCount = std::min<size_t>( zones.size(),
804 std::max<size_t>( std::thread::hardware_concurrency(), 2 ) );
806 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
808 std::thread t = std::thread( [&]()
810 for(
size_t areaId = nextZone.fetch_add( 1 );
811 areaId < zones.size();
812 areaId = nextZone.fetch_add( 1 ) )
814 ZONE* zone = zones[areaId].first;
816 if( zone ==
nullptr )
827 auto mut_it = layer_lock.find( layer );
829 if( mut_it != layer_lock.end() )
831 std::lock_guard< std::mutex > lock( *( mut_it->second ) );
843 while( threadsFinished < parallelThreadCount )
844 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
857 if( aStatusReporter )
858 aStatusReporter->
Report(
_(
"Build Tech layers" ) );
924 std::bitset<LAYER_3D_END> enabledFlags = visibilityFlags;
934 if( aStatusReporter )
935 aStatusReporter->
Report( wxString::Format(
_(
"Build Tech layer %d" ), (
int) layer ) );
951 if( !item->IsOnLayer( layer ) )
954 switch( item->Type() )
994 if( !track->IsOnLayer( layer ) )
1004 if( !
via->FlashLayer( copper_layer ) )
1008 int maskExpansion = track->GetSolderMaskExpansion();
1020 for(
PAD*
pad : footprint->Pads() )
1022 if( !
pad->IsOnLayer( layer ) )
1030 addPads( footprint, layerContainer, layer );
1041 if( zone->IsOnLayer( layer ) )
1055 if( !item->IsOnLayer( layer ) )
1058 switch( item->Type() )
1061 item->TransformShapeToPolySet( *layerPoly, layer, 0, item->GetMaxError(),
ERROR_INSIDE );
1078 textbox->PCB_SHAPE::TransformShapeToPolygon( *layerPoly, layer, 0, textbox->
GetMaxError(),
1091 cell->TransformTextToPolySet( *layerPoly, 0, cell->GetMaxError(),
ERROR_INSIDE );
1128 if(
via->FlashLayer( layer ) && !
via->IsTented( layer ) )
1130 track->TransformShapeToPolygon( *layerPoly, layer, maskExpansion, track->GetMaxError(),
1136 if( track->HasSolderMask() )
1138 track->TransformShapeToPolySet( *layerPoly, layer, maskExpansion, track->GetMaxError(),
1152 for(
PAD*
pad : footprint->Pads() )
1154 if(
pad->IsOnLayer( layer ) )
1163 footprint->TransformPadsToPolySet( *layerPoly, layer, 0, footprint->GetMaxError(),
ERROR_INSIDE );
1175 if( zone->IsOnLayer( layer ) )
1176 zone->TransformSolidAreasShapesToPolygon( layer, *layerPoly );
1194 if( !footprint->GetBoundingBox().Intersects( boardBBox ) )
1196 if( footprint->IsFlipped() )
1209 if( aStatusReporter )
1210 aStatusReporter->
Report(
_(
"Simplifying copper layer polygons" ) );
1214 if( aStatusReporter )
1215 aStatusReporter->
Report(
_(
"Calculating plated copper" ) );
1244 std::vector<PCB_LAYER_ID> &selected_layer_id = layer_ids;
1245 std::vector<PCB_LAYER_ID> layer_id_without_F_and_B;
1249 layer_id_without_F_and_B.clear();
1250 layer_id_without_F_and_B.reserve( layer_ids.size() );
1254 if( layer !=
F_Cu && layer !=
B_Cu )
1255 layer_id_without_F_and_B.push_back( layer );
1258 selected_layer_id = layer_id_without_F_and_B;
1261 if( selected_layer_id.size() > 0 )
1263 if( aStatusReporter )
1265 aStatusReporter->
Report( wxString::Format(
_(
"Simplifying %d copper layers" ),
1266 (
int) selected_layer_id.size() ) );
1269 std::atomic<size_t> nextItem( 0 );
1270 std::atomic<size_t> threadsFinished( 0 );
1272 size_t parallelThreadCount = std::min<size_t>(
1273 std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
1274 selected_layer_id.size() );
1276 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
1278 std::thread t = std::thread(
1279 [&nextItem, &threadsFinished, &selected_layer_id,
this]()
1281 for(
size_t i = nextItem.fetch_add( 1 );
1282 i < selected_layer_id.size();
1283 i = nextItem.fetch_add( 1 ) )
1299 while( threadsFinished < parallelThreadCount )
1300 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
1305 if( aStatusReporter )
1306 aStatusReporter->
Report(
_(
"Simplify holes contours" ) );
1325 if( aStatusReporter )
1326 aStatusReporter->
Report(
_(
"Build BVH for holes and vias" ) );
1334 for( std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& hole :
m_layerHoleMap )
1335 hole.second->BuildBVH();