void EDA_3D_CANVAS::draw3DAxis() { if( ! m_glLists[GL_ID_AXIS] ) { m_glLists[GL_ID_AXIS] = glGenLists( 1 ); glNewList( m_glLists[GL_ID_AXIS], GL_COMPILE ); glEnable( GL_COLOR_MATERIAL ); glBegin( GL_LINES ); SetGLColor( RED ); glNormal3f( 0.0f, 0.0f, 1.0f ); // Normal is Z axis glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( -10.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( 10.0f, 0.0f, 0.0f ); // X axis SetGLColor( GREEN ); glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, -10.0f, 0.0f ); // Y axis glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 10.0f, 0.0f ); SetGLColor( BLUE ); glNormal3f( 1.0f, 0.0f, 0.0f ); // Normal is Y axis glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, -10.0f ); glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, 10.0f ); // Z axis glEnd(); glEndList(); } }
void OpenGLDrawRenderLines(DISPLAY *display, RECTANGLE *r, BOOL remove) { int w, h; GLfloat projmatrix[16]; if(remove) SetGLColor(COLOR_BKGROUND); else SetGLColor(COLOR_UNSELECTED); glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0x8888); glGetFloatv(GL_PROJECTION_MATRIX, projmatrix); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho( 0, display->view->width, 0, display->view->height, -100.f, 100.f); if (r->top == display->view->top) { glBegin(GL_LINES); glVertex2f(r->left, r->top); glVertex2f(r->left, r->bottom); glVertex2f(r->right, r->top); glVertex2f(r->right, r->bottom); glEnd(); } else { glBegin(GL_LINES); glVertex2f(r->left, r->top); glVertex2f(r->right, r->top); glVertex2f(r->left, r->bottom); glVertex2f(r->right, r->bottom); glEnd(); } if (global.enablearea) { w = r->right - r->left; h = r->bottom - r->top; glBegin(GL_LINES); glVertex2f(w*global.xmin + r->left, display->view->height - h*global.ymin + r->top); glVertex2f(w*global.xmax + r->left, display->view->height - h*global.ymin + r->top); glVertex2f(w*global.xmax + r->left, display->view->height - h*global.ymin + r->top); glVertex2f(w*global.xmax + r->left, display->view->height - h*global.ymax + r->top); glVertex2f(w*global.xmax + r->left, display->view->height - h*global.ymax + r->top); glVertex2f(w*global.xmin + r->left, display->view->height - h*global.ymax + r->top); glVertex2f(w*global.xmin + r->left, display->view->height - h*global.ymax + r->top); glVertex2f(w*global.xmin + r->left, display->view->height - h*global.ymin + r->top); glEnd(); } glDisable(GL_LINE_STIPPLE); glLoadMatrixf(projmatrix); glMatrixMode(GL_MODELVIEW); }
void GOpenGLBoard::DoGroupBegin(const GAABox2& LogicBox) { gIsFirstGroupDrawing = G_TRUE; // if group opacity is not supported by hardware or group compositing operation is DST_OP just exit; the case of // CLEAR_OP is the same, a black box will be drawn inside DoGroupEnd() if (!gGroupOpacitySupport || GroupCompOp() == G_DST_OP) return; // group begin affects only color buffer if (TargetMode() == G_CACHE_MODE || TargetMode() == G_CLIP_MODE || TargetMode() == G_CLIP_AND_CACHE_MODE) return; GrabFrameBuffer(LogicBox, gGLGroupRect); GReal ll, rr, bb, tt; Projection(ll, rr, bb, tt); GMatrix44 m = GLProjectionMatrix(ll, rr, bb, tt, 1); glMatrixMode(GL_PROJECTION); glPushMatrix(); #ifdef DOUBLE_REAL_TYPE glLoadMatrixd((const GLdouble *)m.Data()); #else glLoadMatrixf((const GLfloat *)m.Data()); #endif glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); GLDisableShaders(); SetGLColor(GVector4(1, 1, 1, 0)); // enable texture 2D SELECT_AND_DISABLE_TUNIT(0) glDisable(GL_BLEND); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); DrawGLBox(gGLGroupRect.gExpandedLogicBox); // now intersect bounding box with current mask(s) if (ClipEnabled()) { StencilPush(); DrawGLBox(gGLGroupRect.gExpandedLogicBox); // increment top stencil value because StencilPush checks for InsideGroup() flag; gTopStencilValue is // incremented only if we are not inside e group (here we are already in a group, because we have just // entered it) gTopStencilValue++; } // exit from window-mode glMatrixMode(GL_PROJECTION); glPopMatrix(); }
void Pcb3D_GLCanvas::Draw3D_DrawSegment(DRAWSEGMENT * segment) /*************************************************************/ { int layer; double x, y, xf, yf; double zpos, w; int color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[segment->m_Layer]; if ( color & ITEM_NOT_SHOW ) return; SetGLColor(color); w = segment->m_Width * g_Parm_3D_Visu.m_BoardScale; x = segment->m_Start.x * g_Parm_3D_Visu.m_BoardScale; y = segment->m_Start.y * g_Parm_3D_Visu.m_BoardScale; xf = segment->m_End.x * g_Parm_3D_Visu.m_BoardScale; yf = segment->m_End.y * g_Parm_3D_Visu.m_BoardScale; if ( segment->m_Layer == EDGE_N) { for ( layer = 0; layer < g_Parm_3D_Visu.m_Layers; layer++ ) { glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0); zpos = g_Parm_3D_Visu.m_LayerZcoord[layer]; Draw3D_FilledSegment( x, -y, xf, -yf, w, zpos); } } else { zpos = g_Parm_3D_Visu.m_LayerZcoord[segment->m_Layer]; Draw3D_FilledSegment( x, -y, xf, -yf, w, zpos); } }
// Draw 3D pads. void EDA_3D_CANVAS::draw3DPadHole( const D_PAD* aPad ) { // Draw the pad hole wxSize drillsize = aPad->GetDrillSize(); bool hasHole = drillsize.x && drillsize.y; if( !hasHole ) return; // Store here the points to approximate hole by segments SHAPE_POLY_SET holecornersBuffer; int thickness = GetPrm3DVisu().GetCopperThicknessBIU(); int height = GetPrm3DVisu().GetLayerZcoordBIU( F_Cu ) - GetPrm3DVisu().GetLayerZcoordBIU( B_Cu ); if( isRealisticMode() ) setGLCopperColor(); else SetGLColor( DARKGRAY ); int holeZpoz = GetPrm3DVisu().GetLayerZcoordBIU( B_Cu ) - thickness / 2; int holeHeight = height + thickness; if( drillsize.x == drillsize.y ) // usual round hole { int hole_radius = ( drillsize.x + thickness ) / 2; Draw3D_ZaxisCylinder( aPad->GetPosition(), hole_radius, holeHeight, thickness, holeZpoz, GetPrm3DVisu().m_BiuTo3Dunits ); } else // Oblong hole { wxPoint ends_offset; int width; if( drillsize.x > drillsize.y ) // Horizontal oval { ends_offset.x = ( drillsize.x - drillsize.y ) / 2; width = drillsize.y; } else // Vertical oval { ends_offset.y = ( drillsize.y - drillsize.x ) / 2; width = drillsize.x; } RotatePoint( &ends_offset, aPad->GetOrientation() ); wxPoint start = aPad->GetPosition() + ends_offset; wxPoint end = aPad->GetPosition() - ends_offset; int hole_radius = ( width + thickness ) / 2; // Draw the hole Draw3D_ZaxisOblongCylinder( start, end, hole_radius, holeHeight, thickness, holeZpoz, GetPrm3DVisu().m_BiuTo3Dunits ); } }
void DrawSelf () { // draw line SetGLColor (Color (1, 1, 1)); glLineWidth(2.0); glBegin (GL_LINES); glVertex (Vect (0, 0, 0)); glVertex (vertex); glEnd (); }
// Helper function: initialize the color to draw the // solder mask layers in realistic mode. void EDA_3D_CANVAS::setGLSolderMaskColor( float aTransparency ) { // Generates a solder mask color SetGLColor( GetPrm3DVisu().m_SolderMaskColor, aTransparency ); if( isEnabled( FL_RENDER_TEXTURES ) ) { SetGLTexture( m_text_pcb, TEXTURE_PCB_SCALE ); } }
// Helper function: initialize the color to draw the epoxy // body board in realistic mode. void EDA_3D_CANVAS::setGLEpoxyColor( float aTransparency ) { // Generates an epoxy color, near board color SetGLColor( GetPrm3DVisu().m_BoardBodyColor, aTransparency ); if( isEnabled( FL_RENDER_TEXTURES ) ) { SetGLTexture( m_text_pcb, TEXTURE_PCB_SCALE ); } }
// Helper function: initialize the color to draw the non copper layers // in realistic mode and normal mode. void EDA_3D_CANVAS::setGLTechLayersColor( LAYER_NUM aLayer ) { EDA_COLOR_T color; if( isRealisticMode() ) { switch( aLayer ) { case B_Paste: case F_Paste: SetGLColor( GetPrm3DVisu().m_SolderPasteColor, 1 ); break; case B_SilkS: case F_SilkS: SetGLColor( GetPrm3DVisu().m_SilkScreenColor, 0.96 ); if( isEnabled( FL_RENDER_TEXTURES ) ) { SetGLTexture( m_text_silk, 10.0f ); } break; case B_Mask: case F_Mask: setGLSolderMaskColor( 0.90 ); break; default: color = g_ColorsSettings.GetLayerColor( aLayer ); SetGLColor( color, 0.7 ); break; } } else { color = g_ColorsSettings.GetLayerColor( aLayer ); SetGLColor( color, 0.7 ); } }
void DrawSelf () { // draw line SetGLColor (Color (1, 1, 1)); glLineWidth(2.0); glBegin (GL_LINES); glVertex (Vect (0, 0, 0)); glVertex (vertex); glEnd (); // draw bar (DrawQuad draws from the bottom left corner) DrawQuad (Vect (-Feld () -> Width () / 2, Feld () -> Height () / 2 - h, 0), Vect (m, 0, 0), Vect (0, h, 0)); }
/************* * DESCRIPTION: Set the color with wich the object is drawn * INPUT: - * OUTPUT: - *************/ void TEXTURE_OBJECT::SetDrawColor(DISPLAY *display) { #ifdef __OPENGL__ if(display->display == DISPLAY_SOLID) SetGLColor(COLOR_BRUSH); else #endif // __OPENGL__ { if(selected) gfx.SetPen(COLOR_BRUSH); else gfx.SetPen(COLOR_UNSELECTED); } }
void Pcb3D_GLCanvas::Draw3D_Via(SEGVIA * via) /*********************************************/ /* 3D drawing for a VIA (cylinder + filled circles) */ { double x, y, r, hole; int layer, top_layer, bottom_layer; double zpos, height; int color; r = via->m_Width * g_Parm_3D_Visu.m_BoardScale / 2; hole = g_Parm_3D_Visu.m_BoardSettings->m_ViaDrill * g_Parm_3D_Visu.m_BoardScale / 2; x = via->m_Start.x * g_Parm_3D_Visu.m_BoardScale; y = via->m_Start.y * g_Parm_3D_Visu.m_BoardScale; via->ReturnLayerPair(&top_layer, &bottom_layer); // Drawing filled circles: for ( layer = bottom_layer; layer < g_Parm_3D_Visu.m_Layers; layer++ ) { zpos = g_Parm_3D_Visu.m_LayerZcoord[layer]; if ( layer < g_Parm_3D_Visu.m_Layers-1 ) color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer]; else color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[CMP_N]; if ( color & ITEM_NOT_SHOW ) continue; SetGLColor(color); glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0); Draw3D_FilledCircle(x, -y, r, hole, zpos); if ( layer >= top_layer) break; } // Drawing hole: SetGLColor(DARKGRAY); height = g_Parm_3D_Visu.m_LayerZcoord[top_layer] - g_Parm_3D_Visu.m_LayerZcoord[bottom_layer]; Draw3D_FilledCylinder(x, -y, hole, height, g_Parm_3D_Visu.m_LayerZcoord[bottom_layer]); }
void EDGE_MODULE::Draw3D(Pcb3D_GLCanvas * glcanvas) /***************************************************/ { int ux0, uy0, dx, dy,rayon, StAngle, EndAngle; double scale, x, y, fx, fy, w, zpos ; int color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[m_Layer]; if ( color & ITEM_NOT_SHOW ) return; SetGLColor(color); glNormal3f( 0.0, 0.0, (m_Layer == CUIVRE_N) ? -1.0 : 1.0); scale = g_Parm_3D_Visu.m_BoardScale; ux0 = m_Start.x; uy0 = m_Start.y; dx = m_End.x; dy = m_End.y; zpos = g_Parm_3D_Visu.m_LayerZcoord[m_Layer]; w = m_Width * g_Parm_3D_Visu.m_BoardScale; switch (m_Shape ) { case S_SEGMENT: x = m_Start.x * g_Parm_3D_Visu.m_BoardScale; y = m_Start.y * g_Parm_3D_Visu.m_BoardScale; fx = dx * g_Parm_3D_Visu.m_BoardScale; fy = dy * g_Parm_3D_Visu.m_BoardScale; Draw3D_FilledSegment(x, -y, fx, -fy, w, zpos); break ; case S_CIRCLE: rayon = (int)hypot((double)(dx-ux0),(double)(dy-uy0) ); /* TO DO */ break; case S_ARC: rayon = (int)hypot((double)(dx-ux0),(double)(dy-uy0) ); StAngle = (int)ArcTangente( dy-uy0, dx-ux0 ); EndAngle = StAngle + m_Angle; /* TO DO */ break; } }
void Pcb3D_GLCanvas::Draw3D_Track(TRACK * track) /************************************************/ { double zpos; int color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[track->m_Layer]; int layer = track->m_Layer; double ox, oy, fx, fy; double w; if ( color & ITEM_NOT_SHOW ) return; if ( track->m_Layer == CMP_N ) layer = g_Parm_3D_Visu.m_Layers -1; zpos = g_Parm_3D_Visu.m_LayerZcoord[layer]; SetGLColor(color); glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0); w = track->m_Width * g_Parm_3D_Visu.m_BoardScale; ox = track->m_Start.x * g_Parm_3D_Visu.m_BoardScale; oy = track->m_Start.y * g_Parm_3D_Visu.m_BoardScale; fx = track->m_End.x * g_Parm_3D_Visu.m_BoardScale; fy = track->m_End.y * g_Parm_3D_Visu.m_BoardScale; Draw3D_FilledSegment(ox, -oy, fx, -fy, w, zpos); }
void EDA_3D_CANVAS::draw3DViaHole( const VIA* aVia ) { LAYER_ID top_layer, bottom_layer; int thickness = GetPrm3DVisu().GetCopperThicknessBIU(); int inner_radius = (int)((float)aVia->GetDrillValue() * 1.01f) / 2.0f; // This add a bit more in order to correct a draw artifact while using thickness aVia->LayerPair( &top_layer, &bottom_layer ); // Drawing via hole: if( isRealisticMode() ) setGLCopperColor(); else { EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + aVia->GetViaType() ); SetGLColor( color ); } int height = GetPrm3DVisu().GetLayerZcoordBIU( top_layer ) - GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) + thickness; int zpos = GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) - thickness / 2; Draw3D_ZaxisCylinder( aVia->GetStart(), inner_radius, height, thickness, zpos, GetPrm3DVisu().m_BiuTo3Dunits ); }
void EDA_3D_CANVAS::Draw3DViaHole( const VIA* aVia ) { LAYER_ID top_layer, bottom_layer; int inner_radius = aVia->GetDrillValue() / 2; int thickness = GetPrm3DVisu().GetCopperThicknessBIU(); aVia->LayerPair( &top_layer, &bottom_layer ); // Drawing via hole: if( isRealisticMode() ) setGLCopperColor(); else { EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + aVia->GetViaType() ); SetGLColor( color ); } int height = GetPrm3DVisu().GetLayerZcoordBIU( top_layer ) - GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) - thickness; int zpos = GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) + thickness / 2; Draw3D_ZaxisCylinder( aVia->GetStart(), inner_radius + thickness / 2, height, thickness, zpos, GetPrm3DVisu().m_BiuTo3Dunits ); }
// draw a 3D grid: an horizontal grid (XY plane and Z = 0, // and a vertical grid (XZ plane and Y = 0) void EDA_3D_CANVAS::draw3DGrid( double aGriSizeMM ) { double zpos = 0.0; EDA_COLOR_T gridcolor = DARKGRAY; // Color of grid lines EDA_COLOR_T gridcolor_marker = LIGHTGRAY; // Color of grid lines every 5 lines const double scale = GetPrm3DVisu().m_BiuTo3Dunits; const double transparency = 0.3; glNormal3f( 0.0, 0.0, 1.0 ); wxSize brd_size = getBoardSize(); wxPoint brd_center_pos = getBoardCenter(); brd_center_pos.y = -brd_center_pos.y; int xsize = std::max( brd_size.x, Millimeter2iu( 100 ) ) * 1.2; int ysize = std::max( brd_size.y, Millimeter2iu( 100 ) ) * 1.2; // Grid limits, in 3D units double xmin = (brd_center_pos.x - xsize / 2) * scale; double xmax = (brd_center_pos.x + xsize / 2) * scale; double ymin = (brd_center_pos.y - ysize / 2) * scale; double ymax = (brd_center_pos.y + ysize / 2) * scale; double zmin = Millimeter2iu( -50 ) * scale; double zmax = Millimeter2iu( 100 ) * scale; // Draw horizontal grid centered on 3D origin (center of the board) for( int ii = 0; ; ii++ ) { if( (ii % 5) ) SetGLColor( gridcolor, transparency ); else SetGLColor( gridcolor_marker, transparency ); int delta = KiROUND( ii * aGriSizeMM * IU_PER_MM ); if( delta <= xsize / 2 ) // Draw grid lines parallel to X axis { glBegin( GL_LINES ); glVertex3f( (brd_center_pos.x + delta) * scale, -ymin, zpos ); glVertex3f( (brd_center_pos.x + delta) * scale, -ymax, zpos ); glEnd(); if( ii != 0 ) { glBegin( GL_LINES ); glVertex3f( (brd_center_pos.x - delta) * scale, -ymin, zpos ); glVertex3f( (brd_center_pos.x - delta) * scale, -ymax, zpos ); glEnd(); } } if( delta <= ysize / 2 ) // Draw grid lines parallel to Y axis { glBegin( GL_LINES ); glVertex3f( xmin, -(brd_center_pos.y + delta) * scale, zpos ); glVertex3f( xmax, -(brd_center_pos.y + delta) * scale, zpos ); glEnd(); if( ii != 0 ) { glBegin( GL_LINES ); glVertex3f( xmin, -(brd_center_pos.y - delta) * scale, zpos ); glVertex3f( xmax, -(brd_center_pos.y - delta) * scale, zpos ); glEnd(); } } if( ( delta > ysize / 2 ) && ( delta > xsize / 2 ) ) break; } // Draw vertical grid on Z axis glNormal3f( 0.0, -1.0, 0.0 ); // Draw vertical grid lines (parallel to Z axis) double posy = -brd_center_pos.y * scale; for( int ii = 0; ; ii++ ) { if( (ii % 5) ) SetGLColor( gridcolor, transparency ); else SetGLColor( gridcolor_marker, transparency ); double delta = ii * aGriSizeMM * IU_PER_MM; glBegin( GL_LINES ); xmax = (brd_center_pos.x + delta) * scale; glVertex3f( xmax, posy, zmin ); glVertex3f( xmax, posy, zmax ); glEnd(); if( ii != 0 ) { glBegin( GL_LINES ); xmin = (brd_center_pos.x - delta) * scale; glVertex3f( xmin, posy, zmin ); glVertex3f( xmin, posy, zmax ); glEnd(); } if( delta > xsize / 2.0f ) break; } // Draw horizontal grid lines on Z axis (parallel to X axis) for( int ii = 0; ; ii++ ) { if( (ii % 5) ) SetGLColor( gridcolor, transparency); else SetGLColor( gridcolor_marker, transparency ); double delta = ii * aGriSizeMM * IU_PER_MM * scale; if( delta <= zmax ) { // Draw grid lines on Z axis (positive Z axis coordinates) glBegin( GL_LINES ); glVertex3f( xmin, posy, delta ); glVertex3f( xmax, posy, delta ); glEnd(); } if( delta <= -zmin && ( ii != 0 ) ) { // Draw grid lines on Z axis (negative Z axis coordinates) glBegin( GL_LINES ); glVertex3f( xmin, posy, -delta ); glVertex3f( xmax, posy, -delta ); glEnd(); } if( ( delta > zmax ) && ( delta > -zmin ) ) break; } }
void D_PAD::Draw3D(Pcb3D_GLCanvas * glcanvas) /***********************************************/ /* Dessin 3D des pads avec leur trou de percage */ { int ii, ll, layer, nlmax; int ux0,uy0, dx,dx0,dy,dy0, delta_cx, delta_cy, xc, yc; int angle, delta_angle; int coord[4][2]; double fcoord[8][2], f_hole_coord[8][2]; float scale; double zpos; wxPoint shape_pos; double x, y, r, w, hole; double drillx, drilly; bool Oncu, Oncmp, Both; int color; scale = g_Parm_3D_Visu.m_BoardScale; hole = (double)m_Drill * scale / 2; /* calcul du centre des formes des pads : */ shape_pos = ReturnShapePos(); ux0 = shape_pos.x; uy0 = shape_pos.y; xc = ux0; yc = uy0; /* le trace depend de la rotation de l'empreinte */ dx = dx0 = m_Size.x >> 1 ; dy = dy0 = m_Size.y >> 1 ; /* demi dim dx et dy */ angle = m_Orient; drillx = m_Pos.x * scale; drilly = m_Pos.y * scale; /* trace du trou de percage */ if ( m_Drill ) { SetGLColor(DARKGRAY); Draw3D_FilledCylinder(drillx, -drilly, hole, g_Parm_3D_Visu.m_LayerZcoord[CMP_N], 0.0); } glNormal3f( 0.0, 0.0, 1.0); // Normal is Z axis nlmax = g_Parm_3D_Visu.m_Layers-1; Oncu = (m_Masque_Layer & CUIVRE_LAYER) ? TRUE : FALSE; Oncmp = (m_Masque_Layer & CMP_LAYER) ? TRUE : FALSE; Both = Oncu && Oncmp; switch (m_PadShape & 0x7F) { case CIRCLE : x = xc * scale; y = yc * scale; r = (double)dx * scale; for ( layer = CUIVRE_N; layer <= CMP_N; layer ++) { if (layer && (layer == nlmax) ) layer = CMP_N; if ( (layer == CMP_N) && ! Oncmp ) continue; if ( (layer == CUIVRE_N) && ! Oncu ) continue; if ( (layer > CUIVRE_N) && (layer < CMP_N) && !Both) continue; color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer]; if ( color & ITEM_NOT_SHOW ) continue; SetGLColor(color); glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0); zpos = g_Parm_3D_Visu.m_LayerZcoord[layer]; Draw3D_FilledCircle(x, -y, r, hole, zpos); } break; case OVALE : /* calcul de l'entraxe de l'ellipse */ if( dx > dy ) /* ellipse horizontale */ { delta_cx = dx - dy; delta_cy = 0; w = m_Size.y * scale; delta_angle = angle+900; } else /* ellipse verticale */ { delta_cx = 0; delta_cy = dy - dx; w = m_Size.x * scale; delta_angle = angle; } RotatePoint(&delta_cx, &delta_cy, angle); { double ox, oy, fx, fy; ox = (double)(ux0 + delta_cx) * scale; oy = (double)(uy0 + delta_cy) * scale; fx = (double)(ux0 - delta_cx) * scale; fy = (double)(uy0 - delta_cy) * scale; for ( layer = CUIVRE_N; layer <= CMP_N; layer ++) { if (layer && (layer == nlmax) ) layer = CMP_N; if ( (layer == CMP_N) && ! Oncmp ) continue; if ( (layer == CUIVRE_N) && ! Oncu ) continue; if ( (layer > CUIVRE_N) && (layer < CMP_N) && !Both) continue; color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer]; glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0); if ( color & ITEM_NOT_SHOW ) continue; SetGLColor(color); zpos = g_Parm_3D_Visu.m_LayerZcoord[layer]; Draw3D_FilledSegmentWithHole(ox, -oy, fx, -fy, w, drillx, -drilly, hole, zpos); } } break; case RECT : case SPECIAL_PAD: case TRAPEZE: { int ddx, ddy ; ddx = m_DeltaSize.x >> 1 ; ddy = m_DeltaSize.y >> 1 ; /* demi dim dx et dy */ coord[0][0] = - dx - ddy; coord[0][1] = + dy + ddx; coord[1][0] = - dx + ddy; coord[1][1] = - dy - ddx; coord[2][0] = + dx - ddy; coord[2][1] = - dy + ddx; coord[3][0] = + dx + ddy; coord[3][1] = + dy - ddx; for (ii = 0; ii < 4; ii++) { RotatePoint(&coord[ii][0],&coord[ii][1], angle); coord[ii][0] += ux0; coord[ii][1] += uy0; ll = ii*2; fcoord[ll][0] = coord[ii][0] * scale; fcoord[ll][1] = coord[ii][1] * scale; } for (ii = 0; ii < 7; ii+=2) { ll = ii+2; if (ll > 7) ll -= 8; fcoord[ii+1][0] = (fcoord[ii][0] + fcoord[ll][0])/2; fcoord[ii+1][1] = (fcoord[ii][1] + fcoord[ll][1])/2; } for (ii = 0; ii < 8; ii++) { f_hole_coord[ii][0] = -hole*0.707; f_hole_coord[ii][1] = hole*0.707; RotatePoint(&f_hole_coord[ii][0], &f_hole_coord[ii][1], angle -(ii * 450) ); f_hole_coord[ii][0] += drillx; f_hole_coord[ii][1] += drilly; } for ( layer = CUIVRE_N; layer <= CMP_N; layer ++) { if (layer && (layer == nlmax) ) layer = CMP_N; if ( (layer == CMP_N) && ! Oncmp ) continue; if ( (layer == CUIVRE_N) && ! Oncu ) continue; if ( (layer > CUIVRE_N) && (layer < CMP_N) && !Both) continue; color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer]; glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0); if ( color & ITEM_NOT_SHOW ) continue; SetGLColor(color); zpos = g_Parm_3D_Visu.m_LayerZcoord[layer]; glBegin(GL_QUAD_STRIP); for ( ii = 0; ii < 8; ii++ ) { glVertex3f( f_hole_coord[ii][0], -f_hole_coord[ii][1] , zpos); glVertex3f( fcoord[ii][0], -fcoord[ii][1] , zpos); } glVertex3f( f_hole_coord[0][0], -f_hole_coord[0][1] , zpos); glVertex3f( fcoord[0][0], -fcoord[0][1] , zpos); glEnd(); } break; default: break; } } }
GLuint Pcb3D_GLCanvas::CreateDrawGL_List(void) /**********************************************/ /* Creation de la liste des elements a afficher */ { GLuint gllist = glGenLists( 1 ); WinEDA_BasePcbFrame * pcbframe = m_Parent->m_Parent; BOARD * pcb = pcbframe->m_Pcb; TRACK * pt_piste; int ii; wxBusyCursor dummy; pcb->ComputeBoundaryBox(); g_Parm_3D_Visu.m_BoardSettings = pcb->m_BoardSettings; g_Parm_3D_Visu.m_BoardSize = pcb->m_BoundaryBox.GetSize(); g_Parm_3D_Visu.m_BoardPos = pcb->m_BoundaryBox.Centre(); g_Parm_3D_Visu.m_BoardPos.y = - g_Parm_3D_Visu.m_BoardPos.y; g_Parm_3D_Visu.m_Layers = pcb->m_BoardSettings->m_CopperLayerCount; g_Parm_3D_Visu.m_BoardScale = 2.0 / MAX(g_Parm_3D_Visu.m_BoardSize.x, g_Parm_3D_Visu.m_BoardSize.y); float epoxy_width = 1.6; // epoxy width in mm g_Parm_3D_Visu.m_Epoxy_Width = epoxy_width/2.54 * 1000 * g_Parm_3D_Visu.m_BoardScale; /* calcul de l'altitude de chaque couche */ for ( ii = 0; ii < 32; ii++ ) { if ( ii < g_Parm_3D_Visu.m_Layers ) g_Parm_3D_Visu.m_LayerZcoord[ii] = g_Parm_3D_Visu.m_Epoxy_Width * ii / (g_Parm_3D_Visu.m_Layers-1); else g_Parm_3D_Visu.m_LayerZcoord[ii] = g_Parm_3D_Visu.m_Epoxy_Width; } GLfloat zpos_cu = 500 * g_Parm_3D_Visu.m_BoardScale; GLfloat zpos_cmp = g_Parm_3D_Visu.m_Epoxy_Width + zpos_cu; g_Parm_3D_Visu.m_LayerZcoord[ADHESIVE_N_CU] = -zpos_cu*2; g_Parm_3D_Visu.m_LayerZcoord[ADHESIVE_N_CMP] = zpos_cmp + zpos_cu; g_Parm_3D_Visu.m_LayerZcoord[SILKSCREEN_N_CU] = -zpos_cu; g_Parm_3D_Visu.m_LayerZcoord[SILKSCREEN_N_CMP] = zpos_cmp; g_Parm_3D_Visu.m_LayerZcoord[DRAW_N] = zpos_cmp + zpos_cu; g_Parm_3D_Visu.m_LayerZcoord[COMMENT_N] = zpos_cmp + zpos_cu; g_Parm_3D_Visu.m_LayerZcoord[ECO1_N] = zpos_cmp + zpos_cu; g_Parm_3D_Visu.m_LayerZcoord[ECO2_N] = zpos_cmp + zpos_cu; glNewList( gllist, GL_COMPILE_AND_EXECUTE ); glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); /* draw axes*/ glEnable(GL_COLOR_MATERIAL); SetGLColor(WHITE); glBegin(GL_LINES); glNormal3f( 0.0, 0.0, 1.0); // Normal is Z axis glVertex3f( 0.0 , 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); // X axis glVertex3f( 0.0 , 0.0, 0.0); glVertex3f(0.0, -1.0, 0.0); // y axis glNormal3f( 1.0, 0.0, 0.0); // Normal is Y axis glVertex3f( 0.0 , 0.0, 0.0); glVertex3f(0.0, 0.0, 0.3); // z axis glEnd(); /* Draw epoxy limits (do not use, works and test in progress)*/ #if 0 glEnable(GL_FOG); GLfloat param; // param = GL_LINEAR; glFogfv(GL_FOG_MODE,& param); param = 0.2; glFogfv(GL_FOG_DENSITY,& param); param = g_Parm_3D_Visu.m_LayerZcoord[15]; glFogfv(GL_FOG_END,& param); glBegin(GL_QUADS); SetGLColor(g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[CMP_N]); double sx = DataScale3D * g_Parm_3D_Visu.m_BoardSize.x / 2; double sy = DataScale3D * g_Parm_3D_Visu.m_BoardSize.y / 2; double zpos = g_Parm_3D_Visu.m_LayerZcoord[15]; glNormal3f( 0.0, 0.0, 1.0); // Normal is Z axis sx = sy = 0.5; glVertex3f( -sx, -sy , zpos); glVertex3f( -sx, sy , zpos); glVertex3f( sx, sy , zpos); glVertex3f( sx, -sy , zpos); glEnd(); glBegin(GL_QUADS); SetGLColor(g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[CUIVRE_N]); glNormal3f( 0.0, 0.0, -1.0); // Normal is -Z axis glVertex3f( -sx, -sy , 0); glVertex3f( -sx, sy , 0); glVertex3f( sx, sy , 0); glVertex3f( sx, -sy , 0); glEnd(); #endif /* Translation du tracé du BOARD pour placer son centre en 0, 0 */ glTranslatef(-g_Parm_3D_Visu.m_BoardPos.x * g_Parm_3D_Visu.m_BoardScale, -g_Parm_3D_Visu.m_BoardPos.y * g_Parm_3D_Visu.m_BoardScale, 0.0F); glNormal3f( 0.0, 0.0, 1.0); // Normal is Z axis /* Tracé des pistes : */ for (pt_piste = pcb->m_Track ; pt_piste != NULL ; pt_piste = (TRACK*) pt_piste->Pnext ) { if ( pt_piste->m_StructType == TYPEVIA ) Draw3D_Via((SEGVIA*)pt_piste); else Draw3D_Track( pt_piste); } /* Tracé des edges */ EDA_BaseStruct * PtStruct; for ( PtStruct = pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Pnext) { #define STRUCT ((DRAWSEGMENT *) PtStruct) if( PtStruct->m_StructType != TYPEDRAWSEGMENT ) continue; Draw3D_DrawSegment(STRUCT); } /* tracé des modules */ MODULE * Module = (MODULE*) pcb->m_Modules; for ( ; Module != NULL; Module = (MODULE *) Module->Pnext ) { Module->Draw3D(this); } glEndList(); /* Test for errors */ GLenum err = glGetError(); if ( err != GL_NO_ERROR ) DisplayError(this, wxT("Error in GL commands") ); return gllist; }
void OpenGLDrawSelBox(VECTOR *min, VECTOR *min1, VECTOR *max, VECTOR *max1) { SetGLColor(COLOR_SELBOX); glDisable(GL_LIGHTING); glBegin(GL_LINES); glVertex3fv((GLfloat*)max); glVertex3f(max1->x, max->y, max->z); glVertex3fv((GLfloat*)max); glVertex3f(max->x, max1->y, max->z); glVertex3fv((GLfloat*)max); glVertex3f(max->x, max->y, max1->z); glVertex3f(max->x, max->y, min->z); glVertex3f(max1->x, max->y, min->z); glVertex3f(max->x, max->y, min->z); glVertex3f(max->x, max1->y, min->z); glVertex3f(max->x, max->y, min->z); glVertex3f(max->x, max->y, min1->z); glVertex3f(max->x, min->y, max->z); glVertex3f(max1->x, min->y, max->z); glVertex3f(max->x, min->y, max->z); glVertex3f(max->x, min1->y, max->z); glVertex3f(max->x, min->y, max->z); glVertex3f(max->x, min->y, max1->z); glVertex3f(max->x, min->y, min->z); glVertex3f(max1->x, min->y, min->z); glVertex3f(max->x, min->y, min->z); glVertex3f(max->x, min1->y, min->z); glVertex3f(max->x, min->y, min->z); glVertex3f(max->x, min->y, min1->z); glVertex3f(min->x, max->y, max->z); glVertex3f(min1->x, max->y, max->z); glVertex3f(min->x, max->y, max->z); glVertex3f(min->x, max1->y, max->z); glVertex3f(min->x, max->y, max->z); glVertex3f(min->x, max->y, max1->z); glVertex3f(min->x, max->y, min->z); glVertex3f(min1->x, max->y, min->z); glVertex3f(min->x, max->y, min->z); glVertex3f(min->x, max1->y, min->z); glVertex3f(min->x, max->y, min->z); glVertex3f(min->x, max->y, min1->z); glVertex3f(min->x, min->y, max->z); glVertex3f(min1->x, min->y, max->z); glVertex3f(min->x, min->y, max->z); glVertex3f(min->x, min1->y, max->z); glVertex3f(min->x, min->y, max->z); glVertex3f(min->x, min->y, max1->z); glVertex3fv((GLfloat*)min); glVertex3f(min1->x, min->y, min->z); glVertex3fv((GLfloat*)min); glVertex3f(min->x, min1->y, min->z); glVertex3fv((GLfloat*)min); glVertex3f(min->x, min->y, min1->z); glEnd(); glEnable(GL_LIGHTING); }
void OpenGLDrawGrid(DISPLAY *display) { float dx, dy, t1, t2, viewh, viewv; int i; float delta; SetGLColor(COLOR_GRID); glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0x8888); switch (display->view->viewmode) { case VIEW_CAMERA: case VIEW_PERSP: dx = -SUBDIV*display->gridsize; t1 = SUBDIV*display->gridsize; glBegin(GL_LINES); for (i = 0; i <= 2*SUBDIV; i++) { glVertex3f(t1, 0.f, dx); glVertex3f(-t1, 0.f, dx); glVertex3f(dx, 0.f, t1); glVertex3f(dx, 0.f, -t1); dx += display->gridsize; } glEnd(); glDisable(GL_LINE_STIPPLE); return; case VIEW_FRONT: viewh = display->view->viewpoint.x; viewv = display->view->viewpoint.y; break; case VIEW_RIGHT: viewh = display->view->viewpoint.z; viewv = display->view->viewpoint.y; break; case VIEW_TOP: viewh = display->view->viewpoint.x; viewv = display->view->viewpoint.z; break; } t1 = display->view->width/display->view->zoom*0.5f + 2*display->gridsize; t2 = display->view->height/display->view->zoom*0.5f+ 2*display->gridsize; dx = viewh - fmod(viewh, display->gridsize) - (t1 - fmod(t1, display->gridsize)); dy = viewv - fmod(viewv, display->gridsize) - (t2 - fmod(t2, display->gridsize)); delta = 0.f; t1 *= 2.f; t2 *= 2.f; switch (display->view->viewmode) { case VIEW_FRONT: glBegin(GL_LINES); while(delta < t1) { glVertex3f(dx+delta, dy, 0.f); glVertex3f(dx+delta, dy+t2, 0.f); delta += display->gridsize; } delta = 0.f; while(delta < t2) { glVertex3f(dx, dy+delta, 0.f); glVertex3f(dx+t1, dy+delta, 0.f); delta += display->gridsize; } glEnd(); glDisable(GL_LINE_STIPPLE); glBegin(GL_LINES); glVertex3f(0.f, dy, 0.f); glVertex3f(0.f, dy+t2, 0.f); glVertex3f(dx, 0.f, 0.f); glVertex3f(dx+t1, 0.f, 0.f); glEnd(); break; case VIEW_RIGHT: glBegin(GL_LINES); while(delta < t1) { glVertex3f(0.f, dy, dx+delta); glVertex3f(0.f, dy+t2, dx+delta); delta += display->gridsize; } delta = 0.f; while(delta < t2) { glVertex3f(0.f, dy+delta, dx); glVertex3f(0.f, dy+delta, dx+t1); delta += display->gridsize; } glEnd(); glDisable(GL_LINE_STIPPLE); glBegin(GL_LINES); glVertex3f(0.f, dy, 0.f); glVertex3f(0.f, dy+t2, 0.f); glVertex3f(0.f, 0.f, dx); glVertex3f(0.f, 0.f, dx+t1); glEnd(); break; case VIEW_TOP: glBegin(GL_LINES); while(delta < t1) { glVertex3f(dx+delta, 0.f, dy); glVertex3f(dx+delta, 0.f, dy+t2); delta += display->gridsize; } delta = 0.f; while(delta < t2) { glVertex3f(dx, 0.f, dy+delta); glVertex3f(dx+t1, 0.f, dy+delta); delta += display->gridsize; } glEnd(); glDisable(GL_LINE_STIPPLE); glBegin(GL_LINES); glVertex3f(0.f, 0.f, dy); glVertex3f(0.f, 0.f, dy+t2); glVertex3f(dx, 0.f, 0.f); glVertex3f(dx+t1, 0.f, 0.f); glEnd(); break; } }
void GOpenGLBoard::DoGroupEnd() { if (TargetMode() == G_CACHE_MODE) return; if ((TargetMode() == G_CLIP_MODE || TargetMode() == G_CLIP_AND_CACHE_MODE) && gIsFirstGroupDrawing == G_FALSE) { UpdateClipMasksState(); gClipMasksBoxes.push_back(gGroupBox); if (gTopStencilValue < gMaxTopStencilValue) { if (ClipOperation() == G_INTERSECTION_CLIP) gTopStencilValue++; else { // in the case of replace operation, gTopStencilValue has been already incremented by // the first drawing operation } } } gIsFirstGroupDrawing = G_FALSE; // if group opacity is not supported by hardware or group compositing operation is DST_OP or group is // empty just exit if (gGLGroupRect.IsEmpty || !gGroupOpacitySupport || GroupCompOp() == G_DST_OP) return; // DoGroupEnd() affects only color buffer if (TargetMode() == G_CACHE_MODE || TargetMode() == G_CLIP_MODE || TargetMode() == G_CLIP_AND_CACHE_MODE) return; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glDisable(GL_STENCIL_TEST); GrabFrameBuffer(gGLGroupRect.gNotExpandedLogicBox, gCompositingBuffer); // use SRC_OP just to disable blend and enable all 4 channels color mask ReplaceFrameBuffer(gGLGroupRect, G_SRC_OP, 0); glEnable(GL_STENCIL_TEST); if (ClipEnabled()) { gTopStencilValue++; glStencilFunc(GL_EQUAL, gTopStencilValue, gStencilMask); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); } else { glStencilFunc(GL_EQUAL, (GLint)(0x7FFFFFFF), gStencilDualMask); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); } if (GroupCompOp() == G_CLEAR_OP) { SELECT_AND_DISABLE_TUNIT(0) GLDisableShaders(); glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); SetGLColor(GVector4(0, 0, 0, 0)); DrawGLBox(gGLGroupRect.gExpandedLogicBox); } else { // simulate the drawing of a rectangle with GroupCompOp() and only fill GUInt32 stylePassesCount = 0; GUInt32 fbPassesCount = 0; CompOpPassesCount(GroupCompOp(), stylePassesCount, fbPassesCount); for (GUInt32 ii = 0; ii < stylePassesCount; ++ii) { UseGroupStyle(ii, gCompositingBuffer, gGLGroupRect); G_ASSERT(gCompositingBuffer.Width == gGLGroupRect.Width); G_ASSERT(gCompositingBuffer.Height == gGLGroupRect.Height); G_ASSERT(gCompositingBuffer.Target == gGLGroupRect.Target); DrawGrabbedRect(gCompositingBuffer, G_TRUE, G_TRUE, G_TRUE, G_FALSE); } for (GUInt32 ii = 0; ii < fbPassesCount; ++ii) ReplaceFrameBuffer(gGLGroupRect, GroupCompOp(), ii); } GLDisableShaders(); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); if (ClipEnabled()) { // delete stencil drawn pixels mask StencilPop(); DrawGLBox(gGLGroupRect.gExpandedLogicBox); // delete stencil bounding box mask StencilPop(); DrawGLBox(gGLGroupRect.gExpandedLogicBox); } else { glStencilFunc(GL_EQUAL, (GLint)(0x7FFFFFFF), gStencilDualMask); glStencilOp(GL_KEEP, GL_ZERO, GL_ZERO); glStencilMask(gStencilDualMask); DrawGLBox(gGLGroupRect.gExpandedLogicBox); } }
// Helper function: initialize the copper color to draw the board // in realistic mode. void EDA_3D_CANVAS::setGLCopperColor() { glDisable( GL_TEXTURE_2D ); SetGLColor( GetPrm3DVisu().m_CopperColor, 1.0 ); }
void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList, REPORTER* aErrorMessages, REPORTER* aActivity ) { BOARD* pcb = GetBoard(); // If FL_RENDER_SHOW_HOLES_IN_ZONES is true, holes are correctly removed from copper zones areas. // If FL_RENDER_SHOW_HOLES_IN_ZONES is false, holes are not removed from copper zones areas, // but the calculation time is twice shorter. bool remove_Holes = isEnabled( FL_RENDER_SHOW_HOLES_IN_ZONES ); bool realistic_mode = isRealisticMode(); bool useTextures = isRealisticMode() && isEnabled( FL_RENDER_TEXTURES ); // Number of segments to convert a circle to polygon // We use 2 values: the first gives a good shape (for instanes rond pads) // the second is used to speed up calculations, when a poor approximation is acceptable (holes) const int segcountforcircle = 18; double correctionFactor = 1.0 / cos( M_PI / (segcountforcircle * 2.0) ); const int segcountLowQuality = 12; // segments to draw a circle with low quality // to reduce time calculations // for holes and items which do not need // a fine representation double correctionFactorLQ = 1.0 / cos( M_PI / (segcountLowQuality * 2.0) ); SHAPE_POLY_SET bufferPolys; // copper areas: tracks, pads and filled zones areas // when holes are removed from zones SHAPE_POLY_SET bufferPcbOutlines; // stores the board main outlines SHAPE_POLY_SET bufferZonesPolys; // copper filled zones areas // when holes are not removed from zones SHAPE_POLY_SET currLayerHoles; // Contains holes for the current layer SHAPE_POLY_SET allLayerHoles; // Contains holes for all layers // Build a polygon from edge cut items wxString msg; if( !pcb->GetBoardPolygonOutlines( bufferPcbOutlines, allLayerHoles, &msg ) ) { if( aErrorMessages ) { msg << wxT("\n") << _("Unable to calculate the board outlines.\n" "Therefore use the board boundary box.") << wxT("\n\n"); aErrorMessages->Report( msg, REPORTER::RPT_WARNING ); } } // Build board holes, with optimization of large holes shape. buildBoardThroughHolesPolygonList( allLayerHoles, segcountLowQuality, true ); LSET cu_set = LSET::AllCuMask( GetPrm3DVisu().m_CopperLayersCount ); glNewList( aBoardList, GL_COMPILE ); for( LSEQ cu = cu_set.CuStack(); cu; ++cu ) { LAYER_ID layer = *cu; // Skip non enabled layers in normal mode, // and internal layers in realistic mode if( !is3DLayerEnabled( layer ) ) continue; if( aActivity ) aActivity->Report( wxString::Format( _( "Build layer %s" ), LSET::Name( layer ) ) ); bufferPolys.RemoveAllContours(); bufferZonesPolys.RemoveAllContours(); currLayerHoles.RemoveAllContours(); // Draw track shapes: for( TRACK* track = pcb->m_Track; track; track = track->Next() ) { if( !track->IsOnLayer( layer ) ) continue; track->TransformShapeWithClearanceToPolygon( bufferPolys, 0, segcountforcircle, correctionFactor ); // Add blind/buried via holes if( track->Type() == PCB_VIA_T ) { VIA *via = static_cast<VIA*>( track ); if( via->GetViaType() == VIA_THROUGH ) continue; // already done int holediameter = via->GetDrillValue(); int thickness = GetPrm3DVisu().GetCopperThicknessBIU(); int hole_outer_radius = (holediameter + thickness) / 2; TransformCircleToPolygon( currLayerHoles, via->GetStart(), hole_outer_radius, segcountLowQuality ); } } // draw pad shapes for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) { // Note: NPTH pads are not drawn on copper layers when the pad // has same shape as its hole module->TransformPadsShapesWithClearanceToPolygon( layer, bufferPolys, 0, segcountforcircle, correctionFactor, true ); // Micro-wave modules may have items on copper layers module->TransformGraphicShapesWithClearanceToPolygonSet( layer, bufferPolys, 0, segcountforcircle, correctionFactor ); // pad holes are already in list. } // Draw copper zones. Note: // * if the holes are removed from copper zones // the polygons are stored in bufferPolys (which contains all other polygons) // * if the holes are NOT removed from copper zones // the polygons are stored in bufferZonesPolys if( isEnabled( FL_ZONE ) ) { for( int ii = 0; ii < pcb->GetAreaCount(); ii++ ) { ZONE_CONTAINER* zone = pcb->GetArea( ii ); LAYER_NUM zonelayer = zone->GetLayer(); if( zonelayer == layer ) { zone->TransformSolidAreasShapesToPolygonSet( remove_Holes ? bufferPolys : bufferZonesPolys, segcountLowQuality, correctionFactorLQ ); } } } // draw graphic items on copper layers (texts) for( BOARD_ITEM* item = pcb->m_Drawings; item; item = item->Next() ) { if( !item->IsOnLayer( layer ) ) continue; switch( item->Type() ) { case PCB_LINE_T: // should not exist on copper layers ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( bufferPolys, 0, segcountforcircle, correctionFactor ); break; case PCB_TEXT_T: ( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet( bufferPolys, 0, segcountLowQuality, correctionFactor ); break; default: break; } } // bufferPolys contains polygons to merge. Many overlaps . // Calculate merged polygons if( bufferPolys.IsEmpty() ) continue; // Use Clipper lib to subtract holes to copper areas if( currLayerHoles.OutlineCount() ) { currLayerHoles.Append(allLayerHoles); currLayerHoles.Simplify(); bufferPolys.BooleanSubtract( currLayerHoles ); } else bufferPolys.BooleanSubtract( allLayerHoles ); int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer ); int zpos = GetPrm3DVisu().GetLayerZcoordBIU( layer ); float zNormal = 1.0f; // When using thickness it will draw first the top and then botton (with z inverted) // If we are not using thickness, then the z-normal has to match the layer direction // because just one plane will be drawn if( !thickness ) zNormal = Get3DLayer_Z_Orientation( layer ); if( realistic_mode ) { setGLCopperColor(); } else { EDA_COLOR_T color = g_ColorsSettings.GetLayerColor( layer ); SetGLColor( color ); } // If holes are removed from copper zones, bufferPolys contains all polygons // to draw (tracks+zones+texts). Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, thickness, GetPrm3DVisu().m_BiuTo3Dunits, useTextures, zNormal ); // If holes are not removed from copper zones (for calculation time reasons, // the zone polygons are stored in bufferZonesPolys and have to be drawn now: if( !bufferZonesPolys.IsEmpty() ) { Draw3D_SolidHorizontalPolyPolygons( bufferZonesPolys, zpos, thickness, GetPrm3DVisu().m_BiuTo3Dunits, useTextures, zNormal ); } } if( aActivity ) aActivity->Report( _( "Build board body" ) ); // Draw plated vertical holes inside the board, but not always. They are drawn: // - if the board body is not shown, to show the holes. // - or if the copper thickness is shown if( !isEnabled( FL_SHOW_BOARD_BODY ) || isEnabled( FL_USE_COPPER_THICKNESS ) ) { // Draw vias holes (vertical cylinders) for( const TRACK* track = pcb->m_Track; track; track = track->Next() ) { if( track->Type() == PCB_VIA_T ) { const VIA *via = static_cast<const VIA*>(track); draw3DViaHole( via ); } } // Draw pads holes (vertical cylinders) for( const MODULE* module = pcb->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) if( pad->GetAttribute () != PAD_HOLE_NOT_PLATED ) draw3DPadHole( pad ); } } glEndList(); // Build the body board: glNewList( aBodyOnlyList, GL_COMPILE ); if( isRealisticMode() ) { setGLEpoxyColor( 1.00 ); } else { EDA_COLOR_T color = g_ColorsSettings.GetLayerColor( Edge_Cuts ); SetGLColor( color, 0.7 ); } float copper_thickness = GetPrm3DVisu().GetCopperThicknessBIU(); // a small offset between substrate and external copper layer to avoid artifacts // when drawing copper items on board float epsilon = Millimeter2iu( 0.01 ); float zpos = GetPrm3DVisu().GetLayerZcoordBIU( B_Cu ); float board_thickness = GetPrm3DVisu().GetLayerZcoordBIU( F_Cu ) - GetPrm3DVisu().GetLayerZcoordBIU( B_Cu ); // items on copper layers and having a thickness = copper_thickness // are drawn from zpos - copper_thickness/2 to zpos + copper_thickness // therefore substrate position is copper_thickness/2 to // substrate_height - copper_thickness/2 zpos += (copper_thickness + epsilon) / 2.0f; board_thickness -= copper_thickness + epsilon; bufferPcbOutlines.BooleanSubtract( allLayerHoles ); if( !bufferPcbOutlines.IsEmpty() ) { Draw3D_SolidHorizontalPolyPolygons( bufferPcbOutlines, zpos + board_thickness / 2.0, board_thickness, GetPrm3DVisu().m_BiuTo3Dunits, useTextures, 1.0f ); } glEndList(); }
void EDA_3D_CANVAS::Redraw() { // SwapBuffer requires the window to be shown before calling if( !IsShownOnScreen() ) return; wxString err_messages; WX_STRING_REPORTER errorReporter( &err_messages ); STATUS_TEXT_REPORTER activityReporter( Parent(), 0 ); // Display build time at the end of build unsigned strtime = GetRunningMicroSecs(); GL_CONTEXT_MANAGER::Get().LockCtx( m_glRC, this ); // Set the OpenGL viewport according to the client size of this canvas. // This is done here rather than in a wxSizeEvent handler because our // OpenGL rendering context (and thus viewport setting) is used with // multiple canvases: If we updated the viewport in the wxSizeEvent // handler, changing the size of one canvas causes a viewport setting that // is wrong when next another canvas is repainted. wxSize size = GetClientSize(); InitGL(); if( isRealisticMode() && isEnabled( FL_RENDER_SHADOWS ) ) { generateFakeShadowsTextures( &errorReporter, &activityReporter ); } // *MUST* be called *after* GL_CONTEXT_MANAGER::LockCtx(): glViewport( 0, 0, size.x, size.y ); // clear color and depth buffers glClearColor( 0.95, 0.95, 1.0, 1.0 ); glClearStencil( 0 ); glClearDepth( 1.0 ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); glShadeModel( GL_SMOOTH ); // Draw background glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glDisable( GL_LIGHTING ); glDisable( GL_COLOR_MATERIAL ); glDisable( GL_DEPTH_TEST ); glDisable( GL_TEXTURE_2D ); // Draw the background ( rectangle with color gradient) glBegin( GL_QUADS ); SetGLColor( GetPrm3DVisu().m_BgColor_Top, 1.0 ); glVertex2f( -1.0, 1.0 ); // Top left corner SetGLColor( GetPrm3DVisu().m_BgColor, 1.0 ); glVertex2f( -1.0,-1.0 ); // bottom left corner glVertex2f( 1.0,-1.0 ); // bottom right corner SetGLColor( GetPrm3DVisu().m_BgColor_Top, 1.0 ); glVertex2f( 1.0, 1.0 ); // top right corner glEnd(); glEnable( GL_DEPTH_TEST ); // set viewing projection glMatrixMode( GL_PROJECTION ); glLoadIdentity(); #define MAX_VIEW_ANGLE 160.0 / 45.0 if( GetPrm3DVisu().m_Zoom > MAX_VIEW_ANGLE ) GetPrm3DVisu().m_Zoom = MAX_VIEW_ANGLE; if( Parent()->ModeIsOrtho() ) { // OrthoReductionFactor is chosen to provide roughly the same size as // Perspective View const double orthoReductionFactor = 400 / GetPrm3DVisu().m_Zoom; // Initialize Projection Matrix for Ortographic View glOrtho( -size.x / orthoReductionFactor, size.x / orthoReductionFactor, -size.y / orthoReductionFactor, size.y / orthoReductionFactor, 1, 100 ); } else { // Ratio width / height of the window display double ratio_HV = (double) size.x / size.y; // Initialize Projection Matrix for Perspective View gluPerspective( 45.0f * GetPrm3DVisu().m_Zoom, ratio_HV, 1, 100 ); } // position viewer glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( 0.0f, 0.0f, -(m_ZBottom + m_ZTop) / 2.0f ); // Setup light sources: SetLights(); CheckGLError( __FILE__, __LINE__ ); glMatrixMode( GL_MODELVIEW ); // position viewer // transformations GLfloat mat[4][4]; // Translate motion first, so rotations don't mess up the orientation... glTranslatef( m_draw3dOffset.x, m_draw3dOffset.y, 0.0F ); build_rotmatrix( mat, GetPrm3DVisu().m_Quat ); glMultMatrixf( &mat[0][0] ); glRotatef( GetPrm3DVisu().m_Rot[0], 1.0, 0.0, 0.0 ); glRotatef( GetPrm3DVisu().m_Rot[1], 0.0, 1.0, 0.0 ); glRotatef( GetPrm3DVisu().m_Rot[2], 0.0, 0.0, 1.0 ); if( ! m_glLists[GL_ID_BOARD] || ! m_glLists[GL_ID_TECH_LAYERS] ) CreateDrawGL_List( &errorReporter, &activityReporter ); if( isEnabled( FL_AXIS ) && m_glLists[GL_ID_AXIS] ) glCallList( m_glLists[GL_ID_AXIS] ); // move the board in order to draw it with its center at 0,0 3D coordinates glTranslatef( -GetPrm3DVisu().m_BoardPos.x * GetPrm3DVisu().m_BiuTo3Dunits, -GetPrm3DVisu().m_BoardPos.y * GetPrm3DVisu().m_BiuTo3Dunits, 0.0f ); if( isEnabled( FL_MODULE ) ) { if( ! m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] ) CreateDrawGL_List( &errorReporter, &activityReporter ); } glEnable( GL_LIGHTING ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); if( isRealisticMode() && isEnabled( FL_RENDER_TEXTURES ) ) glEnable( GL_TEXTURE_2D ); else glDisable( GL_TEXTURE_2D ); // Set material for the board glEnable( GL_COLOR_MATERIAL ); SetOpenGlDefaultMaterial(); //glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, FALSE ); // Board Body GLint shininess_value = 32; glMateriali( GL_FRONT_AND_BACK, GL_SHININESS, shininess_value ); if( isEnabled( FL_SHOW_BOARD_BODY ) ) { if( m_glLists[GL_ID_BODY] ) { glCallList( m_glLists[GL_ID_BODY] ); } } // Board // specify material parameters for the lighting model. shininess_value = 52; glMateriali( GL_FRONT_AND_BACK, GL_SHININESS, shininess_value ); glm::vec4 specular( GetPrm3DVisu().m_CopperColor.m_Red * 0.20f, GetPrm3DVisu().m_CopperColor.m_Green * 0.20f, GetPrm3DVisu().m_CopperColor.m_Blue * 0.20f, 1.0f ); glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.x ); if( m_glLists[GL_ID_BOARD] ) { glCallList( m_glLists[GL_ID_BOARD] ); } // Tech layers shininess_value = 32; glMateriali( GL_FRONT_AND_BACK, GL_SHININESS, shininess_value ); glm::vec4 specularTech( 0.0f, 0.0f, 0.0f, 1.0f ); glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specularTech.x ); if( m_glLists[GL_ID_TECH_LAYERS] ) { glCallList( m_glLists[GL_ID_TECH_LAYERS] ); } if( isEnabled( FL_COMMENTS ) || isEnabled( FL_ECO ) ) { if( ! m_glLists[GL_ID_AUX_LAYERS] ) CreateDrawGL_List( &errorReporter, &activityReporter ); glCallList( m_glLists[GL_ID_AUX_LAYERS] ); } //glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, TRUE ); // Draw Component Shadow if( isEnabled( FL_MODULE ) && isRealisticMode() && isEnabled( FL_RENDER_SHADOWS ) ) { glEnable( GL_CULL_FACE ); glDisable( GL_DEPTH_TEST ); glEnable( GL_COLOR_MATERIAL ) ; SetOpenGlDefaultMaterial(); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glEnable( GL_TEXTURE_2D ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); if( m_glLists[GL_ID_SHADOW_FRONT] ) { glBindTexture( GL_TEXTURE_2D, m_text_fake_shadow_front ); glCallList( m_glLists[GL_ID_SHADOW_FRONT] ); } if( m_glLists[GL_ID_SHADOW_BACK] ) { glBindTexture( GL_TEXTURE_2D, m_text_fake_shadow_back ); glCallList( m_glLists[GL_ID_SHADOW_BACK] ); } glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glEnable( GL_DEPTH_TEST ); glDisable( GL_TEXTURE_2D ); glDisable( GL_CULL_FACE ); } glEnable( GL_COLOR_MATERIAL ); SetOpenGlDefaultMaterial(); glDisable( GL_BLEND ); // Draw Solid Shapes if( isEnabled( FL_MODULE ) ) { if( ! m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] ) CreateDrawGL_List( &errorReporter, &activityReporter ); glCallList( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] ); } glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // Grid uses transparency: draw it after all objects if( isEnabled( FL_GRID ) ) { if( ! m_glLists[GL_ID_GRID] ) CreateDrawGL_List( &errorReporter, &activityReporter ); glCallList( m_glLists[GL_ID_GRID] ); } // Draw Board Shadow if( isRealisticMode() && isEnabled( FL_RENDER_SHADOWS ) ) { if( m_glLists[GL_ID_SHADOW_BOARD] ) { glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glColor4f( 1.0, 1.0, 1.0, 0.75f ); glEnable( GL_CULL_FACE ); glDisable( GL_COLOR_MATERIAL ); glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, m_text_fake_shadow_board ); glCallList( m_glLists[GL_ID_SHADOW_BOARD] ); glDisable( GL_CULL_FACE ); glDisable( GL_TEXTURE_2D ); } } // This list must be drawn last, because it contains the // transparent gl objects, which should be drawn after all // non transparent objects if( isEnabled( FL_MODULE ) && m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] ) { glEnable( GL_COLOR_MATERIAL ); SetOpenGlDefaultMaterial(); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] ); } // Debug bounding boxes /* glDisable( GL_BLEND ); glDisable( GL_COLOR_MATERIAL ); glDisable( GL_LIGHTING ); glColor4f( 1.0f, 0.0f, 1.0f, 1.0f ); m_fastAABBox_Shadow.GLdebug(); glColor4f( 0.0f, 1.0f, 1.0f, 1.0f ); m_boardAABBox.GLdebug(); */ SwapBuffers(); GL_CONTEXT_MANAGER::Get().UnlockCtx( m_glRC ); // Show calculation time if some activity was reported if( activityReporter.HasMessage() ) { // Calculation time in seconds double calculation_time = (double)( GetRunningMicroSecs() - strtime) / 1e6; activityReporter.Report( wxString::Format( _( "Build time %.3f s" ), calculation_time ) ); } else activityReporter.Report( wxEmptyString ); if( !err_messages.IsEmpty() ) wxLogMessage( err_messages ); }