static void export_vrml_circle( MODEL_VRML& aModel, LAYER_NUM layer, double startx, double starty, double endx, double endy, double width ) { VRML_LAYER* vlayer; if( !GetLayer( aModel, layer, &vlayer ) ) return; if( width < aModel.minLineWidth ) width = aModel.minLineWidth; starty = -starty; endy = -endy; double hole, radius; radius = Distance( startx, starty, endx, endy ) + ( width / 2); hole = radius - width; if( !vlayer->AddCircle( startx, starty, radius, false ) ) throw( std::runtime_error( vlayer->GetError() ) ); if( hole > 0.0001 ) { if( !vlayer->AddCircle( startx, starty, hole, true ) ) throw( std::runtime_error( vlayer->GetError() ) ); } }
static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb ) { double scale = aModel.scale; double x, y; for( int ii = 0; ii < aPcb->GetAreaCount(); ii++ ) { ZONE_CONTAINER* zone = aPcb->GetArea( ii ); VRML_LAYER* vl; if( !GetLayer( aModel, zone->GetLayer(), &vl ) ) continue; if( !zone->IsFilled() ) { zone->SetFillMode( 0 ); // use filled polygons zone->BuildFilledSolidAreasPolygons( aPcb ); } const CPOLYGONS_LIST& poly = zone->GetFilledPolysList(); int nvert = poly.GetCornersCount(); int i = 0; while( i < nvert ) { int seg = vl->NewContour(); bool first = true; if( seg < 0 ) break; while( i < nvert ) { x = poly.GetX(i) * scale; y = -(poly.GetY(i) * scale); if( poly.IsEndContour(i) ) break; if( !vl->AddVertex( seg, x, y ) ) throw( std::runtime_error( vl->GetError() ) ); ++i; } // KiCad ensures that the first polygon is the outline // and all others are holes vl->EnsureWinding( seg, first ? false : true ); if( first ) first = false; ++i; } } }
static void export_vrml_arc( MODEL_VRML& aModel, LAYER_NUM layer, double centerx, double centery, double arc_startx, double arc_starty, double width, double arc_angle ) { VRML_LAYER* vlayer; if( !GetLayer( aModel, layer, &vlayer ) ) return; if( width < aModel.minLineWidth ) width = aModel.minLineWidth; centery = -centery; arc_starty = -arc_starty; if( !vlayer->AddArc( centerx, centery, arc_startx, arc_starty, width, arc_angle, false ) ) throw( std::runtime_error( vlayer->GetError() ) ); }
static void export_vrml_line( MODEL_VRML& aModel, LAYER_NUM layer, double startx, double starty, double endx, double endy, double width ) { VRML_LAYER* vlayer; if( !GetLayer( aModel, layer, &vlayer ) ) return; if( width < aModel.minLineWidth) width = aModel.minLineWidth; starty = -starty; endy = -endy; double angle = atan2( endy - starty, endx - startx ) * 180.0 / M_PI; double length = Distance( startx, starty, endx, endy ) + width; double cx = ( startx + endx ) / 2.0; double cy = ( starty + endy ) / 2.0; if( !vlayer->AddSlot( cx, cy, length, width, angle, false ) ) throw( std::runtime_error( vlayer->GetError() ) ); }
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; } }