static void export_vrml_drawsegment( MODEL_VRML& aModel, DRAWSEGMENT* drawseg ) { LAYER_NUM layer = drawseg->GetLayer(); double w = drawseg->GetWidth() * aModel.scale; double x = drawseg->GetStart().x * aModel.scale; double y = drawseg->GetStart().y * aModel.scale; double xf = drawseg->GetEnd().x * aModel.scale; double yf = drawseg->GetEnd().y * aModel.scale; // Items on the edge layer are handled elsewhere; just return if( layer == Edge_Cuts ) return; switch( drawseg->GetShape() ) { case S_ARC: export_vrml_arc( aModel, layer, (double) drawseg->GetCenter().x, (double) drawseg->GetCenter().y, (double) drawseg->GetArcStart().x, (double) drawseg->GetArcStart().y, w, drawseg->GetAngle() / 10 ); break; case S_CIRCLE: export_vrml_circle( aModel, layer, x, y, xf, yf, w ); break; default: export_vrml_line( aModel, layer, x, y, xf, yf, w ); break; } }
static void export_round_padstack( BOARD* pcb, double x, double y, double r, int bottom_layer, int top_layer ) { int copper_layers = pcb->GetCopperLayerCount( ); for( int layer = bottom_layer; layer < copper_layers; layer++ ) { // The last layer is always the component one, unless it's single face if( (layer > FIRST_COPPER_LAYER) && (layer == copper_layers - 1) ) layer = LAST_COPPER_LAYER; if( layer <= top_layer ) export_vrml_circle( layer, x, y, x + r / 2, y, r ); } }
static void export_vrml_edge_module( EDGE_MODULE* aOutline ) //{{{ { int layer = aOutline->GetLayer(); double x = aOutline->GetStart().x; double y = aOutline->GetStart().y; double xf = aOutline->GetEnd().x; double yf = aOutline->GetEnd().y; double w = aOutline->GetWidth(); switch( aOutline->GetShape() ) { case S_ARC: export_vrml_arc( layer, x, y, xf, yf, w, aOutline->GetAngle()/10 ); break; case S_CIRCLE: export_vrml_circle( layer, x, y, xf, yf, w ); break; default: export_vrml_line( layer, x, y, xf, yf, w, 1 ); break; } }
static void export_vrml_edge_module( MODEL_VRML& aModel, EDGE_MODULE* aOutline, double aOrientation ) { LAYER_NUM layer = aOutline->GetLayer(); double x = aOutline->GetStart().x * aModel.scale; double y = aOutline->GetStart().y * aModel.scale; double xf = aOutline->GetEnd().x * aModel.scale; double yf = aOutline->GetEnd().y * aModel.scale; double w = aOutline->GetWidth() * aModel.scale; switch( aOutline->GetShape() ) { case S_SEGMENT: export_vrml_line( aModel, layer, x, y, xf, yf, w ); break; case S_ARC: export_vrml_arc( aModel, layer, x, y, xf, yf, w, aOutline->GetAngle() / 10 ); break; case S_CIRCLE: export_vrml_circle( aModel, layer, x, y, xf, yf, w ); break; case S_POLYGON: { VRML_LAYER* vl; if( !GetLayer( aModel, layer, &vl ) ) break; int nvert = aOutline->GetPolyPoints().size() - 1; int i = 0; if( nvert < 3 ) break; int seg = vl->NewContour(); if( seg < 0 ) break; while( i < nvert ) { CPolyPt corner( aOutline->GetPolyPoints()[i] ); RotatePoint( &corner.x, &corner.y, aOrientation ); corner.x += aOutline->GetPosition().x; corner.y += aOutline->GetPosition().y; x = corner.x * aModel.scale; y = - ( corner.y * aModel.scale ); if( !vl->AddVertex( seg, x, y ) ) throw( std::runtime_error( vl->GetError() ) ); ++i; } vl->EnsureWinding( seg, false ); } break; default: break; } }
static void export_vrml_pad( BOARD* pcb, D_PAD* aPad ) //{{{ { double hole_drill_w = (double) aPad->GetDrillSize().x / 2; double hole_drill_h = (double) aPad->GetDrillSize().y / 2; double hole_drill = std::min( hole_drill_w, hole_drill_h ); double hole_x = aPad->GetPosition().x; double hole_y = aPad->GetPosition().y; // Export the hole on the edge layer if( hole_drill > 0 ) { if( aPad->GetDrillShape() == PAD_OVAL ) { // Oblong hole (slot) export_vrml_slot( layer_triangles[EDGE_N], FIRST_COPPER_LAYER, LAST_COPPER_LAYER, hole_x, hole_y, hole_drill_w, hole_drill_h, aPad->GetOrientation() ); } else { // Drill a round hole export_vrml_hole( layer_triangles[EDGE_N], FIRST_COPPER_LAYER, LAST_COPPER_LAYER, hole_x, hole_y, hole_drill ); } } // The pad proper, on the selected layers int layer_mask = aPad->GetLayerMask(); int copper_layers = pcb->GetCopperLayerCount( ); // The (maybe offseted) pad position wxPoint pad_pos = aPad->ReturnShapePos(); double pad_x = pad_pos.x; double pad_y = pad_pos.y; wxSize pad_delta = aPad->GetDelta(); double pad_dx = pad_delta.x / 2; double pad_dy = pad_delta.y / 2; double pad_w = aPad->GetSize().x / 2; double pad_h = aPad->GetSize().y / 2; for( int layer = FIRST_COPPER_LAYER; layer < copper_layers; layer++ ) { // The last layer is always the component one, unless it's single face if( (layer > FIRST_COPPER_LAYER) && (layer == copper_layers - 1) ) layer = LAST_COPPER_LAYER; if( layer_mask & (1 << layer) ) { // OK, the pad is on this layer, export it switch( aPad->GetShape() ) { case PAD_CIRCLE: export_vrml_circle( layer, pad_x, pad_y, pad_x + pad_w / 2, pad_y, pad_w ); break; case PAD_OVAL: export_vrml_oval_pad( layer, pad_x, pad_y, pad_w * 2, pad_h * 2, aPad->GetOrientation() ); break; case PAD_RECT: // Just to be sure :D pad_dx = 0; pad_dy = 0; case PAD_TRAPEZOID: { int coord[8] = { KiROUND(-pad_w - pad_dy), KiROUND(+pad_h + pad_dx), KiROUND(-pad_w + pad_dy), KiROUND(-pad_h - pad_dx), KiROUND(+pad_w - pad_dy), KiROUND(+pad_h - pad_dx), KiROUND(+pad_w + pad_dy), KiROUND(-pad_h + pad_dx), }; for( int i = 0; i < 4; i++ ) { RotatePoint( &coord[i * 2], &coord[i * 2 + 1], aPad->GetOrientation() ); coord[i * 2] += KiROUND( pad_x ); coord[i * 2 + 1] += KiROUND( pad_y ); } bag_flat_quad( layer, coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7] ); } break; default: ; } } } }
static void export_vrml_drawsegment( DRAWSEGMENT* drawseg ) //{{{ { int layer = drawseg->GetLayer(); double w = drawseg->GetWidth(); double x = drawseg->GetStart().x; double y = drawseg->GetStart().y; double xf = drawseg->GetEnd().x; double yf = drawseg->GetEnd().y; // Items on the edge layer are high, not thick if( layer == EDGE_N ) { switch( drawseg->GetShape() ) { // There is a special 'varc' primitive for this case S_ARC: export_vrml_varc( layer_triangles[layer], FIRST_COPPER_LAYER, LAST_COPPER_LAYER, x, y, xf, yf, drawseg->GetAngle()/10 ); break; // Circles on edge are usually important holes case S_CIRCLE: export_vrml_hole( layer_triangles[layer], FIRST_COPPER_LAYER, LAST_COPPER_LAYER, x, y, hypot( xf - x, yf - y ) / 2 ); break; default: { // Simply a quad double z_top = layer_z[FIRST_COPPER_LAYER]; double z_bottom = layer_z[LAST_COPPER_LAYER]; bag_vquad( layer_triangles[layer], x, y, xf, yf, z_top, z_bottom ); break; } } } else { switch( drawseg->GetShape() ) { case S_ARC: export_vrml_arc( layer, (double) drawseg->GetCenter().x, (double) drawseg->GetCenter().y, (double) drawseg->GetArcStart().x, (double) drawseg->GetArcStart().y, w, drawseg->GetAngle()/10 ); break; case S_CIRCLE: export_vrml_circle( layer, x, y, xf, yf, w ); break; default: export_vrml_line( layer, x, y, xf, yf, w, 1 ); break; } } }