2719 lines
61 KiB
Plaintext
2719 lines
61 KiB
Plaintext
//=====================================
|
||
//
|
||
// Converter of CadSoft-Eagle board designs to the Specctra DSN-Textformat.
|
||
//
|
||
// Created by ConnectEDA extended and modified by Thomas Kaeubler and Alfons Wirtz.
|
||
//
|
||
// Many thanks to ConnectEDA for allowing us to use their pcb_to_dsn ulp-file.
|
||
//
|
||
//
|
||
// Last change November 23th 2008
|
||
//
|
||
//=====================================
|
||
|
||
int preprotect = 0;
|
||
int string_quote = 1;
|
||
real polyline_endpoint_tolerance = 0.001; // The tolerance for regarding 2 line endpoints as equal.
|
||
|
||
enum {false,true};
|
||
int Units;
|
||
|
||
string layer_name[];
|
||
string TopLayer, BotLayer;
|
||
real default_wire_width, default_via_size, default_drill_size, default_clearance, rv_pad_inner, min_via_inner, min_pad_inner, max_pad_inner;
|
||
real clearance_wire_pad, clearance_wire_smd, clearance_wire_via, clearance_pad_pad, clearance_pad_via;
|
||
real clearance_via_via, clearance_smd_pad, clearance_smd_via, clearance_smd_smd;
|
||
|
||
|
||
|
||
|
||
|
||
void write_Db2Unit(int Length)
|
||
//----------------------------
|
||
{
|
||
real Value;
|
||
switch (Units)
|
||
{
|
||
case GRID_UNIT_MM :
|
||
Value = u2mm(Length);
|
||
break;
|
||
|
||
case GRID_UNIT_MIL :
|
||
Value = u2mil(Length);
|
||
break;
|
||
|
||
case GRID_UNIT_INCH :
|
||
Value = u2inch(Length);
|
||
break;
|
||
|
||
case GRID_UNIT_MIC :
|
||
Value = u2mic(Length);
|
||
break;
|
||
|
||
}
|
||
string String;
|
||
sprintf(String,"%f",Value);
|
||
printf(String);
|
||
}
|
||
|
||
void write_Int(int Val)
|
||
//---------------------
|
||
{
|
||
string String;
|
||
sprintf(String,"%d",Val);
|
||
printf(String);
|
||
}
|
||
|
||
void write_Real(real Val)
|
||
//-----------------------
|
||
{
|
||
string String;
|
||
sprintf(String,"%f",Val);
|
||
printf(String);
|
||
}
|
||
|
||
void write_qStr(string String)
|
||
//----------------------------
|
||
{
|
||
if (string_quote)
|
||
printf("\"");
|
||
printf(String);
|
||
if (string_quote)
|
||
printf("\"");
|
||
}
|
||
|
||
void write_Str(string String)
|
||
//---------------------------
|
||
{
|
||
printf(String);
|
||
}
|
||
|
||
|
||
real Db2Unit(int Length)
|
||
//---------------------
|
||
{
|
||
real Value = 0;
|
||
switch (Units)
|
||
{
|
||
case GRID_UNIT_MM :
|
||
Value = u2mm(Length);
|
||
break;
|
||
|
||
case GRID_UNIT_MIL :
|
||
Value = u2mil(Length);
|
||
break;
|
||
|
||
case GRID_UNIT_INCH :
|
||
Value = u2inch(Length);
|
||
break;
|
||
|
||
case GRID_UNIT_MIC :
|
||
Value = u2mic(Length);
|
||
break;
|
||
|
||
}
|
||
|
||
return Value;
|
||
}
|
||
|
||
real mm2u(real val)
|
||
//-----------------
|
||
{
|
||
real Value = 0;
|
||
switch (Units)
|
||
{
|
||
case GRID_UNIT_MM :
|
||
Value = val;
|
||
break;
|
||
|
||
case GRID_UNIT_MIL :
|
||
Value = val*39.3700787402;
|
||
break;
|
||
|
||
case GRID_UNIT_INCH :
|
||
Value = val*0.0393700787402;
|
||
break;
|
||
|
||
case GRID_UNIT_MIC :
|
||
Value = val*0.001;
|
||
break;
|
||
|
||
}
|
||
|
||
|
||
return Value;
|
||
}
|
||
|
||
real mil2u(real val)
|
||
//-----------------
|
||
{
|
||
real Value = 0;
|
||
switch (Units)
|
||
{
|
||
case GRID_UNIT_MM :
|
||
Value = val*0.0254;
|
||
break;
|
||
|
||
case GRID_UNIT_MIL :
|
||
Value = val;
|
||
break;
|
||
|
||
case GRID_UNIT_INCH :
|
||
Value = val*0.001;
|
||
break;
|
||
|
||
case GRID_UNIT_MIC :
|
||
Value = val*0.0000254;
|
||
break;
|
||
|
||
}
|
||
|
||
return Value;
|
||
}
|
||
|
||
real inch2u(real val)
|
||
//-----------------
|
||
{
|
||
real Value = 0;
|
||
switch (Units)
|
||
{
|
||
case GRID_UNIT_MM :
|
||
Value = val*25.4;
|
||
break;
|
||
|
||
case GRID_UNIT_MIL :
|
||
Value = val*1000;
|
||
break;
|
||
|
||
case GRID_UNIT_INCH :
|
||
Value = val;
|
||
break;
|
||
|
||
case GRID_UNIT_MIC :
|
||
Value = val*0.0254;
|
||
break;
|
||
|
||
}
|
||
|
||
return Value;
|
||
}
|
||
|
||
real mic2u(real val)
|
||
//-----------------
|
||
{
|
||
real Value = 0;
|
||
switch (Units)
|
||
{
|
||
case GRID_UNIT_MM :
|
||
Value = val*0.001;
|
||
break;
|
||
|
||
case GRID_UNIT_MIL :
|
||
Value = val*0.0393700787402;
|
||
break;
|
||
|
||
case GRID_UNIT_INCH :
|
||
Value = val*0.0000393700787402;
|
||
break;
|
||
|
||
case GRID_UNIT_MIC :
|
||
Value = val;
|
||
break;
|
||
|
||
}
|
||
|
||
|
||
return Value;
|
||
}
|
||
|
||
int u2int_u(real val)
|
||
//-----------------
|
||
{
|
||
int Value = 0;
|
||
switch (Units)
|
||
{
|
||
case GRID_UNIT_MM :
|
||
Value = val*10000;
|
||
break;
|
||
|
||
case GRID_UNIT_MIL :
|
||
Value = val*254;
|
||
break;
|
||
|
||
case GRID_UNIT_INCH :
|
||
Value = val*254000;
|
||
break;
|
||
|
||
case GRID_UNIT_MIC :
|
||
Value = val;
|
||
break;
|
||
|
||
}
|
||
|
||
return Value;
|
||
}
|
||
|
||
real Unit2Value(real val, string s)
|
||
//---------------------
|
||
{
|
||
real Value = 0;
|
||
if( s=="m" )
|
||
{
|
||
Value = mm2u(val);
|
||
}
|
||
else
|
||
if( s=="l" )
|
||
{
|
||
Value = mil2u(val);
|
||
}
|
||
else
|
||
if( s=="h" )
|
||
{
|
||
Value = inch2u(val);
|
||
}
|
||
else
|
||
if( s=="c" )
|
||
{
|
||
Value = mic2u(val);
|
||
}
|
||
else
|
||
{
|
||
Value = val;
|
||
}
|
||
return Value;
|
||
}
|
||
|
||
// Returns the new x coordinate of the point (p_x, p_y) after rotating around the zero point by p_degree degrees.
|
||
real rotate_x( real p_x, real p_y, real p_degree)
|
||
{
|
||
real angle = p_degree * PI / 180.0;
|
||
real rotated_x = p_x * cos(angle) - p_y * sin(angle);
|
||
return rotated_x;
|
||
}
|
||
|
||
// Returns the new x coordinate of the point (p_x, p_y) after rotating around the zero point by p_degree degrees.
|
||
real rotate_y( real p_x, real p_y, real p_degree)
|
||
{
|
||
real angle = p_degree * PI / 180.0;
|
||
real rotated_y = p_x * sin(angle) + p_y * cos(angle);
|
||
return rotated_y;
|
||
}
|
||
|
||
|
||
//=================================================================
|
||
|
||
int NumberPadTypes = 0;
|
||
numeric string PadTypeName[];
|
||
string ViaTypeName[];
|
||
int PadTypeshape[];
|
||
int PadTypeDrill[];
|
||
int PadTypeX[];
|
||
int PadTypeY[];
|
||
int PadTypeE[];
|
||
int PadTypeAngle[];
|
||
int PadTypeLayer[];
|
||
int PadShapeRectangle=99;
|
||
//Erweiterung---------------------------------------
|
||
int ViaTypeStart[];
|
||
int ViaTypeEnd[];
|
||
|
||
//--------------------------------------------------
|
||
int ViaType = 0;
|
||
|
||
string layer_setup; // = "(1*16)";
|
||
int Layer_No[];
|
||
int Layer_count=0;
|
||
string LayerSetup[];
|
||
int LayerSetup_rk[];
|
||
int LayerSetup_ek[];
|
||
int NumberLayer=0;
|
||
|
||
int ViaBracketLevel[];
|
||
int ViaBracketPos[];
|
||
int ViaTypeDrill[];
|
||
|
||
int rgw;
|
||
|
||
|
||
int read_layer_setup(UL_BOARD B)
|
||
//----------------------------
|
||
{
|
||
int i;
|
||
int n = strlen(layer_setup);
|
||
int ek=0;
|
||
int rk=0;
|
||
int no=0;
|
||
int count=0;
|
||
|
||
for (i=0; i<n; i++)
|
||
{
|
||
string tmp_s = strsub(layer_setup, i, 1);
|
||
if (tmp_s == "[")
|
||
{
|
||
ek++;
|
||
LayerSetup_ek[count]=ek;
|
||
}
|
||
if (tmp_s == "(")
|
||
{
|
||
rk++;
|
||
LayerSetup_rk[count]=rk;
|
||
}
|
||
if (tmp_s == "]")
|
||
{
|
||
LayerSetup_ek[count]=ek;
|
||
ek--;
|
||
}
|
||
if (tmp_s == ")")
|
||
{
|
||
LayerSetup_rk[count]=rk;
|
||
rk--;
|
||
}
|
||
if (tmp_s=="0"||tmp_s=="1"||tmp_s=="2"||tmp_s=="3"||tmp_s=="4"||tmp_s=="5"||
|
||
tmp_s=="6"||tmp_s=="7"||tmp_s=="8"||tmp_s=="9")
|
||
{
|
||
if(no==1)
|
||
{
|
||
tmp_s = strsub(layer_setup, i-1, 2);
|
||
count--;
|
||
}
|
||
no=1;
|
||
|
||
}
|
||
else
|
||
{
|
||
no=0;
|
||
}
|
||
|
||
LayerSetup[count]=tmp_s;
|
||
count++;
|
||
}
|
||
return count;
|
||
}
|
||
|
||
string NewPadTypeName(int ShapeType)
|
||
//----------------------------------
|
||
{
|
||
string Name;
|
||
int i=0;
|
||
int Highest=-1;
|
||
if (ShapeType == PAD_SHAPE_SQUARE)
|
||
{
|
||
Name = "Square";
|
||
}
|
||
else
|
||
if (ShapeType == PAD_SHAPE_ROUND)
|
||
{
|
||
Name = "Round";
|
||
}
|
||
else
|
||
if (ShapeType == PAD_SHAPE_OCTAGON)
|
||
{
|
||
Name = "Octagon";
|
||
}
|
||
else
|
||
if (ShapeType == PadShapeRectangle)
|
||
{
|
||
Name = "Rectangle";
|
||
}
|
||
else
|
||
if (ShapeType == PAD_SHAPE_LONG)
|
||
{
|
||
Name = "Oblong";
|
||
}
|
||
if (ShapeType == PAD_SHAPE_OFFSET)
|
||
{
|
||
Name = "Offset";
|
||
}
|
||
for (i = 0; i < NumberPadTypes; i++)
|
||
{
|
||
if (PadTypeshape[i] == ShapeType)
|
||
{
|
||
Highest = i;
|
||
}
|
||
}
|
||
|
||
int Index = 1;
|
||
if (Highest >= 0)
|
||
{
|
||
string IndexString = strsub(PadTypeName[Highest], strlen(Name));
|
||
Index = strtol(IndexString) + 1;
|
||
}
|
||
|
||
sprintf(Name, "%s%d", Name, Index);
|
||
|
||
return(Name);
|
||
}
|
||
|
||
int write_ViaType(UL_BOARD B, int n)
|
||
//----------------------------
|
||
{
|
||
int i=0;
|
||
|
||
//----Blinde Via from Top
|
||
for (i=0; i<n; i++)
|
||
{
|
||
if (LayerSetup[i] == "[" && LayerSetup[i+1]!="[" && LayerSetup[i+1]!="(")
|
||
{
|
||
if (LayerSetup[i+2]==":")
|
||
{
|
||
ViaTypeEnd[ViaType++]=strtol(LayerSetup[i+1]);
|
||
|
||
for (int j=i+1; j<n; j++)
|
||
{
|
||
if (
|
||
LayerSetup[j]==":"
|
||
&&
|
||
(strtol(LayerSetup[j+1])>0 && strtol(LayerSetup[j+1])<17)
|
||
&&
|
||
(LayerSetup[j+2]=="+" || LayerSetup[j+2]=="*")
|
||
)
|
||
{
|
||
ViaTypeStart[ViaType-1]=strtol(LayerSetup[j+1]);
|
||
break;
|
||
}
|
||
if (
|
||
LayerSetup[j]==":"
|
||
&&
|
||
( LayerSetup[j+1]=="[" || LayerSetup[j+1]=="(" )
|
||
&&
|
||
(strtol(LayerSetup[j+2])>0 && strtol(LayerSetup[j+2])<17)
|
||
&&
|
||
(LayerSetup[j+3]=="+" || LayerSetup[j+3]=="*")
|
||
)
|
||
{
|
||
ViaTypeStart[ViaType-1]=strtol(LayerSetup[j+2]);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//----Blinde Via from Bottom
|
||
for (i=n; i>0; i--)
|
||
{
|
||
if (LayerSetup[i] == "]" && LayerSetup[i-1]!="]" && LayerSetup[i-1]!=")")
|
||
{
|
||
if (LayerSetup[i-2]==":")
|
||
{
|
||
ViaTypeStart[ViaType++]=strtol(LayerSetup[i-1]);
|
||
|
||
for (int j=i-1; j>=0; j--)
|
||
{
|
||
if (
|
||
LayerSetup[j]==":"
|
||
&&
|
||
(strtol(LayerSetup[j-1])>0 && strtol(LayerSetup[j-1])<17)
|
||
&&
|
||
(LayerSetup[j-2]=="+" || LayerSetup[j-2]=="*")
|
||
)
|
||
{
|
||
ViaTypeEnd[ViaType-1]=strtol(LayerSetup[j-1]);
|
||
break;
|
||
}
|
||
if (
|
||
LayerSetup[j]==":"
|
||
&&
|
||
( LayerSetup[j-1]=="]" || LayerSetup[j-1]==")" )
|
||
&&
|
||
(strtol(LayerSetup[j-2])>0 && strtol(LayerSetup[j-2])<17)
|
||
&&
|
||
(LayerSetup[j-3]=="+" || LayerSetup[j-3]=="*")
|
||
)
|
||
{
|
||
ViaTypeEnd[ViaType-1]=strtol(LayerSetup[j-2]);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//----Buried Via from Top
|
||
int BracketStart[];
|
||
int BracketEnd[];
|
||
|
||
// Offene Klammern zu denen noch keine passende geschlossene Klammer gefunden wurde.
|
||
// Tempor<6F>rer Array, der nur w<>hrend der Berechnung ben<65>tigt wird.
|
||
int unhandeled_open_brackets [];
|
||
int unhandeled_open_bracket_count = 0;
|
||
|
||
// Arrays der gefundenen Positionen der zueinander passenen offenen und geschlossenen Klammern.
|
||
int bracket_count;
|
||
int open_brackets[];
|
||
int closed_brackets[];
|
||
|
||
// Berechnet Paare von offenen und geschlossenen Klammern und speichert das Ergebnis in
|
||
// den Arrays open_brackets und closed_brackets
|
||
|
||
// Schleife <20>ber den ganzen String
|
||
for (i=0; i<n ; i++)
|
||
{
|
||
// gehe bis zur n<>chsten geschlossenen Klammer und paare sie mit der letzen
|
||
// offenen Klammer im Array unhandeled_open_brackets.
|
||
if(LayerSetup[i]=="(")
|
||
{
|
||
unhandeled_open_brackets[unhandeled_open_bracket_count] = i;
|
||
++unhandeled_open_bracket_count;
|
||
}
|
||
else if(LayerSetup[i]==")")
|
||
{
|
||
// Geschlossene Klammer gefunden.
|
||
closed_brackets[bracket_count] = i;
|
||
|
||
if (unhandeled_open_bracket_count <= 0)
|
||
{
|
||
// Fehler, der geschlossenen Klammer geht keine offene Klammer vorous
|
||
}
|
||
// Die passende offenne Klammer ist die letzte im Array unhandeled_open_brackets
|
||
// F<>ge sie zum Array open_brackets hinzu und entferne sie aus dem Array unhandeled_open_brackets
|
||
--unhandeled_open_bracket_count;
|
||
open_brackets[bracket_count] = unhandeled_open_brackets [unhandeled_open_bracket_count];
|
||
++bracket_count;
|
||
}
|
||
}
|
||
|
||
if (unhandeled_open_bracket_count != 0)
|
||
{
|
||
// Fehler, Anzahl der offenen und geschlossenen Klammern ist nicht gleich
|
||
}
|
||
for( i=0; i<bracket_count; i++)
|
||
{
|
||
int j;
|
||
for( j=open_brackets[i]; j<=closed_brackets[i]; j++)
|
||
{
|
||
if( LayerSetup[j]=="(" && (strtol(LayerSetup[j+1])>0 && strtol(LayerSetup[j+1])<17))
|
||
{
|
||
ViaTypeStart[ViaType]=strtol(LayerSetup[j+1]);
|
||
break;
|
||
}
|
||
}
|
||
for(j=closed_brackets[i]; j>=open_brackets[i]; j--)
|
||
{
|
||
if( LayerSetup[j]==")" && (strtol(LayerSetup[j-1])>0 && strtol(LayerSetup[j-1])<17))
|
||
{
|
||
ViaTypeEnd[ViaType++]=strtol(LayerSetup[j-1]);
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
NumberPadTypes = ViaType;
|
||
|
||
for (i=0; i<ViaType; i++)
|
||
{
|
||
PadTypeshape[i]=1;
|
||
PadTypeX[i] = u2int_u(default_via_size);
|
||
PadTypeDrill[i] = u2int_u(default_drill_size);
|
||
PadTypeY[i] = 0;
|
||
PadTypeE[i] = 0;
|
||
PadTypeAngle[i] = 0;
|
||
PadTypeLayer[i] = 0;
|
||
sprintf(PadTypeName[i], "%s%d$%f", "Round", i+1, Db2Unit(PadTypeDrill[i]));
|
||
ViaTypeName[i] = PadTypeName[i];
|
||
}
|
||
return n;
|
||
}
|
||
|
||
|
||
int find_layer(UL_BOARD B,int n)
|
||
//----------------------------
|
||
{
|
||
string tmp;
|
||
for (int i=0; i<n; i++)
|
||
{
|
||
int Found=-1;
|
||
if(strtol(LayerSetup[i])>0 && strtol(LayerSetup[i])<17)
|
||
{
|
||
for (int j=0; (j<Layer_count); j++)
|
||
{
|
||
if (Layer_No[j]==strtol(LayerSetup[i]))
|
||
{
|
||
Found=j;
|
||
break;
|
||
}
|
||
}
|
||
if(Found==-1)
|
||
{
|
||
Layer_No[Layer_count++]=strtol(LayerSetup[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
sort( Layer_count, Layer_No);
|
||
|
||
for (int j=0; (j<Layer_count); j++)
|
||
{
|
||
sprintf(tmp, "%d", Layer_No[j]);
|
||
}
|
||
return Layer_count;
|
||
}
|
||
|
||
void PTHPadType(UL_PAD Pad)
|
||
//-------------------------
|
||
{
|
||
int i=0;
|
||
int Found=-1;
|
||
|
||
for (i=0; (i<NumberPadTypes) && (Found==-1); i++)
|
||
{
|
||
if (PadTypeshape[i] == Pad.shape[LAYER_TOP] &&
|
||
PadTypeX[i] == Pad.diameter[LAYER_TOP] &&
|
||
PadTypeE[i] == Pad.elongation &&
|
||
PadTypeAngle[i] == Pad.angle &&
|
||
PadTypeDrill[i] == Pad.drill &&
|
||
PadTypeY[i] == 0 &&
|
||
PadTypeLayer[i] == 0)
|
||
{
|
||
Found = i;
|
||
}
|
||
}
|
||
|
||
if (Found==-1)
|
||
{
|
||
PadTypeName[NumberPadTypes] = NewPadTypeName(Pad.shape[LAYER_TOP]);
|
||
PadTypeshape[NumberPadTypes] = Pad.shape[LAYER_TOP];
|
||
PadTypeX[NumberPadTypes] = Pad.diameter[LAYER_TOP];
|
||
PadTypeE[NumberPadTypes] = Pad.elongation;
|
||
PadTypeAngle[NumberPadTypes] = Pad.angle;
|
||
PadTypeDrill[NumberPadTypes] = Pad.drill;
|
||
PadTypeY[NumberPadTypes] = 0;
|
||
PadTypeLayer[NumberPadTypes] = 0;
|
||
NumberPadTypes++;
|
||
}
|
||
}
|
||
|
||
|
||
void SMDPadType(UL_SMD Pad)
|
||
//-------------------------
|
||
{
|
||
int i=0;
|
||
int Found=-1;
|
||
int ShapeType = PadShapeRectangle;
|
||
|
||
// Fehlerhaft bei rechteckigen SMD-Pads mit Roundness 100 20050620 thk
|
||
if (Pad.roundness == 100)
|
||
ShapeType = PAD_SHAPE_ROUND;
|
||
|
||
for (i=0; (i<NumberPadTypes) && (Found==-1); i++)
|
||
{
|
||
if (PadTypeshape[i] == ShapeType &&
|
||
PadTypeX[i] == Pad.dx &&
|
||
PadTypeY[i] == Pad.dy &&
|
||
PadTypeAngle[i] == Pad.angle &&
|
||
PadTypeLayer[i] == Pad.layer)
|
||
{
|
||
Found = i;
|
||
}
|
||
}
|
||
|
||
if (Found == -1)
|
||
{
|
||
PadTypeName[NumberPadTypes] = NewPadTypeName(ShapeType);
|
||
PadTypeshape[NumberPadTypes] = ShapeType;
|
||
PadTypeX[NumberPadTypes] = Pad.dx;
|
||
PadTypeY[NumberPadTypes] = Pad.dy;
|
||
PadTypeE[NumberPadTypes] = 0;
|
||
PadTypeAngle[NumberPadTypes] = Pad.angle;
|
||
PadTypeDrill[NumberPadTypes] = 0;
|
||
PadTypeLayer[NumberPadTypes] = Pad.layer;
|
||
NumberPadTypes++;
|
||
}
|
||
|
||
}
|
||
|
||
void ViaPadType(UL_VIA Via)
|
||
//-------------------------
|
||
{
|
||
int i=0;
|
||
int Found=-1;
|
||
|
||
for (i=0; (i<NumberPadTypes) && (Found==-1); i++)
|
||
{
|
||
if (PadTypeshape[i] == Via.shape[LAYER_TOP] &&
|
||
PadTypeX[i] == Via.diameter[LAYER_TOP] &&
|
||
PadTypeDrill[i] == Via.drill &&
|
||
//Erweiterung---------------------------------------
|
||
ViaTypeStart[i] == Via.start &&
|
||
ViaTypeEnd[i] == Via.end &&
|
||
//--------------------------------------------------
|
||
PadTypeY[i] == 0 &&
|
||
PadTypeLayer[i] == 0)
|
||
{
|
||
Found = i;
|
||
}
|
||
}
|
||
|
||
if (Found==-1)
|
||
{
|
||
//Erweiterung---------------------------------------
|
||
ViaTypeStart[NumberPadTypes] = Via.start;
|
||
ViaTypeEnd[NumberPadTypes] = Via.end;
|
||
//--------------------------------------------------
|
||
PadTypeshape[NumberPadTypes] = Via.shape[LAYER_TOP];
|
||
PadTypeX[NumberPadTypes] = Via.diameter[LAYER_TOP];
|
||
PadTypeDrill[NumberPadTypes] = Via.drill;
|
||
PadTypeY[NumberPadTypes] = 0;
|
||
PadTypeE[NumberPadTypes] = 0;
|
||
PadTypeAngle[NumberPadTypes] = 0;
|
||
PadTypeLayer[NumberPadTypes] = 0;
|
||
sprintf(PadTypeName[NumberPadTypes], "%s$%f", NewPadTypeName(Via.shape[LAYER_VIAS]), Db2Unit(PadTypeDrill[NumberPadTypes]));
|
||
ViaTypeName[ViaType] = PadTypeName[NumberPadTypes];
|
||
ViaType++;
|
||
NumberPadTypes++;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
string FindPadType(int ShapeType, int XSize, int YSize, int drill, int Layer, int Elongation, int Angle)
|
||
//------------------------------------------------------------------------------------------------------
|
||
{
|
||
int i=0;
|
||
int Found=-1;
|
||
|
||
for (i=0; (i<NumberPadTypes) && (Found==-1); i++)
|
||
{
|
||
if (PadTypeshape[i] == ShapeType &&
|
||
PadTypeX[i] == XSize &&
|
||
PadTypeY[i] == YSize &&
|
||
PadTypeAngle[i] == Angle &&
|
||
PadTypeDrill[i] == drill &&
|
||
PadTypeE[i] == Elongation &&
|
||
PadTypeLayer[i] == Layer)
|
||
{
|
||
Found = i;
|
||
}
|
||
}
|
||
|
||
return(PadTypeName[Found]);
|
||
}
|
||
|
||
string FindViaType(int ShapeType, int XSize, int YSize, int drill, int Layer, int Elongation, int Angle, int start, int end)
|
||
//--------------------------------------------------------------------------------------------------------------------------
|
||
{
|
||
int i=0;
|
||
int Found=-1;
|
||
|
||
for (i=0; (i<NumberPadTypes) && (Found==-1); i++)
|
||
{
|
||
if (PadTypeshape[i] == ShapeType &&
|
||
ViaTypeStart[i] == start &&
|
||
ViaTypeEnd[i] == end &&
|
||
PadTypeX[i] == XSize &&
|
||
PadTypeY[i] == YSize &&
|
||
PadTypeAngle[i] == Angle &&
|
||
PadTypeDrill[i] == drill &&
|
||
PadTypeE[i] == Elongation &&
|
||
PadTypeLayer[i] == Layer)
|
||
{
|
||
Found = i;
|
||
}
|
||
}
|
||
|
||
return(PadTypeName[Found]);
|
||
}
|
||
|
||
void FPPadTypes(UL_PACKAGE FP)
|
||
//----------------------------
|
||
{
|
||
FP.contacts(C)
|
||
{
|
||
if (C.pad)
|
||
{
|
||
PTHPadType(C.pad);
|
||
}
|
||
if (C.smd)
|
||
{
|
||
SMDPadType(C.smd);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
string LayerFromId_old(int Id)
|
||
//------------------------
|
||
{
|
||
string LayerName;
|
||
|
||
if ((Id < 1) || (Id > 16))
|
||
return "signal";
|
||
|
||
board(Board)
|
||
{
|
||
Board.layers(Layer)
|
||
{
|
||
if (Layer.number == Id)
|
||
{
|
||
LayerName = Layer.name;
|
||
return LayerName;
|
||
|
||
}
|
||
}
|
||
}
|
||
return "signal";
|
||
}
|
||
|
||
|
||
|
||
string LayerFromId(int Id)
|
||
//------------------------
|
||
{
|
||
string LayerName;
|
||
|
||
if ((Id < 1) || (Id > 16))
|
||
return "signal";
|
||
|
||
for (int i = 0; i < rgw; i++)
|
||
{
|
||
if (Layer_No[i] == Id)
|
||
{
|
||
sprintf(LayerName,"%d#%s", Layer_No[i], LayerFromId_old(Layer_No[i]));
|
||
if(string_quote)
|
||
sprintf(LayerName,"%c%s%c",'"', LayerName, '"');
|
||
return LayerName;
|
||
}
|
||
}
|
||
return "signal";
|
||
}
|
||
|
||
|
||
void write_Octagon(int o, int i, real a, real b)
|
||
//------------------
|
||
{
|
||
printf("\n (shape ");
|
||
printf("(polygon ");
|
||
printf(LayerFromId(o));
|
||
printf(" 0 ");
|
||
printf("%f %f ", a, b );// 1
|
||
printf("%f %f ", b, a );// 2
|
||
printf("%f %f ", -b, a );// 3
|
||
printf("%f %f ", -a, b );// 4
|
||
printf("%f %f ", -a, -b );// 5
|
||
printf("%f %f ", -b, -a );// 6
|
||
printf("%f %f ", b, -a );// 7
|
||
printf("%f %f ", a, -b );// 8
|
||
printf("))");
|
||
}
|
||
|
||
|
||
|
||
void Padstacks()
|
||
//--------------
|
||
{
|
||
int i, j, l;
|
||
real a, b;
|
||
string tmp;
|
||
|
||
printf(" (padstack ");
|
||
sprintf(tmp, "ViaDefault$%f", default_drill_size);
|
||
|
||
write_qStr(tmp); printf("\n");
|
||
printf(" (shape (circle signal %f", default_via_size);
|
||
printf(" 0 0))\n");
|
||
printf(" )\n");
|
||
|
||
for (i=0; i<NumberPadTypes; i++)
|
||
{
|
||
l=0;
|
||
printf(" (padstack ");
|
||
write_qStr(PadTypeName[i]); printf(" ");// "\n"
|
||
if (PadTypeshape[i]==PAD_SHAPE_ROUND)
|
||
{
|
||
if (PadTypeLayer[i]==0)
|
||
{
|
||
for( j=0; j <rgw; j++)
|
||
{
|
||
if(ViaTypeStart[i] <= Layer_No[j])
|
||
{
|
||
if(Layer_No[j] > ViaTypeEnd[i])
|
||
{
|
||
if(l==0)
|
||
{
|
||
printf("\n (shape ");
|
||
printf("(circle ");
|
||
printf(LayerFromId(ViaTypeStart[i]));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]);
|
||
printf(" 0 0))");
|
||
}
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
l=1;
|
||
printf("\n (shape ");
|
||
printf("(circle ");
|
||
printf(LayerFromId(Layer_No[j]));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]);
|
||
printf(" 0 0))");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf(" (shape ");
|
||
printf("(circle ");
|
||
printf(LayerFromId(PadTypeLayer[i]));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]);
|
||
printf(" 0 0))");
|
||
}
|
||
}
|
||
else
|
||
if (PadTypeshape[i]==PAD_SHAPE_OCTAGON)
|
||
{
|
||
a=Db2Unit(PadTypeX[i])/2;
|
||
b=(Db2Unit(PadTypeX[i])/2)*0.4142135;
|
||
|
||
if (PadTypeLayer[i]==0)
|
||
{
|
||
for( j=0; j <rgw; j++)
|
||
{
|
||
if(ViaTypeStart[i] <= Layer_No[j])
|
||
{
|
||
if(Layer_No[j] > ViaTypeEnd[i])
|
||
{
|
||
if(l==0)
|
||
{
|
||
if(Layer_No[j]==Layer_No[0])
|
||
write_Octagon(Layer_No[j], i, a, b);
|
||
if((j > 0) && (j < rgw-1))
|
||
{
|
||
printf("\n (shape ");
|
||
printf("(circle ");
|
||
printf(LayerFromId(Layer_No[j]));
|
||
printf(" ");
|
||
if(Db2Unit(PadTypeDrill[i])+(min_pad_inner*2) >= Db2Unit(PadTypeDrill[i])*(1+rv_pad_inner*2))
|
||
{
|
||
printf("%f",Db2Unit(PadTypeDrill[i])+(min_pad_inner*2));
|
||
}
|
||
else if(Db2Unit(PadTypeDrill[i])*(1+rv_pad_inner*2) <= Db2Unit(PadTypeDrill[i])+(max_pad_inner*2))
|
||
{
|
||
printf("%f",Db2Unit(PadTypeDrill[i])*(1+rv_pad_inner*2));
|
||
}
|
||
else
|
||
{
|
||
printf("%f",Db2Unit(PadTypeDrill[i])+(max_pad_inner*2));
|
||
}
|
||
printf(" 0 0))");
|
||
}
|
||
if(Layer_No[j]==Layer_No[rgw-1])
|
||
write_Octagon(Layer_No[j], i, a, b);
|
||
}
|
||
// break;
|
||
}
|
||
else
|
||
{
|
||
l=1;
|
||
if(Layer_No[j]==Layer_No[0])
|
||
write_Octagon(Layer_No[j], i, a, b);
|
||
if((j > 0) && (j < rgw-1))
|
||
{
|
||
printf("\n (shape ");
|
||
printf("(circle ");
|
||
printf(LayerFromId(Layer_No[j]));
|
||
printf(" ");
|
||
printf("%f",Db2Unit(PadTypeDrill[i])+(min_via_inner*2));
|
||
printf(" 0 0))");
|
||
}
|
||
if(Layer_No[j]==Layer_No[rgw-1])
|
||
write_Octagon(Layer_No[j], i, a, b);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
write_Octagon(Layer_No[0], i, a, b);
|
||
for( j=1; j < (rgw-1); j++)
|
||
{
|
||
printf("\n (shape ");
|
||
printf("(circle ");
|
||
printf(LayerFromId(Layer_No[j]));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]);
|
||
printf(" 0 0))");
|
||
}
|
||
write_Octagon(Layer_No[j], i, a, b);
|
||
}
|
||
}
|
||
else
|
||
if (PadTypeshape[i]==PAD_SHAPE_LONG || PadTypeshape[i]==PAD_SHAPE_OFFSET)
|
||
{
|
||
printf("\n (shape ");
|
||
printf("(path ");
|
||
if (PadTypeLayer[i]==0)
|
||
{
|
||
printf("signal");
|
||
}
|
||
else
|
||
{
|
||
printf(LayerFromId(PadTypeLayer[i]));
|
||
}
|
||
printf(" ");
|
||
|
||
l = PadTypeX[i];
|
||
if (l < PadTypeY[i])
|
||
l = PadTypeY[i];
|
||
|
||
real Side = (0.02 * PadTypeE[i] - 1) * l;
|
||
|
||
write_Db2Unit(l);
|
||
printf(" ");
|
||
real x1, x2, y1, y2;
|
||
if (PadTypeshape[i]==PAD_SHAPE_LONG)
|
||
{
|
||
real half_widht = Side / 2;
|
||
if (PadTypeAngle[i] == 90 || PadTypeAngle[i] == 270)
|
||
{
|
||
x1 = 0;
|
||
y1 = -half_widht;
|
||
x2 = 0;
|
||
y2 = half_widht;
|
||
}
|
||
else if (PadTypeAngle[i] == 0 || PadTypeAngle[i] == 180)
|
||
{
|
||
x1 = -half_widht;
|
||
y1 = 0;
|
||
x2 = half_widht;
|
||
y2 = 0;
|
||
}
|
||
else
|
||
{
|
||
x2 = rotate_x (half_widht, 0, PadTypeAngle[i]);
|
||
y2 = rotate_y (half_widht, 0, PadTypeAngle[i]);
|
||
x1 = -x2;
|
||
y1 = y2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (PadTypeAngle[i] == 0)
|
||
{
|
||
x1 = 0;
|
||
y1 = 0;
|
||
x2 = Side;
|
||
y2 = 0;
|
||
}
|
||
else if (PadTypeAngle[i] == 180)
|
||
{
|
||
x1 = -Side;
|
||
y1 = 0;
|
||
x2 = 0;
|
||
y2 = 0;
|
||
}
|
||
if (PadTypeAngle[i] == 90)
|
||
{
|
||
x1 = 0;
|
||
y1 = 0;
|
||
x2 = 0;
|
||
y2 = Side;
|
||
}
|
||
else if (PadTypeAngle[i] == 270)
|
||
{
|
||
x1 = 0;
|
||
y1 = -Side;
|
||
x2 = 0;
|
||
y2 = 0;
|
||
}
|
||
else
|
||
{
|
||
x1 = 0;
|
||
y1 = 0;
|
||
x2 = rotate_x (Side, 0, PadTypeAngle[i]);
|
||
y2 = rotate_y (Side, 0, PadTypeAngle[i]);
|
||
}
|
||
}
|
||
write_Db2Unit(x1);
|
||
printf(" ");
|
||
write_Db2Unit(y1);
|
||
printf(" ");
|
||
write_Db2Unit(x2);
|
||
printf(" ");
|
||
write_Db2Unit(y2);
|
||
printf("))");
|
||
|
||
|
||
|
||
}
|
||
else
|
||
if (PadTypeshape[i]==PAD_SHAPE_SQUARE)
|
||
{
|
||
if (PadTypeLayer[i]==0)
|
||
{
|
||
for( j=0; j <rgw; j++)
|
||
{
|
||
if(ViaTypeStart[i] <= Layer_No[j])
|
||
{
|
||
if(Layer_No[j] > ViaTypeEnd[i])
|
||
{
|
||
if(l==0)
|
||
{
|
||
printf("\n (shape ");
|
||
printf("(rect ");
|
||
printf(LayerFromId(ViaTypeStart[i]));
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeX[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeX[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]/2);
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]/2);
|
||
printf("))");
|
||
}
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
l=1;
|
||
printf("\n (shape ");
|
||
printf("(rect ");
|
||
printf(LayerFromId(Layer_No[j]));
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeX[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeX[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]/2);
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]/2);
|
||
printf("))");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("\n (shape ");
|
||
printf("(rect ");
|
||
printf(LayerFromId(PadTypeLayer[i]));
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeX[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeX[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]/2);
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]/2);
|
||
printf("))");
|
||
}
|
||
}
|
||
else
|
||
if (PadTypeshape[i]==PadShapeRectangle)
|
||
{
|
||
printf("\n (shape ");
|
||
printf("(rect ");
|
||
if (PadTypeLayer[i]==0)
|
||
{
|
||
printf("signal");
|
||
}
|
||
else
|
||
{
|
||
printf(LayerFromId(PadTypeLayer[i]));
|
||
}
|
||
if (PadTypeAngle[i] == 90 || PadTypeAngle[i] == 270)
|
||
{
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeY[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeX[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeY[i]/2);
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]/2);
|
||
printf("))");
|
||
}
|
||
else
|
||
{
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeX[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeY[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]/2);
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeY[i]/2);
|
||
printf("))");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("\n (shape ");
|
||
printf("(rect ");
|
||
if (PadTypeLayer[i]==0)
|
||
{
|
||
printf("signal");
|
||
}
|
||
else
|
||
{
|
||
printf(LayerFromId(PadTypeLayer[i]));
|
||
}
|
||
if (PadTypeAngle[i] == 90 || PadTypeAngle[i] == 270)
|
||
{
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeY[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeX[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeY[i]/2);
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]/2);
|
||
printf("))");
|
||
}
|
||
else
|
||
{
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeX[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(-(PadTypeY[i]/2));
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeX[i]/2);
|
||
printf(" ");
|
||
write_Db2Unit(PadTypeY[i]/2);
|
||
printf("))");
|
||
}
|
||
}
|
||
|
||
printf("\n");
|
||
printf(" (attach off)\n");
|
||
printf(" )\n");
|
||
}
|
||
}
|
||
|
||
|
||
char IsKeepoutLayer(int LayerNumber)
|
||
//----------------------------------
|
||
{
|
||
if (LayerNumber >= 39 && LayerNumber <= 43)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
string KeepoutType(int LayerNumber)
|
||
//---------------------------------
|
||
{
|
||
if (LayerNumber == 43)
|
||
{
|
||
return "via_keepout";
|
||
}
|
||
if (LayerNumber == 41 || LayerNumber == 42)
|
||
{
|
||
return "wire_keepout";
|
||
}
|
||
if (LayerNumber == 39 || LayerNumber == 40)
|
||
{
|
||
return "place_keepout";
|
||
}
|
||
|
||
return "keepout";
|
||
}
|
||
|
||
|
||
// Calculates the square of the distance between the points (x1, y1) and (x2, y2).
|
||
real dist_square ( int x1, int y1, int x2, int y2)
|
||
//---------------------------------
|
||
{
|
||
real dx = x2 - x1;
|
||
real dy = y2 - y1;
|
||
return (dx * dx + dy * dy);
|
||
}
|
||
|
||
// Calculates the distance between the points (x1, y1) and (x2, y2).
|
||
real distance ( int x1, int y1, int x2, int y2)
|
||
//---------------------------------
|
||
{
|
||
real d2 = dist_square (x1, y1, x2, y2);
|
||
return sqrt (d2);
|
||
}
|
||
|
||
|
||
int boundary_lines_a_x[], boundary_lines_a_y[]; // The coordinates of the start points of the lines of the boundary.
|
||
int boundary_lines_b_x[], boundary_lines_b_y[]; // The coordinates of the end points of the lines of the boundary.
|
||
int line_handeled[]; // Describes, if a line is already handeled while creating
|
||
// the polygons of the boundary.
|
||
|
||
int approximate_boundary_arc(UL_ARC arc, int line_no)
|
||
//---------------------------------
|
||
{
|
||
real max_piece_length = 1000;
|
||
|
||
real arc_length = distance(arc.x1, arc.y1, arc.x2, arc.y2);
|
||
int approx_count = arc_length / max_piece_length;
|
||
approx_count = max (approx_count, 1);
|
||
real delta_angle = arc.angle2 - arc.angle1;
|
||
if (delta_angle < 0)
|
||
{
|
||
delta_angle += 360;
|
||
}
|
||
real angle_inc = delta_angle / approx_count;
|
||
int prev_x = arc.x1;
|
||
int prev_y = arc.y1;
|
||
for (int i = 1; i <= approx_count; ++i)
|
||
{
|
||
int next_x;
|
||
int next_y;
|
||
if (i == approx_count)
|
||
{
|
||
next_x = arc.x2;
|
||
next_y = arc.y2;
|
||
}
|
||
else
|
||
{
|
||
real curr_angle = arc.angle1 + i * angle_inc;
|
||
if (curr_angle > 360)
|
||
{
|
||
curr_angle -= 360;
|
||
}
|
||
real radian_angle = curr_angle * PI / 180.0;
|
||
next_x = arc.xc + arc.radius * cos(radian_angle);
|
||
next_y = arc.yc + arc.radius * sin(radian_angle);
|
||
}
|
||
boundary_lines_a_x[line_no]= prev_x;
|
||
boundary_lines_a_y[line_no]= prev_y;
|
||
boundary_lines_b_x[line_no]= next_x;
|
||
boundary_lines_b_y[line_no]= next_y;
|
||
++line_no;
|
||
prev_x = next_x;
|
||
prev_y = next_y;
|
||
}
|
||
return line_no;
|
||
}
|
||
|
||
|
||
int process_next_wire (UL_WIRE p_wire, int p_corner_count)
|
||
{
|
||
int new_corner_count;
|
||
if (p_wire.arc)
|
||
{
|
||
new_corner_count = approximate_boundary_arc(p_wire.arc, p_corner_count);
|
||
}
|
||
else
|
||
{
|
||
boundary_lines_a_x[p_corner_count] = p_wire.x1;
|
||
boundary_lines_a_y[p_corner_count] = p_wire.y1;
|
||
boundary_lines_b_x[p_corner_count] = p_wire.x2;
|
||
boundary_lines_b_y[p_corner_count] = p_wire.y2;
|
||
new_corner_count = p_corner_count + 1;
|
||
}
|
||
return new_corner_count;
|
||
}
|
||
|
||
// Collects the lines of the board outline.
|
||
int collectOutlineLines(UL_BOARD Board)
|
||
//-------------------------
|
||
{
|
||
int i=0;
|
||
Board.wires(W)
|
||
{
|
||
if (W.layer == LAYER_DIMENSION)
|
||
{
|
||
i = process_next_wire(W, i);
|
||
}
|
||
}
|
||
return i;
|
||
}
|
||
|
||
int polygon_corner_count; // The numer of corners of the polygon.
|
||
int polygon_part_corners_x[], polygon_part_corners_y[]; // A connected part of a keepout described as a polygon.
|
||
int polygon_part_corner_count; // The number of corners of the connected part.
|
||
|
||
// Combines all connected unhandeled lines of a list of lines to a polygon.
|
||
// Returns false, if there are no more unhandled lines.
|
||
|
||
int combineLines(real p_end_point_tolerance)
|
||
{
|
||
int index_of_first_unhandeled_line = -1;
|
||
for (int j = 0; j < polygon_corner_count; ++j)
|
||
{
|
||
if (!line_handeled[j])
|
||
{
|
||
index_of_first_unhandeled_line = j;
|
||
}
|
||
}
|
||
if (index_of_first_unhandeled_line < 0)
|
||
{
|
||
return false;
|
||
}
|
||
int searchx = boundary_lines_b_x[index_of_first_unhandeled_line];
|
||
int searchy = boundary_lines_b_y[index_of_first_unhandeled_line];
|
||
polygon_part_corners_x[0] = boundary_lines_a_x[index_of_first_unhandeled_line];
|
||
polygon_part_corners_y[0] = boundary_lines_a_y[index_of_first_unhandeled_line];
|
||
line_handeled[index_of_first_unhandeled_line] = true;
|
||
int resultcornercount = 1;
|
||
|
||
for (j = 0; j < polygon_corner_count; ++j)
|
||
{
|
||
real min_distance = p_end_point_tolerance;
|
||
int next_line_found = false;
|
||
int nearest_line_index;
|
||
char nearest_point_is_start;
|
||
// Search the nearest endpoint of the other lines to (searchx, searchy)
|
||
// and add it to the result polygon.
|
||
// In general this point should be equal to (searchx, searchy).
|
||
for (int i = 0; i < polygon_corner_count; ++i)
|
||
{
|
||
if (line_handeled[i])
|
||
{
|
||
continue;
|
||
}
|
||
real curr_distance = dist_square(searchx, searchy, boundary_lines_a_x[i], boundary_lines_a_y [i]);
|
||
if ( curr_distance < min_distance)
|
||
{
|
||
min_distance = curr_distance;
|
||
nearest_line_index = i;
|
||
nearest_point_is_start = true;
|
||
next_line_found = true;
|
||
}
|
||
curr_distance = dist_square(searchx, searchy, boundary_lines_b_x[i], boundary_lines_b_y[i]);
|
||
if ( curr_distance < min_distance)
|
||
{
|
||
min_distance = curr_distance;
|
||
nearest_line_index = i;
|
||
nearest_point_is_start = false;
|
||
next_line_found = true;
|
||
}
|
||
}
|
||
if (!next_line_found)
|
||
{
|
||
break;
|
||
}
|
||
polygon_part_corners_x[resultcornercount] = searchx;
|
||
polygon_part_corners_y[resultcornercount] = searchy;
|
||
++resultcornercount;
|
||
// Take the other endpoint of the line of the found nearestpoint
|
||
// as new seach point.
|
||
if (nearest_point_is_start)
|
||
{
|
||
searchx = boundary_lines_b_x[nearest_line_index];
|
||
searchy = boundary_lines_b_y[nearest_line_index];
|
||
}
|
||
else
|
||
{
|
||
searchx = boundary_lines_a_x[nearest_line_index];
|
||
searchy = boundary_lines_a_y[nearest_line_index];
|
||
}
|
||
line_handeled[nearest_line_index] = true;
|
||
}
|
||
if (resultcornercount == 1)
|
||
{
|
||
// no matching lines found, descripe the result shape as line with a width
|
||
polygon_part_corners_x[1] = boundary_lines_b_x[index_of_first_unhandeled_line];
|
||
polygon_part_corners_y[1] = boundary_lines_b_y[index_of_first_unhandeled_line];
|
||
resultcornercount = 2;
|
||
}
|
||
polygon_part_corner_count = resultcornercount;
|
||
return true;
|
||
}
|
||
|
||
void MakeBoundary ()
|
||
//-------------------------
|
||
{
|
||
board(Board)
|
||
{
|
||
polygon_corner_count = collectOutlineLines(Board);
|
||
}
|
||
for (int i = 0; i < polygon_corner_count; ++i)
|
||
{
|
||
printf(" (boundary ");
|
||
printf("(path ");
|
||
printf("signal 0 ");
|
||
write_Db2Unit(boundary_lines_a_x[i]);
|
||
printf(" ");
|
||
write_Db2Unit(boundary_lines_a_y[i]);
|
||
printf(" ");
|
||
write_Db2Unit(boundary_lines_b_x[i]);
|
||
printf(" ");
|
||
write_Db2Unit(boundary_lines_b_y[i]);
|
||
printf("))\n");
|
||
}
|
||
}
|
||
|
||
void board_dimension()
|
||
//-------------------------
|
||
{
|
||
int i=0;
|
||
int ox=0;
|
||
int oy=0;
|
||
int mx=0;
|
||
int my=0;
|
||
int dimx1[], dimy1[]; // coordinate od Dimension
|
||
int dimx2[], dimy2[]; // coordinate od Dimension
|
||
int index[];
|
||
board(B)
|
||
{
|
||
B.wires(W)
|
||
{
|
||
if (W.layer==LAYER_DIMENSION)
|
||
{
|
||
dimx1[i]=W.x1;
|
||
dimy1[i]=W.y1;
|
||
dimx2[i]=W.x2;
|
||
dimy2[i]=W.y2;
|
||
i++;
|
||
}
|
||
}
|
||
}
|
||
sort(i, index, dimx1, dimx2, dimy1, dimy2);
|
||
ox=dimx1[0];
|
||
oy=dimy1[0];
|
||
for (int n = 0; n < i; n++)
|
||
{
|
||
if (dimx1[n]<ox) {ox=dimx1[n];}
|
||
if (dimy1[n]<oy) {oy=dimy1[n];}
|
||
if (dimx2[n]>mx) {mx=dimx2[n];}
|
||
if (dimy2[n]>my) {my=dimy2[n];}
|
||
}
|
||
printf(" (boundary \n");
|
||
printf(" (rect pcb ");
|
||
printf(" "); write_Db2Unit(ox);
|
||
printf(" "); write_Db2Unit(oy);
|
||
printf(" "); write_Db2Unit(mx);
|
||
printf(" "); write_Db2Unit(my);
|
||
printf(")\n )\n");
|
||
}
|
||
|
||
void LineDesc(UL_WIRE Line)
|
||
//-------------------------
|
||
{
|
||
write_Db2Unit(Line.width);
|
||
printf(" ");
|
||
write_Db2Unit(Line.x1);
|
||
printf(" ");
|
||
write_Db2Unit(Line.y1);
|
||
printf(" ");
|
||
write_Db2Unit(Line.x2);
|
||
printf(" ");
|
||
write_Db2Unit(Line.y2);
|
||
}
|
||
|
||
void ArcDesc(UL_ARC Arc)
|
||
//-------------------------
|
||
{
|
||
write_Db2Unit(Arc.width);
|
||
printf(" ");
|
||
write_Db2Unit(Arc.x1);
|
||
printf(" ");
|
||
write_Db2Unit(Arc.y1);
|
||
printf(" ");
|
||
write_Db2Unit(Arc.x2);
|
||
printf(" ");
|
||
write_Db2Unit(Arc.y2);
|
||
}
|
||
|
||
void CircleDesc(UL_CIRCLE Circle)
|
||
//-------------------------------
|
||
{
|
||
write_Db2Unit(Circle.radius * 2);
|
||
printf(" ");
|
||
write_Db2Unit(Circle.x);
|
||
printf(" ");
|
||
write_Db2Unit(Circle.y);
|
||
}
|
||
|
||
|
||
void RectangleDesc(UL_RECTANGLE Rectangle)
|
||
//----------------------------------------
|
||
{
|
||
write_Db2Unit(Rectangle.x1);
|
||
printf(" ");
|
||
write_Db2Unit(Rectangle.y1);
|
||
printf(" ");
|
||
write_Db2Unit(Rectangle.x2);
|
||
printf(" ");
|
||
write_Db2Unit(Rectangle.y2);
|
||
}
|
||
|
||
|
||
void PolygonDesc(UL_POLYGON Polygon)
|
||
//----------------------------------
|
||
{
|
||
printf(" ");
|
||
write_Db2Unit(Polygon.width);
|
||
Polygon.wires(Wire)
|
||
{
|
||
printf(" ");
|
||
write_Db2Unit(Wire.x1);
|
||
printf(" ");
|
||
write_Db2Unit(Wire.y1);
|
||
}
|
||
}
|
||
|
||
void PTHPad(UL_PAD Pad)
|
||
//---------------------
|
||
{
|
||
string Style;
|
||
|
||
Style = FindPadType(Pad.shape[LAYER_TOP], Pad.diameter[LAYER_TOP], 0, Pad.drill, 0, Pad.elongation, Pad.angle);
|
||
write_qStr(Style); printf(" ");
|
||
}
|
||
|
||
|
||
void SMDPad(UL_SMD Pad)
|
||
//---------------------
|
||
{
|
||
string Style;
|
||
|
||
if (Pad.roundness == 100)
|
||
Style = FindPadType(PAD_SHAPE_ROUND, Pad.dx, Pad.dy, 0, Pad.layer, 0, Pad.angle);
|
||
else
|
||
Style = FindPadType(PadShapeRectangle, Pad.dx, Pad.dy, 0, Pad.layer, 0, Pad.angle);
|
||
write_qStr(Style); printf(" ");
|
||
}
|
||
|
||
|
||
void make_component_keepout(int p_layer, string p_layer_name)
|
||
{
|
||
if (polygon_corner_count <= 0 || !IsKeepoutLayer(p_layer))
|
||
{
|
||
return;
|
||
}
|
||
for (int i = 0; i < polygon_corner_count; ++i)
|
||
{
|
||
line_handeled[i] = false;
|
||
}
|
||
for (;;)
|
||
{
|
||
int more_parts = combineLines(polyline_endpoint_tolerance);
|
||
if (!more_parts)
|
||
{
|
||
break;
|
||
}
|
||
printf(" (%s", KeepoutType(p_layer));
|
||
p_layer_name = "signal";
|
||
if (p_layer == 39 || p_layer == 41)
|
||
p_layer_name = TopLayer;
|
||
if (p_layer == 40 || p_layer == 42)
|
||
p_layer_name = BotLayer;
|
||
printf("(path ");
|
||
write_Str(p_layer_name);
|
||
printf(" 0 ");
|
||
|
||
for (i = 0; i< polygon_part_corner_count; ++i)
|
||
{
|
||
write_Db2Unit(polygon_part_corners_x[i]);
|
||
printf(" ");
|
||
write_Db2Unit(polygon_part_corners_y[i]);
|
||
printf(" ");
|
||
}
|
||
printf("))\n");
|
||
}
|
||
}
|
||
|
||
void FPOutline(UL_PACKAGE FP, UL_LAYER Layer)
|
||
//-------------------------------------------
|
||
{
|
||
string LayerName;
|
||
|
||
if (Layer.number == LAYER_TPLACE || IsKeepoutLayer(Layer.number))
|
||
{
|
||
LayerName = LayerFromId(Layer.number);
|
||
board(Board)
|
||
{
|
||
Board.layers(Layer)
|
||
{
|
||
if (Layer.number == 1)
|
||
LayerName = LayerFromId(Layer.number);
|
||
}
|
||
}
|
||
|
||
polygon_corner_count = 0;
|
||
int width = 0;
|
||
|
||
FP.wires(W)
|
||
{
|
||
if (W.layer == Layer.number)
|
||
{
|
||
polygon_corner_count = process_next_wire (W, polygon_corner_count);
|
||
width = W.width;
|
||
}
|
||
}
|
||
|
||
make_component_keepout(Layer.number, LayerName);
|
||
|
||
FP.circles(Circle)
|
||
{
|
||
if (Circle.layer==Layer.number)
|
||
{
|
||
if (IsKeepoutLayer(Layer.number))
|
||
{
|
||
printf(" (%s", KeepoutType(Layer.number));
|
||
LayerName ="signal";
|
||
if (Layer.number == 39 || Layer.number == 41)
|
||
LayerName = TopLayer;
|
||
if (Layer.number == 40 || Layer.number == 42)
|
||
LayerName = BotLayer;
|
||
}
|
||
else
|
||
printf(" (outline");
|
||
printf("(circ ");
|
||
write_Str(LayerName); printf(" ");
|
||
CircleDesc(Circle);
|
||
printf("))\n");
|
||
}
|
||
}
|
||
FP.rectangles(Rectangle)
|
||
{
|
||
if (Rectangle.layer==Layer.number)
|
||
{
|
||
if (IsKeepoutLayer(Layer.number))
|
||
{
|
||
printf(" (%s", KeepoutType(Layer.number));
|
||
LayerName ="signal";
|
||
if (Layer.number == 39 || Layer.number == 41)
|
||
LayerName = TopLayer;
|
||
if (Layer.number == 40 || Layer.number == 42)
|
||
LayerName = BotLayer;
|
||
}
|
||
else
|
||
printf(" (outline");
|
||
printf("(rect ");
|
||
write_Str(LayerName); printf(" ");
|
||
RectangleDesc(Rectangle);
|
||
printf("))\n");
|
||
}
|
||
}
|
||
FP.polygons(Polygon)
|
||
{
|
||
if (Polygon.layer == Layer.number)
|
||
{
|
||
Polygon.wires(W)
|
||
{
|
||
polygon_corner_count = process_next_wire (W, polygon_corner_count);
|
||
width = W.width;
|
||
}
|
||
for (int i = 0; i < polygon_corner_count; ++i)
|
||
{
|
||
printf(" (outline ");
|
||
printf("(path ");
|
||
printf("signal 0 ");
|
||
write_Db2Unit(boundary_lines_a_x[i]);
|
||
printf(" ");
|
||
write_Db2Unit(boundary_lines_a_y[i]);
|
||
printf(" ");
|
||
write_Db2Unit(boundary_lines_b_x[i]);
|
||
printf(" ");
|
||
write_Db2Unit(boundary_lines_b_y[i]);
|
||
printf("))\n");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void Image(UL_PACKAGE FP)
|
||
//-----------------------
|
||
{
|
||
int hi = 1;
|
||
string HName;
|
||
|
||
printf(" (image ");
|
||
write_qStr(FP.name + "$" + FP.library); printf("\n");
|
||
|
||
|
||
board(Board)
|
||
{
|
||
Board.layers(Layer)
|
||
{
|
||
FPOutline(FP,Layer);
|
||
}
|
||
}
|
||
|
||
FP.holes(Hole)
|
||
{
|
||
printf(" (keepout (circ signal ");
|
||
|
||
write_Db2Unit(Hole.diameter[LAYER_TSTOP]);
|
||
printf(" ");
|
||
write_Db2Unit(Hole.x);
|
||
printf(" ");
|
||
write_Db2Unit(Hole.y);
|
||
printf("))\n");
|
||
}
|
||
|
||
FP.contacts(Pad)
|
||
{
|
||
printf(" (pin ");
|
||
|
||
if (Pad.pad)
|
||
{
|
||
PTHPad(Pad.pad);
|
||
}
|
||
|
||
if (Pad.smd)
|
||
{
|
||
SMDPad(Pad.smd);
|
||
}
|
||
|
||
write_qStr(Pad.name);
|
||
printf(" ");
|
||
|
||
write_Db2Unit(Pad.x);
|
||
printf(" ");
|
||
write_Db2Unit(Pad.y);
|
||
printf(")\n");
|
||
}
|
||
|
||
printf(" )\n");
|
||
}
|
||
|
||
|
||
void GetUsedFPs()
|
||
//---------------
|
||
{
|
||
int UsedFPCount=0;
|
||
numeric string UsedFPs[];
|
||
|
||
board(Board)
|
||
{
|
||
Board.elements(Component)
|
||
{
|
||
string FPName=Component.package.name;
|
||
char Found=false;
|
||
int i;
|
||
for (i=0; (i<UsedFPCount) &&!Found; i++)
|
||
{
|
||
if (UsedFPs[i] == FPName)
|
||
{
|
||
Found = true;
|
||
}
|
||
}
|
||
if (!Found)
|
||
{
|
||
UsedFPs[UsedFPCount++]=FPName;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void PadTypes(void)
|
||
//------------------
|
||
{
|
||
board(Board)
|
||
{
|
||
Board.libraries(Library)
|
||
{
|
||
Library.packages(FP)
|
||
{
|
||
FPPadTypes(FP);
|
||
}
|
||
}
|
||
Board.signals(Net)
|
||
{
|
||
Net.vias(Via)
|
||
{
|
||
ViaPadType(Via);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void Images()
|
||
//----------
|
||
{
|
||
GetUsedFPs();
|
||
|
||
printf(" (library\n");
|
||
|
||
board(Board)
|
||
{
|
||
Board.libraries(Library)
|
||
{
|
||
Library.packages(FP)
|
||
{
|
||
Image(FP);
|
||
}
|
||
}
|
||
}
|
||
|
||
Padstacks();
|
||
|
||
printf(" )\n");
|
||
}
|
||
|
||
void Header()
|
||
//-----------
|
||
{
|
||
board(Board)
|
||
{
|
||
Units = Board.grid.unit;
|
||
|
||
printf("(PCB ");
|
||
printf("\"");
|
||
printf(Board.name);
|
||
printf("\"");
|
||
printf("\n");
|
||
|
||
printf(" (parser\n");
|
||
printf(" (string_quote \")\n");
|
||
printf(" (space_in_quoted_tokens on)\n");
|
||
printf(" (host_cad CadSoft)\n");
|
||
printf(" (host_version '%s')\n", EAGLE_SIGNATURE);
|
||
printf(" )\n");
|
||
|
||
printf(" (resolution ");
|
||
|
||
if (Units == GRID_UNIT_MM)
|
||
{
|
||
printf("mm 10000)");
|
||
printf("\n (unit mm)");
|
||
}
|
||
else
|
||
if (Units == GRID_UNIT_MIL)
|
||
{
|
||
printf("mil 254)");
|
||
printf("\n (unit mil)");
|
||
}
|
||
else
|
||
if (Units == GRID_UNIT_INCH)
|
||
{
|
||
printf("inch 254000)");
|
||
printf("\n (unit inch)");
|
||
}
|
||
else
|
||
if (Units == GRID_UNIT_MIC)
|
||
{
|
||
printf("um 10)");
|
||
printf("\n (unit mm)");
|
||
}
|
||
|
||
printf("\n");
|
||
}
|
||
}
|
||
|
||
void FromTo(UL_CONTACTREF Node)
|
||
//-----------------------------
|
||
{
|
||
/*
|
||
printf(" \"");
|
||
printf(Node.element.name);
|
||
printf("\"-");
|
||
printf("\"");
|
||
printf(Node.contact.name);
|
||
printf("\"");*/
|
||
printf(" ");
|
||
write_qStr(Node.element.name);
|
||
printf("-");
|
||
write_qStr(Node.contact.name);
|
||
}
|
||
|
||
int net_count = 0;
|
||
string net_name_arr[];
|
||
int net_class_no_arr[];
|
||
|
||
void Network()
|
||
//------------
|
||
{
|
||
printf(" (network\n");
|
||
board(Board)
|
||
{
|
||
// write the nets
|
||
Board.signals(Net)
|
||
{
|
||
printf(" (net ");
|
||
write_qStr(Net.name);
|
||
printf("\n");
|
||
printf(" (pins ");
|
||
Net.contactrefs(Node)
|
||
{
|
||
FromTo(Node);
|
||
}
|
||
printf(")\n");
|
||
|
||
printf(" )\n");
|
||
|
||
net_name_arr[net_count] = Net.name;
|
||
net_class_no_arr[net_count] = Net.class.number;
|
||
++net_count;
|
||
}
|
||
|
||
// write the classes
|
||
Board.classes(curr_class)
|
||
{
|
||
if ((curr_class.width == 0) && (curr_class.clearance == 0))
|
||
{
|
||
continue;
|
||
}
|
||
printf(" (class ");
|
||
write_qStr(curr_class.name);
|
||
printf("\n ");
|
||
for(int i = 0; i < net_count; ++i)
|
||
{
|
||
if (net_class_no_arr[i] == curr_class.number)
|
||
{
|
||
printf(" ");
|
||
write_qStr(net_name_arr[i]);
|
||
}
|
||
}
|
||
printf("\n (rule");
|
||
if (curr_class.width != 0)
|
||
{
|
||
printf("\n (width ");
|
||
real wire_width = curr_class.width;
|
||
if (wire_width <= 0)
|
||
{
|
||
wire_width = default_wire_width;
|
||
}
|
||
write_Db2Unit(wire_width);
|
||
printf(")");
|
||
}
|
||
if (curr_class.clearance != 0)
|
||
{
|
||
printf("\n (clearance ");
|
||
real clearance = curr_class.clearance;
|
||
if (clearance <= 0)
|
||
{
|
||
clearance = default_clearance;
|
||
}
|
||
write_Db2Unit(clearance);
|
||
printf(")");
|
||
}
|
||
printf("\n )\n");
|
||
printf(" )\n");
|
||
}
|
||
}
|
||
printf(" )\n");
|
||
}
|
||
|
||
int arc_approx_corners_x[], arc_approx_corners_y[];
|
||
|
||
int approximate_wire_arc(UL_ARC arc)
|
||
//---------------------------------
|
||
{
|
||
real max_piece_length = 10000;
|
||
|
||
real arc_length = distance(arc.x1, arc.y1, arc.x2, arc.y2);
|
||
int approx_count = arc_length / max_piece_length;
|
||
approx_count = max (approx_count, 1);
|
||
real delta_angle = arc.angle2 - arc.angle1;
|
||
if (delta_angle < 0)
|
||
{
|
||
delta_angle += 360;
|
||
}
|
||
real angle_inc = delta_angle / approx_count;
|
||
arc_approx_corners_x[0] = arc.x1;
|
||
arc_approx_corners_y[0] = arc.y1;
|
||
int corner_no = 1;
|
||
for (int i = 1; i <= approx_count; ++i)
|
||
{
|
||
int next_x;
|
||
int next_y;
|
||
if (i == approx_count)
|
||
{
|
||
next_x = arc.x2;
|
||
next_y = arc.y2;
|
||
}
|
||
else
|
||
{
|
||
real curr_angle = arc.angle1 + i * angle_inc;
|
||
if (curr_angle > 360)
|
||
{
|
||
curr_angle -= 360;
|
||
}
|
||
real radian_angle = curr_angle * PI / 180.0;
|
||
next_x = arc.xc + arc.radius * cos(radian_angle);
|
||
next_y = arc.yc + arc.radius * sin(radian_angle);
|
||
}
|
||
arc_approx_corners_x[corner_no]= next_x;
|
||
arc_approx_corners_y[corner_no]= next_y;
|
||
++corner_no;
|
||
}
|
||
return corner_no;
|
||
}
|
||
|
||
|
||
void Wiring()
|
||
//-----------
|
||
{
|
||
int hi = 1;
|
||
string Name;
|
||
|
||
printf(" (wiring\n");
|
||
board(Board)
|
||
{
|
||
Board.signals(Net)
|
||
{
|
||
Net.wires(Wire)
|
||
{
|
||
if ((Wire.layer >= 1) && (Wire.layer <= 16))
|
||
{
|
||
if (Wire.arc)
|
||
{
|
||
int corner_count = approximate_wire_arc(Wire.arc);
|
||
printf(" (wire\n");
|
||
printf(" (path ");
|
||
printf("%s ", LayerFromId(Wire.layer));
|
||
write_Db2Unit(Wire.arc.width);
|
||
for (int i = 0; i < corner_count; ++i)
|
||
{
|
||
printf(" ");
|
||
write_Db2Unit(arc_approx_corners_x[i]);
|
||
printf(" ");
|
||
write_Db2Unit(arc_approx_corners_y[i]);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf(" (wire\n");
|
||
printf(" (path ");
|
||
printf("%s ", LayerFromId(Wire.layer));
|
||
LineDesc(Wire);
|
||
}
|
||
printf(") \n");
|
||
printf(" (net ");
|
||
write_qStr(Net.name);
|
||
if (preprotect)
|
||
printf(") (type protect)\n");
|
||
else
|
||
printf(")\n");
|
||
printf(" )\n");
|
||
}
|
||
}
|
||
|
||
Net.polygons(Poly)
|
||
{
|
||
if ((Poly.layer >= 1) && (Poly.layer <= 16))
|
||
{
|
||
printf(" (wire\n");
|
||
printf(" (poly ");
|
||
printf("%s ", LayerFromId(Poly.layer));
|
||
PolygonDesc(Poly);
|
||
|
||
printf(") \n");
|
||
printf(" (net ");
|
||
write_qStr(Net.name);
|
||
if (preprotect)
|
||
printf(") (type protect)\n");
|
||
else
|
||
printf(")\n");
|
||
printf(" )\n");
|
||
}
|
||
}
|
||
|
||
Net.vias(Via)
|
||
{
|
||
printf(" (via\n ");
|
||
|
||
write_qStr(FindViaType(Via.shape[LAYER_TOP], Via.diameter[LAYER_TOP], 0, Via.drill, 0, 0, 0, Via.start, Via.end));
|
||
printf(" ");
|
||
|
||
write_Db2Unit(Via.x);
|
||
printf(" ");
|
||
write_Db2Unit(Via.y);
|
||
printf("\n (net ");
|
||
write_qStr(Net.name);
|
||
if (preprotect)
|
||
printf(") (type protect)\n");
|
||
else
|
||
printf(")\n");
|
||
printf(" )\n");
|
||
}
|
||
}
|
||
}
|
||
printf(" )\n");
|
||
}
|
||
|
||
|
||
|
||
void Layers(UL_BOARD p_board)
|
||
//---------------------
|
||
{
|
||
int IsSignal;
|
||
string tmp;
|
||
int i;
|
||
|
||
for (i = 0; i < rgw; i++)
|
||
{
|
||
|
||
|
||
tmp = LayerFromId(Layer_No[i]);
|
||
printf(" (layer ");
|
||
printf("%s ", tmp);
|
||
|
||
if (!strchr(LayerFromId(Layer_No[i]),'$'))
|
||
{
|
||
printf(" (type power)");
|
||
printf(" (use_net ");
|
||
printf(strsub(LayerFromId(Layer_No[i]) , 1));
|
||
printf(")");
|
||
}
|
||
else
|
||
{
|
||
printf(" (type signal))\n");
|
||
}
|
||
}
|
||
}
|
||
|
||
void Vias(UL_SIGNAL Net)
|
||
//----------------------
|
||
{
|
||
|
||
Net.vias(Via)
|
||
{
|
||
printf("(via ");
|
||
|
||
write_qStr(FindPadType(Via.shape[LAYER_TOP], Via.diameter[LAYER_TOP], 0, Via.drill, 0, 0, 0));
|
||
printf(" ");
|
||
|
||
write_Db2Unit(Via.x);
|
||
printf(" ");
|
||
write_Db2Unit(Via.y);
|
||
|
||
printf("\n");
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void CmpInstance(UL_ELEMENT Component)
|
||
//------------------------------------
|
||
{
|
||
printf(" (component ");
|
||
|
||
write_qStr(Component.package.name + "$" + Component.package.library); printf(" \n");
|
||
|
||
printf(" (place ");
|
||
write_qStr(Component.name);
|
||
printf(" ");
|
||
|
||
write_Db2Unit(Component.x);
|
||
printf(" ");
|
||
write_Db2Unit(Component.y);
|
||
printf(" ");
|
||
|
||
if (Component.mirror)
|
||
{
|
||
printf("Back");
|
||
}
|
||
else
|
||
{
|
||
printf("Front");
|
||
}
|
||
|
||
printf(" ");
|
||
write_Real(Component.angle);
|
||
printf(")\n )\n");
|
||
}
|
||
|
||
void Placement()
|
||
//--------------
|
||
{
|
||
board(Board)
|
||
{
|
||
printf(" (placement\n");
|
||
|
||
printf(" (place_control (flip_style rotate_first))\n");
|
||
|
||
Board.elements(Component)
|
||
{
|
||
CmpInstance(Component);
|
||
}
|
||
printf(" )\n");
|
||
}
|
||
}
|
||
|
||
|
||
// Creates an keepout, which is made by lines.
|
||
// If p_polygon != null, the wires of p_polygon are processed, else all wires on p_board on layer p_layer
|
||
|
||
void make_keepout_shape(int p_layer, string p_layer_name, int p_width)
|
||
{
|
||
if (polygon_corner_count <= 0)
|
||
{
|
||
return;
|
||
}
|
||
for (int i = 0; i < polygon_corner_count; ++i)
|
||
{
|
||
line_handeled[i] = false;
|
||
}
|
||
for (;;)
|
||
{
|
||
int more_parts = combineLines(polyline_endpoint_tolerance);
|
||
if (!more_parts)
|
||
{
|
||
break;
|
||
}
|
||
|
||
printf(" (%s", KeepoutType(p_layer));
|
||
p_layer_name = "signal";
|
||
if (p_layer == 39 || p_layer == 41)
|
||
p_layer_name = TopLayer;
|
||
if (p_layer == 40 || p_layer == 42)
|
||
p_layer_name = BotLayer;
|
||
|
||
printf("(path ");
|
||
write_Str(p_layer_name);
|
||
printf(" ");
|
||
write_Db2Unit(p_width);
|
||
printf(" ");
|
||
|
||
for (i = 0; i< polygon_part_corner_count; ++i)
|
||
{
|
||
write_Db2Unit(polygon_part_corners_x[i]);
|
||
printf(" ");
|
||
write_Db2Unit(polygon_part_corners_y[i]);
|
||
printf(" ");
|
||
}
|
||
printf("))\n");
|
||
}
|
||
}
|
||
|
||
|
||
void Structure()
|
||
//--------------
|
||
{
|
||
board(Board)
|
||
{
|
||
// print the vias
|
||
|
||
printf(" (via");
|
||
for (int i = 0; i < ViaType; i++)
|
||
{
|
||
printf("\n ");
|
||
write_qStr(ViaTypeName[i]);
|
||
}
|
||
if (ViaType == 0)
|
||
{
|
||
// create a default via padstack
|
||
string tmp;
|
||
sprintf(tmp, "ViaDefault$%f", default_drill_size);
|
||
printf("\n "); write_qStr(tmp);
|
||
}
|
||
printf("\n )\n");
|
||
|
||
// print the rules
|
||
|
||
printf(" (rule (width %f", default_wire_width);
|
||
printf(")(clearance %f", default_clearance);
|
||
printf("))\n");
|
||
if (clearance_wire_pad > 0 && clearance_wire_pad != default_clearance)
|
||
{
|
||
printf(" (rule (clearance %f", clearance_wire_pad);
|
||
printf(" (type wire_pin)))\n");
|
||
}
|
||
if (clearance_wire_smd > 0 && clearance_wire_smd != default_clearance)
|
||
{
|
||
printf(" (rule (clearance %f", clearance_wire_smd);
|
||
printf(" (type wire_smd)))\n");
|
||
}
|
||
if (clearance_wire_via > 0 && clearance_wire_via != default_clearance)
|
||
{
|
||
printf(" (rule (clearance %f", clearance_wire_via);
|
||
printf(" (type wire_via)))\n");
|
||
}
|
||
if (clearance_pad_pad > 0 && clearance_pad_pad != default_clearance)
|
||
{
|
||
printf(" (rule (clearance %f", clearance_pad_pad);
|
||
printf(" (type pin_pin)))\n");
|
||
}
|
||
if (clearance_pad_via > 0 && clearance_pad_via != default_clearance)
|
||
{
|
||
printf(" (rule (clearance %f", clearance_pad_via);
|
||
printf(" (type pin_via)))\n");
|
||
}
|
||
if (clearance_via_via > 0 && clearance_via_via != default_clearance)
|
||
{
|
||
printf(" (rule (clearance %f", clearance_via_via);
|
||
printf(" (type via_via)))\n");
|
||
}
|
||
if (clearance_smd_pad > 0 && clearance_smd_pad != default_clearance)
|
||
{
|
||
printf(" (rule (clearance %f", clearance_smd_pad);
|
||
printf(" (type smd_pin)))\n");
|
||
}
|
||
if (clearance_smd_via > 0 && clearance_smd_via != default_clearance)
|
||
{
|
||
printf(" (rule (clearance %f", clearance_smd_via);
|
||
printf(" (type smd_via)))\n");
|
||
}
|
||
if (clearance_smd_smd > 0 && clearance_smd_smd != default_clearance)
|
||
{
|
||
printf(" (rule (clearance %f", clearance_smd_smd);
|
||
printf(" (type smd_smd)))\n");
|
||
}
|
||
|
||
// print the keepouts
|
||
|
||
Board.layers(Layer)
|
||
{
|
||
if (Layer.number == LAYER_TOP)
|
||
TopLayer = LayerFromId(Layer.number);
|
||
else
|
||
if (Layer.number == LAYER_BOTTOM)
|
||
BotLayer = LayerFromId(Layer.number);
|
||
|
||
if (IsKeepoutLayer(Layer.number))
|
||
{
|
||
string LayerName;
|
||
|
||
LayerName = LayerFromId(Layer.number); // Layer.name;
|
||
if (Layer.number == LAYER_DIMENSION)
|
||
LayerName = "signal";
|
||
else
|
||
if (Layer.number == LAYER_TSTOP)
|
||
LayerName = TopLayer;
|
||
else
|
||
LayerName = BotLayer;
|
||
|
||
int width = 0;
|
||
polygon_corner_count = 0;
|
||
|
||
Board.wires(W)
|
||
{
|
||
if (W.layer == Layer.number)
|
||
{
|
||
polygon_corner_count = process_next_wire(W, polygon_corner_count);
|
||
width = W.width;
|
||
}
|
||
}
|
||
|
||
make_keepout_shape(Layer.number, LayerName, width);
|
||
|
||
Board.circles(Circle)
|
||
{
|
||
|
||
if (Circle.layer == Layer.number)
|
||
{
|
||
printf(" (%s", KeepoutType(Layer.number));
|
||
LayerName = "signal";
|
||
if (Layer.number == 39 || Layer.number == 41)
|
||
LayerName = TopLayer;
|
||
if (Layer.number == 40 || Layer.number == 42)
|
||
LayerName = BotLayer;
|
||
|
||
printf("(circ ");
|
||
write_Str(LayerName); printf(" ");
|
||
|
||
CircleDesc(Circle);
|
||
printf("))\n");
|
||
}
|
||
}
|
||
|
||
Board.rectangles(Rectangle)
|
||
{
|
||
|
||
if (Rectangle.layer == Layer.number)
|
||
{
|
||
printf(" (%s", KeepoutType(Layer.number));
|
||
LayerName = "signal";
|
||
if (Layer.number == 39 || Layer.number == 41)
|
||
LayerName = TopLayer;
|
||
if (Layer.number == 40 || Layer.number == 42)
|
||
LayerName = BotLayer;
|
||
|
||
printf("(rect ");
|
||
write_Str(LayerName); printf(" ");
|
||
RectangleDesc(Rectangle);
|
||
printf("))\n");
|
||
}
|
||
}
|
||
|
||
Board.polygons(Polygon)
|
||
{
|
||
|
||
if (Polygon.layer==Layer.number)
|
||
{
|
||
LayerName = TopLayer;
|
||
if (Layer.number == 40 || Layer.number == 42)
|
||
LayerName = BotLayer;
|
||
Polygon.wires(W)
|
||
{
|
||
polygon_corner_count = process_next_wire(W, polygon_corner_count);
|
||
width = W.width;
|
||
}
|
||
make_keepout_shape(Layer.number, LayerName, width);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Board.holes(Hole)
|
||
{
|
||
|
||
printf(" (keepout (circ signal ");
|
||
|
||
write_Db2Unit(Hole.diameter[LAYER_TSTOP]);
|
||
printf(" ");
|
||
write_Db2Unit(Hole.x);
|
||
printf(" ");
|
||
write_Db2Unit(Hole.y);
|
||
printf("))\n");
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
real get_drufile_value(string p_line, string p_separator)
|
||
{
|
||
return Unit2Value( strtod(strsub(p_line, strrstr(p_line, p_separator)+2, strlen(p_line))), strsub(p_line, strlen(p_line)-1, 1) );
|
||
}
|
||
|
||
board(Board)
|
||
//----------
|
||
{
|
||
string DruFile = filesetext(Board.name, ".dru");
|
||
|
||
if(argv[1]!="f")
|
||
{
|
||
|
||
|
||
string ScrFile = filesetext(Board.name, "_gen_drufile.scr");
|
||
|
||
// Because the dru_file cannot be read from an ulp-file,
|
||
// a script file is created, which creates the dru_file
|
||
// and then calls this ulp-file again with the option f.
|
||
|
||
output(ScrFile, "wtD")
|
||
{
|
||
string tmp;
|
||
tmp = filename(argv[0]);
|
||
printf("DRC SAVE '%s';\n", DruFile);
|
||
printf("RUN %s f;", tmp);
|
||
|
||
exit("script '" + ScrFile + "';");
|
||
}
|
||
}
|
||
clearance_wire_pad = clearance_wire_smd = clearance_wire_via = clearance_pad_pad = clearance_pad_via
|
||
= clearance_via_via = clearance_smd_pad = clearance_smd_via
|
||
= clearance_smd_smd = -1;
|
||
|
||
Units = Board.grid.unit;
|
||
|
||
string default_name = filesetext(Board.name, ".dsn");
|
||
string Filename = dlgFileSave("Eagle to DSN Format", default_name, "*.dsn");
|
||
|
||
if (filesize(DruFile))
|
||
{
|
||
string Lines[];
|
||
int nLines = fileread(Lines, DruFile);
|
||
string separator = "= ";
|
||
int line_no;
|
||
real min_via_outer;
|
||
for (line_no == 0; line_no < nLines; ++line_no)
|
||
{
|
||
string curr_line = Lines[line_no];
|
||
if (strstr(curr_line, "layerSetup") == 0)
|
||
{
|
||
layer_setup = strsub( curr_line, strrstr(curr_line, separator)+2, strlen(curr_line) );
|
||
}
|
||
else if (strstr(curr_line, "msWidth") == 0)
|
||
{
|
||
default_wire_width = get_drufile_value(curr_line, separator);
|
||
|
||
}
|
||
else if (strstr(curr_line, "mdWireWire") == 0)
|
||
{
|
||
default_clearance = get_drufile_value(curr_line, separator);
|
||
|
||
}
|
||
else if (strstr(curr_line, "mdWirePad") == 0)
|
||
{
|
||
clearance_wire_pad = get_drufile_value(curr_line, separator);
|
||
clearance_wire_smd = clearance_wire_pad;
|
||
}
|
||
else if (strstr(curr_line, "mdWireVia") == 0)
|
||
{
|
||
clearance_wire_via = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "mdPadPad") == 0)
|
||
{
|
||
clearance_pad_pad = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "mdPadVia") == 0)
|
||
{
|
||
clearance_pad_via = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "mdViaViaSameLayer") == 0)
|
||
{
|
||
; // not implemented
|
||
}
|
||
else if (strstr(curr_line, "mdViaVia") == 0)
|
||
{
|
||
clearance_via_via = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "mdSmdPad") == 0)
|
||
{
|
||
clearance_smd_pad = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "mdSmdVia") == 0)
|
||
{
|
||
clearance_smd_via = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "mdSmdSmd") == 0)
|
||
{
|
||
clearance_smd_smd = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "msDrill") == 0)
|
||
{
|
||
default_drill_size = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "rvPadInner") == 0)
|
||
{
|
||
rv_pad_inner = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "rlMaxPadInner") == 0)
|
||
{
|
||
max_pad_inner = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "rlMinViaOuter") == 0)
|
||
{
|
||
min_via_outer = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "rlMinViaInner") == 0)
|
||
{
|
||
min_via_inner = get_drufile_value(curr_line, separator);
|
||
}
|
||
else if (strstr(curr_line, "rlMinPadInner") == 0)
|
||
{
|
||
min_pad_inner = get_drufile_value(curr_line, separator);
|
||
}
|
||
}
|
||
default_via_size = default_drill_size + 2 * min_via_outer;
|
||
}
|
||
else
|
||
{
|
||
string Tmp;
|
||
sprintf(Tmp, "%s%s%s", "File ", DruFile, " not exists!");
|
||
if (dlgMessageBox(Tmp, "&Close") == 0)
|
||
exit(0);
|
||
}
|
||
|
||
if (strlen(Filename))
|
||
{
|
||
|
||
rgw=read_layer_setup(Board);
|
||
rgw=write_ViaType(Board, rgw);
|
||
rgw=find_layer(Board, rgw);
|
||
|
||
|
||
output(Filename)
|
||
{
|
||
Header();
|
||
PadTypes();
|
||
printf(" (structure\n");
|
||
Layers(Board);
|
||
board_dimension();
|
||
MakeBoundary();
|
||
Structure();
|
||
printf(" (control\n (via_at_smd on)\n )\n");
|
||
printf(" )\n");
|
||
Placement();
|
||
Images();
|
||
Network();
|
||
Wiring();
|
||
printf(")");
|
||
}
|
||
}
|
||
}
|