static SCENEGRAPH* addOutline( IDF3_COMP_OUTLINE* outline, int idxColor, SGNODE* aParent ) { VRML_LAYER vpcb; if( !getOutlineModel( vpcb, outline->GetOutlines() ) ) { #ifdef DEBUG do { std::ostringstream ostr; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << " * [INFO] no valid outline data"; wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() ); } while( 0 ); #endif return NULL; } vpcb.EnsureWinding( 0, false ); double top = outline->GetThickness(); double bot = 0.0; // note: some IDF entities permit negative heights if( top < bot ) { bot = top; top = 0.0; } SCENEGRAPH* data = vrmlToSG( vpcb, idxColor, aParent, top, bot ); return data; }
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 makeOtherOutlines( IDF3_BOARD& brd, SGNODE* aParent ) { if( NULL == aParent ) return false; VRML_LAYER vpcb; int ncomponents = 0; double brdTop = brd.GetBoardThickness(); double top, bot; // Add the component outlines const std::map< std::string, OTHER_OUTLINE* >*const comp = brd.GetOtherOutlines(); std::map< std::string, OTHER_OUTLINE* >::const_iterator sc = comp->begin(); std::map< std::string, OTHER_OUTLINE* >::const_iterator ec = comp->end(); int nvcont; OTHER_OUTLINE* pout; while( sc != ec ) { pout = sc->second; if( std::abs( pout->GetThickness() ) < 0.001 ) { ++sc; continue; } if( !getOutlineModel( vpcb, pout->GetOutlines() ) ) { vpcb.Clear(); ++sc; continue; } vpcb.EnsureWinding( 0, false ); nvcont = vpcb.GetNContours() - 1; while( nvcont > 0 ) vpcb.EnsureWinding( nvcont--, true ); if( pout->GetSide() == IDF3::LYR_BOTTOM ) { top = 0.0; bot = -pout->GetThickness(); } else { bot = brdTop; top = bot + pout->GetThickness(); } if( NULL == vrmlToSG( vpcb, -1, aParent, top, bot ) ) { vpcb.Clear(); ++sc; continue; } ++ncomponents; vpcb.Clear(); ++sc; } if( 0 == ncomponents ) return false; return true; }
static SCENEGRAPH* makeBoard( IDF3_BOARD& brd, SGNODE* aParent ) { if( NULL == aParent ) return NULL; VRML_LAYER vpcb; // check if no board outline if( brd.GetBoardOutlinesSize() < 1 ) return NULL; if( !getOutlineModel( vpcb, brd.GetBoardOutline()->GetOutlines() ) ) return NULL; vpcb.EnsureWinding( 0, false ); int nvcont = vpcb.GetNContours() - 1; while( nvcont > 0 ) vpcb.EnsureWinding( nvcont--, true ); // Add the drill holes const std::list<IDF_DRILL_DATA*>* drills = &brd.GetBoardDrills(); std::list<IDF_DRILL_DATA*>::const_iterator sd = drills->begin(); std::list<IDF_DRILL_DATA*>::const_iterator ed = drills->end(); while( sd != ed ) { vpcb.AddCircle( (*sd)->GetDrillXPos(), (*sd)->GetDrillYPos(), (*sd)->GetDrillDia() / 2.0, true ); ++sd; } std::map< std::string, IDF3_COMPONENT* >*const comp = brd.GetComponents(); std::map< std::string, IDF3_COMPONENT* >::const_iterator sc = comp->begin(); std::map< std::string, IDF3_COMPONENT* >::const_iterator ec = comp->end(); while( sc != ec ) { drills = sc->second->GetDrills(); sd = drills->begin(); ed = drills->end(); while( sd != ed ) { vpcb.AddCircle( (*sd)->GetDrillXPos(), (*sd)->GetDrillYPos(), (*sd)->GetDrillDia() / 2.0, true ); ++sd; } ++sc; } double top = brd.GetBoardThickness(); SCENEGRAPH* data = vrmlToSG( vpcb, 0, aParent, top, 0.0 ); return data; }