Altium PCB: import hatched polygon pour fills.
This commit is contained in:
parent
37d9b7fac0
commit
a8795711a0
|
@ -615,7 +615,7 @@ AARC6::AARC6( ALTIUM_PARSER& aReader )
|
||||||
is_keepout = flags2 == 2;
|
is_keepout = flags2 == 2;
|
||||||
|
|
||||||
net = aReader.Read<uint16_t>();
|
net = aReader.Read<uint16_t>();
|
||||||
subpolyindex = aReader.Read<uint16_t>();
|
polygon = aReader.Read<uint16_t>();
|
||||||
component = aReader.Read<uint16_t>();
|
component = aReader.Read<uint16_t>();
|
||||||
aReader.Skip( 4 );
|
aReader.Skip( 4 );
|
||||||
center = aReader.ReadVector2IPos();
|
center = aReader.ReadVector2IPos();
|
||||||
|
@ -623,10 +623,11 @@ AARC6::AARC6( ALTIUM_PARSER& aReader )
|
||||||
startangle = aReader.Read<double>();
|
startangle = aReader.Read<double>();
|
||||||
endangle = aReader.Read<double>();
|
endangle = aReader.Read<double>();
|
||||||
width = aReader.ReadKicadUnit();
|
width = aReader.ReadKicadUnit();
|
||||||
|
subpolyindex = aReader.Read<uint16_t>();
|
||||||
|
|
||||||
if( aReader.GetRemainingSubrecordBytes() >= 12 )
|
if( aReader.GetRemainingSubrecordBytes() >= 12 )
|
||||||
{
|
{
|
||||||
aReader.Skip( 11 );
|
aReader.Skip( 9 );
|
||||||
keepoutrestrictions = aReader.Read<uint8_t>();
|
keepoutrestrictions = aReader.Read<uint8_t>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -888,16 +889,17 @@ ATRACK6::ATRACK6( ALTIUM_PARSER& aReader )
|
||||||
is_keepout = flags2 == 2;
|
is_keepout = flags2 == 2;
|
||||||
|
|
||||||
net = aReader.Read<uint16_t>();
|
net = aReader.Read<uint16_t>();
|
||||||
subpolyindex = aReader.Read<uint16_t>();
|
polygon = aReader.Read<uint16_t>();
|
||||||
component = aReader.Read<uint16_t>();
|
component = aReader.Read<uint16_t>();
|
||||||
aReader.Skip( 4 );
|
aReader.Skip( 4 );
|
||||||
start = aReader.ReadVector2IPos();
|
start = aReader.ReadVector2IPos();
|
||||||
end = aReader.ReadVector2IPos();
|
end = aReader.ReadVector2IPos();
|
||||||
width = aReader.ReadKicadUnit();
|
width = aReader.ReadKicadUnit();
|
||||||
|
subpolyindex = aReader.Read<uint16_t>();
|
||||||
|
|
||||||
if( aReader.GetRemainingSubrecordBytes() >= 13 )
|
if( aReader.GetRemainingSubrecordBytes() >= 13 )
|
||||||
{
|
{
|
||||||
aReader.Skip( 12 );
|
aReader.Skip( 10 );
|
||||||
keepoutrestrictions = aReader.Read<uint8_t>();
|
keepoutrestrictions = aReader.Read<uint8_t>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1038,7 +1040,7 @@ AREGION6::AREGION6( ALTIUM_PARSER& aReader, bool aExtendedVertices )
|
||||||
is_keepout = flags2 == 2;
|
is_keepout = flags2 == 2;
|
||||||
|
|
||||||
net = aReader.Read<uint16_t>();
|
net = aReader.Read<uint16_t>();
|
||||||
subpolyindex = aReader.Read<uint16_t>();
|
polygon = aReader.Read<uint16_t>();
|
||||||
component = aReader.Read<uint16_t>();
|
component = aReader.Read<uint16_t>();
|
||||||
aReader.Skip( 5 );
|
aReader.Skip( 5 );
|
||||||
holecount = aReader.Read<uint16_t>();
|
holecount = aReader.Read<uint16_t>();
|
||||||
|
@ -1057,8 +1059,9 @@ AREGION6::AREGION6( ALTIUM_PARSER& aReader, bool aExtendedVertices )
|
||||||
ALTIUM_PARSER::ReadInt( properties, wxT( "KEEPOUTRESTRIC" ), 0x1F ) );
|
ALTIUM_PARSER::ReadInt( properties, wxT( "KEEPOUTRESTRIC" ), 0x1F ) );
|
||||||
|
|
||||||
// TODO: this can differ from the other subpolyindex?!
|
// TODO: this can differ from the other subpolyindex?!
|
||||||
//subpolyindex = static_cast<uint16_t>(
|
// Note: "the other subpolyindex" is "polygon"
|
||||||
// ALTIUM_PARSER::ReadInt( properties, "SUBPOLYINDEX", ALTIUM_POLYGON_NONE ) );
|
subpolyindex = static_cast<uint16_t>(
|
||||||
|
ALTIUM_PARSER::ReadInt( properties, "SUBPOLYINDEX", ALTIUM_POLYGON_NONE ) );
|
||||||
|
|
||||||
switch( pkind )
|
switch( pkind )
|
||||||
{
|
{
|
||||||
|
|
|
@ -549,6 +549,7 @@ struct AREGION6
|
||||||
ALTIUM_LAYER layer;
|
ALTIUM_LAYER layer;
|
||||||
uint16_t net;
|
uint16_t net;
|
||||||
uint16_t component;
|
uint16_t component;
|
||||||
|
uint16_t polygon;
|
||||||
uint16_t subpolyindex;
|
uint16_t subpolyindex;
|
||||||
uint8_t keepoutrestrictions;
|
uint8_t keepoutrestrictions;
|
||||||
uint16_t holecount;
|
uint16_t holecount;
|
||||||
|
@ -570,6 +571,7 @@ struct AARC6
|
||||||
ALTIUM_LAYER layer;
|
ALTIUM_LAYER layer;
|
||||||
uint16_t net;
|
uint16_t net;
|
||||||
uint16_t component;
|
uint16_t component;
|
||||||
|
uint16_t polygon;
|
||||||
uint16_t subpolyindex;
|
uint16_t subpolyindex;
|
||||||
uint8_t keepoutrestrictions;
|
uint8_t keepoutrestrictions;
|
||||||
|
|
||||||
|
@ -683,6 +685,7 @@ struct ATRACK6
|
||||||
ALTIUM_LAYER layer;
|
ALTIUM_LAYER layer;
|
||||||
uint16_t net;
|
uint16_t net;
|
||||||
uint16_t component;
|
uint16_t component;
|
||||||
|
uint16_t polygon;
|
||||||
uint16_t subpolyindex;
|
uint16_t subpolyindex;
|
||||||
uint8_t keepoutrestrictions;
|
uint8_t keepoutrestrictions;
|
||||||
|
|
||||||
|
|
|
@ -530,6 +530,21 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi
|
||||||
for( std::pair<const ALTIUM_LAYER, ZONE*>& zone : m_outer_plane )
|
for( std::pair<const ALTIUM_LAYER, ZONE*>& zone : m_outer_plane )
|
||||||
zone.second->SetAssignedPriority( 0 );
|
zone.second->SetAssignedPriority( 0 );
|
||||||
|
|
||||||
|
// Simplify and fracture zone fills in case we constructed them from tracks (hatched fill)
|
||||||
|
for( ZONE* zone : m_polygons )
|
||||||
|
{
|
||||||
|
if( !zone )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
|
||||||
|
{
|
||||||
|
if( !zone->HasFilledPolysForLayer( layer ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
zone->GetFilledPolysList( layer )->Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Altium doesn't appear to store either the dimension value nor the dimensioned object in
|
// Altium doesn't appear to store either the dimension value nor the dimensioned object in
|
||||||
// the dimension record. (Yes, there is a REFERENCE0OBJECTID, but it doesn't point to the
|
// the dimension record. (Yes, there is a REFERENCE0OBJECTID, but it doesn't point to the
|
||||||
// dimensioned object.) We attempt to plug this gap by finding a colocated arc or circle
|
// dimensioned object.) We attempt to plug this gap by finding a colocated arc or circle
|
||||||
|
@ -2038,7 +2053,7 @@ void ALTIUM_PCB::ConvertShapeBasedRegions6ToBoardItem( const AREGION6& aElem )
|
||||||
}
|
}
|
||||||
else if( aElem.kind == ALTIUM_REGION_KIND::COPPER )
|
else if( aElem.kind == ALTIUM_REGION_KIND::COPPER )
|
||||||
{
|
{
|
||||||
if( aElem.subpolyindex == ALTIUM_POLYGON_NONE )
|
if( aElem.polygon == ALTIUM_POLYGON_NONE )
|
||||||
{
|
{
|
||||||
for( PCB_LAYER_ID klayer : GetKicadLayersToIterate( aElem.layer ) )
|
for( PCB_LAYER_ID klayer : GetKicadLayersToIterate( aElem.layer ) )
|
||||||
ConvertShapeBasedRegions6ToBoardItemOnLayer( aElem, klayer );
|
ConvertShapeBasedRegions6ToBoardItemOnLayer( aElem, klayer );
|
||||||
|
@ -2101,7 +2116,7 @@ void ALTIUM_PCB::ConvertShapeBasedRegions6ToFootprintItem( FOOTPRINT* aFoot
|
||||||
}
|
}
|
||||||
else if( aElem.kind == ALTIUM_REGION_KIND::COPPER )
|
else if( aElem.kind == ALTIUM_REGION_KIND::COPPER )
|
||||||
{
|
{
|
||||||
if( aElem.subpolyindex == ALTIUM_POLYGON_NONE )
|
if( aElem.polygon == ALTIUM_POLYGON_NONE )
|
||||||
{
|
{
|
||||||
for( PCB_LAYER_ID klayer : GetKicadLayersToIterate( aElem.layer ) )
|
for( PCB_LAYER_ID klayer : GetKicadLayersToIterate( aElem.layer ) )
|
||||||
{
|
{
|
||||||
|
@ -2309,28 +2324,22 @@ void ALTIUM_PCB::ParseRegions6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFi
|
||||||
|
|
||||||
ALTIUM_PARSER reader( aAltiumPcbFile, aEntry );
|
ALTIUM_PARSER reader( aAltiumPcbFile, aEntry );
|
||||||
|
|
||||||
for( ZONE* zone : m_polygons )
|
|
||||||
{
|
|
||||||
if( zone )
|
|
||||||
zone->UnFill(); // just to be sure
|
|
||||||
}
|
|
||||||
|
|
||||||
while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ )
|
while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ )
|
||||||
{
|
{
|
||||||
checkpoint();
|
checkpoint();
|
||||||
AREGION6 elem( reader, false );
|
AREGION6 elem( reader, false );
|
||||||
|
|
||||||
if( elem.subpolyindex != ALTIUM_POLYGON_NONE )
|
if( elem.polygon != ALTIUM_POLYGON_NONE )
|
||||||
{
|
{
|
||||||
if( m_polygons.size() <= elem.subpolyindex )
|
if( m_polygons.size() <= elem.polygon )
|
||||||
{
|
{
|
||||||
THROW_IO_ERROR( wxString::Format( "Region stream tries to access polygon id %d "
|
THROW_IO_ERROR( wxString::Format( "Region stream tries to access polygon id %d "
|
||||||
"of %d existing polygons.",
|
"of %d existing polygons.",
|
||||||
elem.subpolyindex,
|
elem.polygon,
|
||||||
m_polygons.size() ) );
|
m_polygons.size() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
ZONE *zone = m_polygons.at( elem.subpolyindex );
|
ZONE* zone = m_polygons.at( elem.polygon );
|
||||||
|
|
||||||
if( zone == nullptr )
|
if( zone == nullptr )
|
||||||
{
|
{
|
||||||
|
@ -2440,8 +2449,44 @@ void ALTIUM_PCB::ConvertArcs6ToPcbShape( const AARC6& aElem, PCB_SHAPE* aShape )
|
||||||
|
|
||||||
void ALTIUM_PCB::ConvertArcs6ToBoardItem( const AARC6& aElem, const int aPrimitiveIndex )
|
void ALTIUM_PCB::ConvertArcs6ToBoardItem( const AARC6& aElem, const int aPrimitiveIndex )
|
||||||
{
|
{
|
||||||
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
if( aElem.polygon != ALTIUM_POLYGON_NONE )
|
||||||
|
{
|
||||||
|
if( m_polygons.size() <= aElem.polygon )
|
||||||
|
{
|
||||||
|
THROW_IO_ERROR( wxString::Format( "Tracks stream tries to access polygon id %d "
|
||||||
|
"of %d existing polygons.",
|
||||||
|
aElem.polygon, m_polygons.size() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ZONE* zone = m_polygons.at( aElem.polygon );
|
||||||
|
|
||||||
|
if( zone == nullptr )
|
||||||
|
{
|
||||||
|
return; // we know the zone id, but because we do not know the layer we did not
|
||||||
|
// add it!
|
||||||
|
}
|
||||||
|
|
||||||
|
PCB_LAYER_ID klayer = GetKicadLayer( aElem.layer );
|
||||||
|
|
||||||
|
if( klayer == UNDEFINED_LAYER )
|
||||||
|
return; // Just skip it for now. Users can fill it themselves.
|
||||||
|
|
||||||
|
SHAPE_POLY_SET* fill = zone->GetFill( klayer );
|
||||||
|
|
||||||
|
// This is not the actual board item. We can use it to create the polygon for the region
|
||||||
|
PCB_SHAPE shape( nullptr );
|
||||||
|
|
||||||
|
ConvertArcs6ToPcbShape( aElem, &shape );
|
||||||
|
shape.SetStroke( STROKE_PARAMS( aElem.width, LINE_STYLE::SOLID ) );
|
||||||
|
|
||||||
|
shape.EDA_SHAPE::TransformShapeToPolygon( *fill, 0, ARC_HIGH_DEF, ERROR_INSIDE );
|
||||||
|
// Will be simplified and fractured later
|
||||||
|
|
||||||
|
zone->SetIsFilled( true );
|
||||||
|
zone->SetNeedRefill( false );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( aElem.is_keepout || aElem.layer == ALTIUM_LAYER::KEEP_OUT_LAYER
|
if( aElem.is_keepout || aElem.layer == ALTIUM_LAYER::KEEP_OUT_LAYER
|
||||||
|| IsAltiumLayerAPlane( aElem.layer ) )
|
|| IsAltiumLayerAPlane( aElem.layer ) )
|
||||||
|
@ -2482,8 +2527,12 @@ void ALTIUM_PCB::ConvertArcs6ToBoardItem( const AARC6& aElem, const int aPrimiti
|
||||||
void ALTIUM_PCB::ConvertArcs6ToFootprintItem( FOOTPRINT* aFootprint, const AARC6& aElem,
|
void ALTIUM_PCB::ConvertArcs6ToFootprintItem( FOOTPRINT* aFootprint, const AARC6& aElem,
|
||||||
const int aPrimitiveIndex, const bool aIsBoardImport )
|
const int aPrimitiveIndex, const bool aIsBoardImport )
|
||||||
{
|
{
|
||||||
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
if( aElem.polygon != ALTIUM_POLYGON_NONE )
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( wxString::Format( "Altium: Unexpected footprint Arc with polygon id %d",
|
||||||
|
aElem.polygon ) );
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( aElem.is_keepout || aElem.layer == ALTIUM_LAYER::KEEP_OUT_LAYER
|
if( aElem.is_keepout || aElem.layer == ALTIUM_LAYER::KEEP_OUT_LAYER
|
||||||
|| IsAltiumLayerAPlane( aElem.layer ) )
|
|| IsAltiumLayerAPlane( aElem.layer ) )
|
||||||
|
@ -3134,8 +3183,43 @@ void ALTIUM_PCB::ParseTracks6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFil
|
||||||
|
|
||||||
void ALTIUM_PCB::ConvertTracks6ToBoardItem( const ATRACK6& aElem, const int aPrimitiveIndex )
|
void ALTIUM_PCB::ConvertTracks6ToBoardItem( const ATRACK6& aElem, const int aPrimitiveIndex )
|
||||||
{
|
{
|
||||||
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
if( aElem.polygon != ALTIUM_POLYGON_NONE )
|
||||||
|
{
|
||||||
|
if( m_polygons.size() <= aElem.polygon )
|
||||||
|
{
|
||||||
|
THROW_IO_ERROR( wxString::Format( "Tracks stream tries to access polygon id %d "
|
||||||
|
"of %d existing polygons.",
|
||||||
|
aElem.polygon, m_polygons.size() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ZONE* zone = m_polygons.at( aElem.polygon );
|
||||||
|
|
||||||
|
if( zone == nullptr )
|
||||||
|
{
|
||||||
|
return; // we know the zone id, but because we do not know the layer we did not
|
||||||
|
// add it!
|
||||||
|
}
|
||||||
|
|
||||||
|
PCB_LAYER_ID klayer = GetKicadLayer( aElem.layer );
|
||||||
|
|
||||||
|
if( klayer == UNDEFINED_LAYER )
|
||||||
|
return; // Just skip it for now. Users can fill it themselves.
|
||||||
|
|
||||||
|
SHAPE_POLY_SET* fill = zone->GetFill( klayer );
|
||||||
|
|
||||||
|
PCB_SHAPE shape( nullptr, SHAPE_T::SEGMENT );
|
||||||
|
shape.SetStart( aElem.start );
|
||||||
|
shape.SetEnd( aElem.end );
|
||||||
|
shape.SetStroke( STROKE_PARAMS( aElem.width, LINE_STYLE::SOLID ) );
|
||||||
|
|
||||||
|
shape.EDA_SHAPE::TransformShapeToPolygon( *fill, 0, ARC_HIGH_DEF, ERROR_INSIDE );
|
||||||
|
// Will be simplified and fractured later
|
||||||
|
|
||||||
|
zone->SetIsFilled( true );
|
||||||
|
zone->SetNeedRefill( false );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( aElem.is_keepout || aElem.layer == ALTIUM_LAYER::KEEP_OUT_LAYER
|
if( aElem.is_keepout || aElem.layer == ALTIUM_LAYER::KEEP_OUT_LAYER
|
||||||
|| IsAltiumLayerAPlane( aElem.layer ) )
|
|| IsAltiumLayerAPlane( aElem.layer ) )
|
||||||
|
@ -3177,8 +3261,12 @@ void ALTIUM_PCB::ConvertTracks6ToFootprintItem( FOOTPRINT* aFootprint, const ATR
|
||||||
const int aPrimitiveIndex,
|
const int aPrimitiveIndex,
|
||||||
const bool aIsBoardImport )
|
const bool aIsBoardImport )
|
||||||
{
|
{
|
||||||
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
if( aElem.polygon != ALTIUM_POLYGON_NONE )
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( wxString::Format( "Altium: Unexpected footprint Track with polygon id %d",
|
||||||
|
aElem.polygon ) );
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( aElem.is_keepout || aElem.layer == ALTIUM_LAYER::KEEP_OUT_LAYER
|
if( aElem.is_keepout || aElem.layer == ALTIUM_LAYER::KEEP_OUT_LAYER
|
||||||
|| IsAltiumLayerAPlane( aElem.layer ) )
|
|| IsAltiumLayerAPlane( aElem.layer ) )
|
||||||
|
|
Loading…
Reference in New Issue