Handle lineweight in dxf import more properly

lineweights can be set to inherit from the layer or block.
This commit is contained in:
Marek Roszko 2020-11-20 07:18:38 -05:00
parent 01b6cd08b5
commit f130970469
2 changed files with 107 additions and 27 deletions

View File

@ -64,6 +64,11 @@ DXF_IMPORT_PLUGIN::DXF_IMPORT_PLUGIN() : DL_CreationAdapter()
m_importAsFPShapes = true;
m_minX = m_minY = std::numeric_limits<double>::max();
m_maxX = m_maxY = std::numeric_limits<double>::min();
// placeholder layer so we can fallback to something later
std::unique_ptr<DXF_IMPORT_LAYER> layer0 =
std::make_unique<DXF_IMPORT_LAYER>( "", DXF_IMPORT_LINEWEIGHT_BY_LW_DEFAULT );
m_layers.push_back( std::move( layer0 ) );
}
@ -126,18 +131,6 @@ double DXF_IMPORT_PLUGIN::mapDim( double aDxfValue )
}
double DXF_IMPORT_PLUGIN::mapWidth( double aDxfWidth )
{
// Always return the default line width
#if 0
// mapWidth returns the aDxfValue if aDxfWidth > 0 m_defaultThickness
if( aDxfWidth > 0.0 )
return SCALE_FACTOR( aDxfWidth * m_DXF2mm );
#endif
return SCALE_FACTOR( m_defaultThickness );
}
bool DXF_IMPORT_PLUGIN::ImportDxfFile( const wxString& aFile )
{
DL_Dxf dxf_reader;
@ -219,22 +212,76 @@ void DXF_IMPORT_PLUGIN::addKnot( const DL_KnotData& aData)
void DXF_IMPORT_PLUGIN::addLayer( const DL_LayerData& aData )
{
// Not yet useful in Pcbnew.
#if 0
wxString name = wxString::FromUTF8( aData.name.c_str() );
wxLogMessage( name );
int lw = attributes.getWidth();
if( lw == DXF_IMPORT_LINEWEIGHT_BY_LAYER )
{
lw = DXF_IMPORT_LINEWEIGHT_BY_LW_DEFAULT;
}
std::unique_ptr<DXF_IMPORT_LAYER> layer = std::make_unique<DXF_IMPORT_LAYER>( name, lw );
m_layers.push_back( std::move( layer ) );
}
void DXF_IMPORT_PLUGIN::addLinetype( const DL_LinetypeData& data )
{
#if 0
wxString name = FROM_UTF8( data.name.c_str() );
wxString description = FROM_UTF8( data.description.c_str() );
#endif
}
double DXF_IMPORT_PLUGIN::lineWeightToWidth( int lw, DXF_IMPORT_LAYER* aLayer )
{
if( lw == DXF_IMPORT_LINEWEIGHT_BY_LAYER && aLayer != nullptr )
{
lw = aLayer->m_lineWeight;
}
// All lineweights >= 0 are always in 100ths of mm
double mm = m_defaultThickness;
if( lw >= 0 )
{
mm = lw / 100.0;
}
return SCALE_FACTOR( mm );
}
DXF_IMPORT_LAYER* DXF_IMPORT_PLUGIN::getImportLayer( const std::string& aLayerName )
{
DXF_IMPORT_LAYER* layer = m_layers.front().get();
wxString layerName = wxString::FromUTF8( aLayerName.c_str() );
if( !layerName.IsEmpty() )
{
auto resultIt = std::find_if( m_layers.begin(), m_layers.end(),
[layerName]( const auto& it ) { return it->m_layerName == layerName; } );
if( resultIt != m_layers.end() )
layer = resultIt->get();
}
return layer;
}
void DXF_IMPORT_PLUGIN::addLine( const DL_LineData& aData )
{
if( m_inBlock )
return;
DXF_IMPORT_LAYER* layer = getImportLayer( attributes.getLayer() );
double lineWidth = lineWeightToWidth( attributes.getWidth(), layer );
VECTOR2D start( mapX( aData.x1 ), mapY( aData.y1 ) );
VECTOR2D end( mapX( aData.x2 ), mapY( aData.y2 ) );
double lineWidth = mapWidth( attributes.getWidth() );
m_internalImporter.AddLine( start, end, lineWidth );
@ -269,7 +316,8 @@ void DXF_IMPORT_PLUGIN::addVertex( const DL_VertexData& aData )
if( m_curr_entity.m_EntityParseStatus == 0 )
return; // Error
double lineWidth = mapWidth( attributes.getWidth() );
DXF_IMPORT_LAYER* layer = getImportLayer( attributes.getLayer() );
double lineWidth = lineWeightToWidth( attributes.getWidth(), layer );
const DL_VertexData* vertex = &aData;
@ -299,14 +347,15 @@ void DXF_IMPORT_PLUGIN::addVertex( const DL_VertexData& aData )
void DXF_IMPORT_PLUGIN::endEntity()
{
DXF_IMPORT_LAYER* layer = getImportLayer( attributes.getLayer() );
double lineWidth = lineWeightToWidth( attributes.getWidth(), layer );
if( m_curr_entity.m_EntityType == DL_ENTITY_POLYLINE ||
m_curr_entity.m_EntityType == DL_ENTITY_LWPOLYLINE )
{
// Polyline flags bit 0 indicates closed (1) or open (0) polyline
if( m_curr_entity.m_EntityFlag & 1 )
{
double lineWidth = mapWidth( attributes.getWidth() );
if( std::abs( m_curr_entity.m_BulgeVertex ) < MIN_BULGE )
insertLine( m_curr_entity.m_LastCoordinate, m_curr_entity.m_PolylineStart,
lineWidth );
@ -318,7 +367,6 @@ void DXF_IMPORT_PLUGIN::endEntity()
if( m_curr_entity.m_EntityType == DL_ENTITY_SPLINE )
{
double lineWidth = mapWidth( attributes.getWidth() );
insertSpline( lineWidth );
}
@ -346,7 +394,9 @@ void DXF_IMPORT_PLUGIN::addCircle( const DL_CircleData& aData )
return;
VECTOR2D center( mapX( aData.cx ), mapY( aData.cy ) );
double lineWidth = mapWidth( attributes.getWidth() );
DXF_IMPORT_LAYER* layer = getImportLayer( attributes.getLayer() );
double lineWidth = lineWeightToWidth( attributes.getWidth(), layer );
m_internalImporter.AddCircle( center, mapDim( aData.radius ), lineWidth, false );
VECTOR2D radiusDelta( mapDim( aData.radius ), mapDim( aData.radius ) );
@ -379,7 +429,8 @@ void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData )
if( angle > 0.0 )
angle -= 360.0;
double lineWidth = mapWidth( attributes.getWidth() );
DXF_IMPORT_LAYER* layer = getImportLayer( attributes.getLayer() );
double lineWidth = lineWeightToWidth( attributes.getWidth(), layer );
m_internalImporter.AddArc( center, arcStart, angle, lineWidth );
VECTOR2D radiusDelta( mapDim( aData.radius ), mapDim( aData.radius ) );

View File

@ -110,6 +110,26 @@ public:
}
};
// Magic constants as defined by dxf specification for line weight
#define DXF_IMPORT_LINEWEIGHT_BY_LAYER -1
#define DXF_IMPORT_LINEWEIGHT_BY_BLOCK -2
#define DXF_IMPORT_LINEWEIGHT_BY_LW_DEFAULT -3
/**
* A helper class to hold layer settings temporarily during import
*/
class DXF_IMPORT_LAYER
{
public:
wxString m_layerName;
int m_lineWeight;
DXF_IMPORT_LAYER( wxString aName, int aLineWeight )
{
m_layerName = aName;
m_lineWeight = aLineWeight;
}
};
/**
* This class import DXF ASCII files and convert basic entities to board entities.
@ -144,6 +164,8 @@ private:
GRAPHICS_IMPORTER_BUFFER m_internalImporter;
std::vector<std::unique_ptr<DXF_IMPORT_LAYER>> m_layers; // List of layers as we import, used just to grab props for objects
public:
DXF_IMPORT_PLUGIN();
~DXF_IMPORT_PLUGIN();
@ -236,9 +258,15 @@ private:
double mapX( double aDxfCoordX );
double mapY( double aDxfCoordY );
double mapDim( double aDxfValue );
// mapWidth returns ( in mm) the aDxfValue if aDxfWidth > 0
// or m_defaultThickness
double mapWidth( double aDxfWidth );
double lineWeightToWidth( int lw, DXF_IMPORT_LAYER* aLayer );
/**
* Returns the import layer data
*
* @param aLayerName is the raw string from dxflib getLayer()
* @returns The given layer by name or the placeholder layer inserted in the constructor
*/
DXF_IMPORT_LAYER* getImportLayer( const std::string& aLayerName );
// Functions to aid in the creation of a Polyline
void insertLine( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, int aWidth );
@ -269,6 +297,7 @@ private:
virtual void addLayer( const DL_LayerData& aData ) override;
virtual void addLine( const DL_LineData& aData ) override;
virtual void addLinetype( const DL_LinetypeData& data ) override;
/**
* Called for each BLOCK in the DXF file