P-Cad PCB importer fixes

This commit is contained in:
Eldar Khayrullin 2017-12-17 11:26:52 +01:00 committed by Maciej Suminski
commit 9f2c6e20cb
9 changed files with 198 additions and 132 deletions

View File

@ -29,6 +29,7 @@
#include <wx/wx.h>
#include <wx/config.h>
#include <wx/regex.h>
#include <common.h>
#include <convert_to_biu.h>
@ -38,10 +39,16 @@
namespace PCAD2KICAD {
// PCAD stroke font average ratio of width to size
const double TEXT_WIDTH_TO_SIZE_AVERAGE = 0.79;
const double TEXT_WIDTH_TO_SIZE_AVERAGE = 0.5;
// PCAD proportions of stroke font
const double TEXT_HEIGHT_TO_SIZE = 0.656;
const double TEXT_WIDTH_TO_SIZE = 0.656;
const double STROKE_HEIGHT_TO_SIZE = 0.656;
const double STROKE_WIDTH_TO_SIZE = 0.69;
// TrueType font
const double TRUETYPE_HEIGHT_TO_SIZE = 0.585;
const double TRUETYPE_WIDTH_TO_SIZE = 0.585;
const double TRUETYPE_THICK_PER_HEIGHT = 0.073;
const double TRUETYPE_BOLD_THICK_MUL = 1.6;
const long TRUETYPE_BOLD_MIN_WEIGHT = 700;
wxString GetWord( wxString* aStr )
{
@ -225,6 +232,18 @@ wxString ValidateName( wxString aName )
}
wxString ValidateReference( wxString aRef )
{
wxRegEx reRef;
reRef.Compile( wxT( "^[[:digit:]][[:digit:]]*$" ) );
if( reRef.Matches( aRef ) )
aRef.Prepend( wxT( '.' ) );
return aRef;
}
void SetWidth( wxString aStr,
wxString aDefaultMeasurementUnit,
int* aWidth,
@ -276,6 +295,7 @@ void SetDoublePrecisionPosition( wxString aStr,
aActualConversion );
}
TTEXT_JUSTIFY GetJustifyIdentificator( wxString aJustify )
{
TTEXT_JUSTIFY id;
@ -302,6 +322,7 @@ TTEXT_JUSTIFY GetJustifyIdentificator( wxString aJustify )
return id;
}
void SetTextParameters( XNODE* aNode,
TTEXTVALUE* aTextValue,
wxString aDefaultMeasurementUnit,
@ -327,12 +348,16 @@ void SetTextParameters( XNODE* aNode,
str.Trim( false );
aTextValue->textRotation = StrToInt1Units( str );
}
else
{
aTextValue->textRotation = 0;
}
str = FindNodeGetContent( aNode, wxT( "isVisible" ) );
if( str == wxT( "True" ) )
aTextValue->textIsVisible = 1;
else if( str == wxT( "False" ) )
else
aTextValue->textIsVisible = 0;
str = FindNodeGetContent( aNode, wxT( "justify" ) );
@ -342,6 +367,8 @@ void SetTextParameters( XNODE* aNode,
if( str == wxT( "True" ) )
aTextValue->mirror = 1;
else
aTextValue->mirror = 0;
tNode = FindNode( aNode, wxT( "textStyleRef" ) );
@ -363,49 +390,76 @@ void SetFontProperty( XNODE* aNode,
aNode = aNode->GetParent();
aNode = FindNode( aNode, wxT( "library" ) );
if( aNode )
aNode = FindNode( aNode, wxT( "textStyleDef" ) );
while( aNode )
{
aNode->GetAttribute( wxT( "Name" ), &propValue );
propValue.Trim( false );
propValue.Trim( true );
if( propValue == n )
break;
aNode = aNode->GetNext();
}
if( aNode )
{
while( true )
{
aNode->GetAttribute( wxT( "Name" ), &propValue );
propValue.Trim( false );
propValue.Trim( true );
wxString fontType;
if( propValue == n )
break;
propValue = FindNodeGetContent( aNode, wxT( "textStyleDisplayTType" ) );
aTextValue->isTrueType = ( propValue == wxT( "True" ) );
aNode = FindNode( aNode, wxT( "font" ) );
fontType = FindNodeGetContent( aNode, wxT( "fontType" ) );
if( ( aTextValue->isTrueType && ( fontType != wxT( "TrueType" ) ) ) ||
( !aTextValue->isTrueType && ( fontType != wxT( "Stroke" ) ) ) )
aNode = aNode->GetNext();
}
if( aNode )
{
aNode = FindNode( aNode, wxT( "font" ) );
if( aNode )
if( aTextValue->isTrueType )
{
if( FindNode( aNode, wxT( "fontHeight" ) ) )
// // SetWidth(iNode.ChildNodes.FindNode('fontHeight').Text,
// // DefaultMeasurementUnit,tv.TextHeight);
// Fixed By Lubo, 02/2008
SetHeight( FindNode( aNode, wxT(
"fontHeight" ) )->GetNodeContent(),
aDefaultMeasurementUnit, &aTextValue->textHeight,
aActualConversion );
propValue = FindNodeGetContent( aNode, wxT( "fontItalic" ) );
aTextValue->isItalic = ( propValue == wxT( "True" ) );
if( FindNode( aNode, wxT( "strokeWidth" ) ) )
SetWidth( FindNode( aNode, wxT(
"strokeWidth" ) )->GetNodeContent(),
aDefaultMeasurementUnit, &aTextValue->textstrokeWidth,
aActualConversion );
propValue = FindNodeGetContent( aNode, wxT( "fontWeight" ) );
if( propValue != wxEmptyString )
{
long fontWeight;
propValue.ToLong( &fontWeight );
aTextValue->isBold = ( fontWeight >= TRUETYPE_BOLD_MIN_WEIGHT );
}
}
XNODE* lNode;
lNode = FindNode( aNode, wxT( "fontHeight" ) );
if( lNode )
SetHeight( lNode->GetNodeContent(), aDefaultMeasurementUnit,
&aTextValue->textHeight, aActualConversion );
if( aTextValue->isTrueType )
{
aTextValue->textstrokeWidth = TRUETYPE_THICK_PER_HEIGHT * aTextValue->textHeight;
if( aTextValue->isBold )
aTextValue->textstrokeWidth *= TRUETYPE_BOLD_THICK_MUL;
}
else
{
lNode = FindNode( aNode, wxT( "strokeWidth" ) );
if( lNode )
SetWidth( lNode->GetNodeContent(), aDefaultMeasurementUnit,
&aTextValue->textstrokeWidth, aActualConversion );
}
}
}
}
void SetTextJustify( EDA_TEXT* aText, TTEXT_JUSTIFY aJustify )
{
switch( aJustify )
@ -449,110 +503,58 @@ void SetTextJustify( EDA_TEXT* aText, TTEXT_JUSTIFY aJustify )
}
}
int CalculateTextLengthSize( TTEXTVALUE* aText )
{
return KiROUND( (double) aText->text.Len() *
(double) aText->textHeight * TEXT_WIDTH_TO_SIZE_AVERAGE );
}
void CorrectTextPosition( TTEXTVALUE* aValue )
{
int cm = aValue->mirror ? -1 : 1;
// sizes of justify correction
int cl = KiROUND( (double) CalculateTextLengthSize( aValue ) / 2.0 );
int ch = KiROUND( (double) aValue->textHeight / 2.0 );
int posX = 0;
int posY = 0;
aValue->correctedPositionX = aValue->textPositionX;
aValue->correctedPositionY = aValue->textPositionY;
if( aValue->justify == LowerLeft ||
aValue->justify == Left ||
aValue->justify == UpperLeft )
posX += cl * cm;
else if( aValue->justify == LowerRight ||
aValue->justify == Right ||
aValue->justify == UpperRight )
posX -= cl * cm;
switch( aValue->textRotation )
{
case 0:
if( aValue->justify == LowerLeft ||
aValue->justify == Left ||
aValue->justify == UpperLeft )
aValue->correctedPositionX += cl * cm;
else if( aValue->justify == LowerRight ||
aValue->justify == Right ||
aValue->justify == UpperRight )
aValue->correctedPositionX -= cl * cm;
if( aValue->justify == LowerLeft ||
aValue->justify == LowerCenter ||
aValue->justify == LowerRight )
posY -= ch;
else if( aValue->justify == UpperLeft ||
aValue->justify == UpperCenter ||
aValue->justify == UpperRight )
posY += ch;
if( aValue->justify == LowerLeft ||
aValue->justify == LowerCenter ||
aValue->justify == LowerRight )
aValue->correctedPositionY -= ch;
else if( aValue->justify == UpperLeft ||
aValue->justify == UpperCenter ||
aValue->justify == UpperRight )
aValue->correctedPositionY += ch;
break;
case 900:
if( aValue->justify == LowerLeft ||
aValue->justify == LowerCenter ||
aValue->justify == LowerRight )
aValue->correctedPositionX -= ch * cm;
else if( aValue->justify == UpperLeft ||
aValue->justify == UpperCenter ||
aValue->justify == UpperRight )
aValue->correctedPositionX += ch * cm;
RotatePoint( &posX, &posY, aValue->textRotation );
if( aValue->justify == LowerLeft ||
aValue->justify == Left ||
aValue->justify == UpperLeft )
aValue->correctedPositionY -= cl;
else if( aValue->justify == LowerRight ||
aValue->justify == Right ||
aValue->justify == UpperRight )
aValue->correctedPositionY += cl;
break;
case 1800:
if( aValue->justify == LowerLeft ||
aValue->justify == Left ||
aValue->justify == UpperLeft )
aValue->correctedPositionX -= cl * cm;
else if( aValue->justify == LowerRight ||
aValue->justify == Right ||
aValue->justify == UpperRight )
aValue->correctedPositionX += cl * cm;
if( aValue->justify == LowerLeft ||
aValue->justify == LowerCenter ||
aValue->justify == LowerRight )
aValue->correctedPositionY += ch;
else if( aValue->justify == UpperLeft ||
aValue->justify == UpperCenter ||
aValue->justify == UpperRight )
aValue->correctedPositionY -= ch;
break;
case 2700:
if( aValue->justify == LowerLeft ||
aValue->justify == LowerCenter ||
aValue->justify == LowerRight )
aValue->correctedPositionX += ch * cm;
else if( aValue->justify == UpperLeft ||
aValue->justify == UpperCenter ||
aValue->justify == UpperRight )
aValue->correctedPositionX -= ch * cm;
if( aValue->justify == LowerLeft ||
aValue->justify == Left ||
aValue->justify == UpperLeft )
aValue->correctedPositionY += cl;
else if( aValue->justify == LowerRight ||
aValue->justify == Right ||
aValue->justify == UpperRight )
aValue->correctedPositionY -= cl;
break;
default:
break;
}
aValue->correctedPositionX = aValue->textPositionX + posX;
aValue->correctedPositionY = aValue->textPositionY + posY;
}
void SetTextSizeFromStrokeFontHeight( EDA_TEXT* aText, int aTextHeight )
{
aText->SetTextSize( wxSize( KiROUND( aTextHeight * TEXT_WIDTH_TO_SIZE ),
KiROUND( aTextHeight * TEXT_HEIGHT_TO_SIZE ) ) );
aText->SetTextSize( wxSize( KiROUND( aTextHeight * STROKE_WIDTH_TO_SIZE ),
KiROUND( aTextHeight * STROKE_HEIGHT_TO_SIZE ) ) );
}
void SetTextSizeFromTrueTypeFontHeight( EDA_TEXT* aText, int aTextHeight )
{
aText->SetTextSize( wxSize( KiROUND( aTextHeight * TRUETYPE_WIDTH_TO_SIZE ),
KiROUND( aTextHeight * TRUETYPE_HEIGHT_TO_SIZE ) ) );
}
@ -601,6 +603,9 @@ void InitTTextValue( TTEXTVALUE* aTextValue )
aTextValue->correctedPositionX = 0;
aTextValue->correctedPositionY = 0;
aTextValue->justify = LowerLeft;
aTextValue->isBold = false;
aTextValue->isItalic = false;
aTextValue->isTrueType = false;
}
} // namespace PCAD2KICAD

