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_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 bool getOutlineModel( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items ) { // empty outlines are not unusual so we fail quietly if( items->size() < 1 ) return false; int nvcont = 0; int iseg = 0; std::list< IDF_OUTLINE* >::const_iterator scont = items->begin(); std::list< IDF_OUTLINE* >::const_iterator econt = items->end(); std::list<IDF_SEGMENT*>::iterator sseg; std::list<IDF_SEGMENT*>::iterator eseg; IDF_SEGMENT lseg; while( scont != econt ) { nvcont = model.NewContour(); if( nvcont < 0 ) { #ifdef DEBUG do { std::ostringstream ostr; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << " * [INFO] cannot create an outline"; wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() ); } while( 0 ); #endif return false; } if( (*scont)->size() < 1 ) { #ifdef DEBUG do { std::ostringstream ostr; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << " * [INFO] invalid contour: no vertices"; wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() ); } while( 0 ); #endif return false; } sseg = (*scont)->begin(); eseg = (*scont)->end(); iseg = 0; while( sseg != eseg ) { lseg = **sseg; if( !addSegment( model, &lseg, nvcont, iseg ) ) { #ifdef DEBUG do { std::ostringstream ostr; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << " * [BUG] cannot add segment"; wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() ); } while( 0 ); #endif return false; } ++iseg; ++sseg; } ++scont; } return true; }