//===================================== // // 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= 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; i0 && 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ärer Array, der nur während der Berechnung benö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 über den ganzen String for (i=0; i0 && 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; i0 && strtol(LayerSetup[i])<17) { for (int j=0; (j 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 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 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 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]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 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(")"); } } }