View File

@ -56,12 +56,15 @@ enum TTEXT_JUSTIFY
typedef struct _TTEXTVALUE
{
wxString text;
int textPositionX, textPositionY,
textRotation, textHeight, textstrokeWidth;
int textIsVisible, mirror, textUnit;
int correctedPositionX, correctedPositionY;
wxString text;
int textPositionX, textPositionY,
textRotation, textHeight, textstrokeWidth;
int textIsVisible, mirror, textUnit;
int correctedPositionX, correctedPositionY;
TTEXT_JUSTIFY justify;
bool isBold;
bool isItalic;
bool isTrueType;
} TTEXTVALUE;
extern wxString GetWord( wxString* aStr );
@ -71,6 +74,7 @@ extern wxString GetAndCutWordWithMeasureUnits( wxString* aStr,
wxString aDefaultMeasurementUnit );
extern int StrToInt1Units( wxString aStr );
extern wxString ValidateName( wxString aName );
extern wxString ValidateReference( wxString aRef );
extern void SetWidth( wxString aStr,
wxString aDefaultMeasurementUnit,
int* aWidth,
@ -99,7 +103,7 @@ extern int CalculateTextLengthSize( TTEXTVALUE* aText );
extern void CorrectTextPosition( TTEXTVALUE* aValue );
extern void SetTextSizeFromStrokeFontHeight( EDA_TEXT* aText,
int aTextHeight );
extern void SetTextSizeFromTrueTypeFontHeight( EDA_TEXT* aText, int aTextHeight );
extern XNODE* FindNode( XNODE* aChild, wxString aTag );
extern wxString FindNodeGetContent( XNODE* aChild, wxString aTag );
extern void InitTTextValue( TTEXTVALUE* aTextValue );

View File

@ -487,7 +487,7 @@ void PCB::MapLayer( XNODE* aNode )
lName = lName.MakeUpper();
if( lName == wxT( "TOP ASSY" ) )
KiCadLayer = Cmts_User;
KiCadLayer = F_Fab;
else if( lName == wxT( "TOP SILK" ) )
KiCadLayer = F_SilkS;
else if( lName == wxT( "TOP PASTE" ) )
@ -505,7 +505,7 @@ void PCB::MapLayer( XNODE* aNode )
else if( lName == wxT( "BOT SILK" ) )
KiCadLayer = B_SilkS;
else if( lName == wxT( "BOT ASSY" ) )
KiCadLayer = Dwgs_User;
KiCadLayer = B_Fab;
else if( lName == wxT( "BOARD" ) )
KiCadLayer = Edge_Cuts;
else

View File

@ -160,7 +160,7 @@ void PCB_ARC::AddToModule( MODULE* aModule )
{
if( IsNonCopperLayer( m_KiCadLayer ) )
{
EDGE_MODULE* arc = new EDGE_MODULE( aModule, S_ARC );
EDGE_MODULE* arc = new EDGE_MODULE( aModule, ( IsCircle() ? S_CIRCLE : S_ARC ) );
aModule->GraphicalItemsList().PushBack( arc );
arc->SetAngle( -m_angle );
@ -181,7 +181,7 @@ void PCB_ARC::AddToBoard()
m_board->Add( dseg, ADD_APPEND );
dseg->SetShape( S_ARC );
dseg->SetShape( IsCircle() ? S_CIRCLE : S_ARC );
dseg->SetTimeStamp( m_timestamp );
dseg->SetLayer( m_KiCadLayer );
dseg->SetStart( wxPoint( m_positionX, m_positionY ) );
@ -190,4 +190,10 @@ void PCB_ARC::AddToBoard()
dseg->SetWidth( m_width );
}
bool PCB_ARC::IsCircle()
{
return ( m_angle == 3600 );
}
} // namespace PCAD2KICAD

View File

@ -54,6 +54,9 @@ public:
virtual void Flip() override;
void AddToModule( MODULE* aModule ) override;
void AddToBoard() override;
private:
bool IsCircle();
};
} // namespace PCAD2KICAD

View File

@ -526,21 +526,26 @@ void PCB_MODULE::AddToBoard()
// reference text
TEXTE_MODULE* ref_text = &module->Reference();
ref_text->SetText( m_name.text );
ref_text->SetText( ValidateReference( m_name.text ) );
ref_text->SetType( TEXTE_MODULE::TEXT_is_REFERENCE );
ref_text->SetPos0( wxPoint( m_name.correctedPositionX, m_name.correctedPositionY ) );
SetTextSizeFromStrokeFontHeight( ref_text, m_name.textHeight );
if( m_name.isTrueType )
SetTextSizeFromTrueTypeFontHeight( ref_text, m_name.textHeight );
else
SetTextSizeFromStrokeFontHeight( ref_text, m_name.textHeight );
r = m_name.textRotation - m_rotation;
ref_text->SetTextAngle( r );
ref_text->SetUnlocked( true );
ref_text->SetItalic( m_name.isItalic );
ref_text->SetThickness( m_name.textstrokeWidth );
ref_text->SetMirrored( m_name.mirror );
ref_text->SetVisible( m_name.textIsVisible );
ref_text->SetLayer( m_KiCadLayer );
ref_text->SetLayer( m_name.mirror ? FlipLayer( m_KiCadLayer ) : m_KiCadLayer );
// Calculate the actual position.
ref_text->SetDrawCoord();
@ -552,17 +557,22 @@ void PCB_MODULE::AddToBoard()
val_text->SetType( TEXTE_MODULE::TEXT_is_VALUE );
val_text->SetPos0( wxPoint( m_value.correctedPositionX, m_value.correctedPositionY ) );
SetTextSizeFromStrokeFontHeight( val_text, m_value.textHeight );
if( m_value.isTrueType )
SetTextSizeFromTrueTypeFontHeight( val_text, m_value.textHeight );
else
SetTextSizeFromStrokeFontHeight( val_text, m_value.textHeight );
r = m_value.textRotation - m_rotation;
val_text->SetTextAngle( r );
val_text->SetUnlocked( true );
val_text->SetItalic( m_value.isItalic );
val_text->SetThickness( m_value.textstrokeWidth );
val_text->SetMirrored( m_value.mirror );
val_text->SetVisible( m_value.textIsVisible );
val_text->SetLayer( m_KiCadLayer );
val_text->SetLayer( m_value.mirror ? FlipLayer( m_KiCadLayer ) : m_KiCadLayer );
// Calculate the actual position.
val_text->SetDrawCoord();
@ -591,6 +601,13 @@ void PCB_MODULE::AddToBoard()
m_moduleObjects[i]->AddToModule( module );
}
// MODULE POLYGONS
for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
{
if( m_moduleObjects[i]->m_objType == wxT( 'Z' ) )
m_moduleObjects[i]->AddToModule( module );
}
// PADS
for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
{
@ -615,14 +632,13 @@ void PCB_MODULE::Flip()
if( m_mirror == 1 )
{
// Flipped
m_KiCadLayer = FlipLayer( m_KiCadLayer );
m_rotation = -m_rotation;
m_rotation = -m_rotation;
for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
{
if( m_moduleObjects[i]->m_objType == wxT( 'L' ) || // lines
m_moduleObjects[i]->m_objType == wxT( 'A' ) || // arcs
m_moduleObjects[i]->m_objType == wxT( 'Z' ) || // polygons
m_moduleObjects[i]->m_objType == wxT( 'P' ) || // pads
m_moduleObjects[i]->m_objType == wxT( 'V' ) ) // vias
{

View File

@ -157,6 +157,25 @@ bool PCB_POLYGON::Parse( XNODE* aNode,
void PCB_POLYGON::AddToModule( MODULE* aModule )
{
if( IsNonCopperLayer( m_KiCadLayer ) )
{
EDGE_MODULE* dwg = new EDGE_MODULE( aModule, S_POLYGON );
aModule->GraphicalItemsList().PushBack( dwg );
dwg->SetWidth( 0 );
dwg->SetLayer( m_KiCadLayer );
auto outline = new std::vector<wxPoint>;
for( auto point : m_outline )
outline->push_back( wxPoint( point->x, point->y ) );
dwg->SetPolyPoints( *outline );
dwg->SetStart0( *outline->begin() );
dwg->SetEnd0( outline->back() );
dwg->SetDrawCoord();
delete( outline );
}
}
@ -208,6 +227,14 @@ void PCB_POLYGON::AddToBoard()
}
void PCB_POLYGON::Flip()
{
PCB_COMPONENT::Flip();
m_KiCadLayer = FlipLayer( m_KiCadLayer );
}
void PCB_POLYGON::SetPosOffset( int aX_offs, int aY_offs )
{
int i, island;

View File

@ -56,6 +56,7 @@ public:
wxString aActualConversion );
virtual void SetPosOffset( int aX_offs, int aY_offs ) override;
virtual void Flip() override;
void AddToModule( MODULE* aModule ) override;
void AddToBoard() override;

View File

@ -110,8 +110,12 @@ void PCB_TEXT::AddToBoard()
pcbtxt->SetText( m_name.text );
SetTextSizeFromStrokeFontHeight( pcbtxt, m_name.textHeight );
if( m_name.isTrueType )
SetTextSizeFromTrueTypeFontHeight( pcbtxt, m_name.textHeight );
else
SetTextSizeFromStrokeFontHeight( pcbtxt, m_name.textHeight );
pcbtxt->SetItalic( m_name.isItalic );
pcbtxt->SetThickness( m_name.textstrokeWidth );
pcbtxt->SetTextAngle( m_name.textRotation );