diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index df9bbb1fd2..b139e5864b 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -538,26 +538,19 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment ) SetGLColor( color ); - double w = segment->GetWidth() * g_Parm_3D_Visu.m_BiuTo3Dunits; - double x = segment->GetStart().x * g_Parm_3D_Visu.m_BiuTo3Dunits; - double y = segment->GetStart().y * g_Parm_3D_Visu.m_BiuTo3Dunits; - double xf = segment->GetEnd().x * g_Parm_3D_Visu.m_BiuTo3Dunits; - double yf = segment->GetEnd().y * g_Parm_3D_Visu.m_BiuTo3Dunits; - if( layer == EDGE_N ) { for( layer = 0; layer < g_Parm_3D_Visu.m_CopperLayersCount; layer++ ) { glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 ); - double zpos = g_Parm_3D_Visu.m_LayerZcoord[layer]; + int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU(layer); switch( segment->GetShape() ) { case S_ARC: - { - S3D_VERTEX pos( xf, -yf, zpos ); - Draw3D_ArcSegment( pos, x, -y, segment->GetAngle(), w ); - } + Draw3D_ArcSegment( segment->GetCenter(), segment->GetArcStart(), + segment->GetAngle(), segment->GetWidth(), thickness, + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); break; case S_CIRCLE: @@ -567,16 +560,14 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment ) ); Draw3D_ZaxisCylinder( segment->GetStart(), radius, thickness, segment->GetWidth(), - g_Parm_3D_Visu.GetLayerZcoordBIU(layer), - g_Parm_3D_Visu.m_BiuTo3Dunits ); + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); } break; default: Draw3D_SolidSegment( segment->GetStart(), segment->GetEnd(), segment->GetWidth(), thickness, - g_Parm_3D_Visu.GetLayerZcoordBIU(layer), - g_Parm_3D_Visu.m_BiuTo3Dunits ); + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); break; } } @@ -584,17 +575,16 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment ) else { glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); - double zpos = g_Parm_3D_Visu.m_LayerZcoord[layer]; + int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU(layer); if( Is3DLayerEnabled( layer ) ) { switch( segment->GetShape() ) { case S_ARC: - { - S3D_VERTEX pos( xf, -yf, zpos ); - Draw3D_ArcSegment( pos, x, -y, segment->GetAngle(), w ); - } + Draw3D_ArcSegment( segment->GetCenter(), segment->GetArcStart(), + segment->GetAngle(), segment->GetWidth(), thickness, + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); break; case S_CIRCLE: @@ -604,16 +594,14 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment ) ); Draw3D_ZaxisCylinder( segment->GetStart(), radius, thickness, segment->GetWidth(), - g_Parm_3D_Visu.GetLayerZcoordBIU(layer), - g_Parm_3D_Visu.m_BiuTo3Dunits ); + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); } break; default: Draw3D_SolidSegment( segment->GetStart(), segment->GetEnd(), segment->GetWidth(), thickness, - g_Parm_3D_Visu.GetLayerZcoordBIU(layer), - g_Parm_3D_Visu.m_BiuTo3Dunits ); + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); break; } } @@ -758,32 +746,18 @@ void MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) { - wxString s; - int dx, dy; - double x, y, fx, fy, w; - if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( m_Layer ) == false ) return; int color = g_ColorsSettings.GetLayerColor( m_Layer ); - SetGLColor( color ); - dx = m_End.x; - dy = m_End.y; - w = m_Width * g_Parm_3D_Visu.m_BiuTo3Dunits; - x = m_Start.x * g_Parm_3D_Visu.m_BiuTo3Dunits; - y = m_Start.y * g_Parm_3D_Visu.m_BiuTo3Dunits; - fx = dx * g_Parm_3D_Visu.m_BiuTo3Dunits; - fy = dy * g_Parm_3D_Visu.m_BiuTo3Dunits; - - if( m_Layer == EDGE_N ) { for( int layer = 0; layer < g_Parm_3D_Visu.m_CopperLayersCount; layer++ ) { glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 ); - int izpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer ); + int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer ); int thickness = m_Layer >= FIRST_NO_COPPER_LAYER ? g_Parm_3D_Visu.GetNonCopperLayerThicknessBIU() : g_Parm_3D_Visu.GetCopperThicknessBIU(); @@ -792,7 +766,7 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) { case S_SEGMENT: Draw3D_SolidSegment( m_Start, m_End, m_Width, - thickness, izpos, + thickness, zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); break; @@ -803,16 +777,14 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) ); Draw3D_ZaxisCylinder( m_Start, radius, thickness, GetWidth(), - g_Parm_3D_Visu.GetLayerZcoordBIU(layer), - g_Parm_3D_Visu.m_BiuTo3Dunits ); + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); } break; case S_ARC: - { - S3D_VERTEX pos( fx, -fy, g_Parm_3D_Visu.m_LayerZcoord[layer] ); - Draw3D_ArcSegment( pos, x, -y, (double) m_Angle, w ); - } + Draw3D_ArcSegment( GetCenter(), GetArcStart(), + GetAngle(), GetWidth(), thickness, + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); break; case S_POLYGON: @@ -833,13 +805,12 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) pt += module->m_Pos; } - Draw3D_HorizontalPolygon( points, izpos, 0, g_Parm_3D_Visu.m_BiuTo3Dunits); + Draw3D_HorizontalPolygon( points, zpos, 0, g_Parm_3D_Visu.m_BiuTo3Dunits); } break; default: - s.Printf( wxT( "Error: Shape nr %d not implemented!\n" ), m_Shape ); - D( printf( "%s", TO_UTF8( s ) ); ) + D( printf( "Error: Shape nr %d not implemented!\n", m_Shape ); ) break; } } @@ -850,13 +821,13 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) g_Parm_3D_Visu.GetNonCopperLayerThicknessBIU() : g_Parm_3D_Visu.GetCopperThicknessBIU(); glNormal3f( 0.0, 0.0, (m_Layer == LAYER_N_BACK) ? -1.0 : 1.0 ); - int izpos = g_Parm_3D_Visu.GetLayerZcoordBIU(m_Layer); + int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU(m_Layer); switch( m_Shape ) { case S_SEGMENT: Draw3D_SolidSegment( m_Start, m_End, m_Width, - thickness, izpos, + thickness, zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); break; @@ -867,16 +838,14 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) ); Draw3D_ZaxisCylinder( m_Start, radius, thickness, GetWidth(), - g_Parm_3D_Visu.GetLayerZcoordBIU(m_Layer), - g_Parm_3D_Visu.m_BiuTo3Dunits ); + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); } break; case S_ARC: - { - S3D_VERTEX pos( fx, -fy, g_Parm_3D_Visu.m_LayerZcoord[m_Layer] ); - Draw3D_ArcSegment( pos, x, -y, (double) m_Angle, w ); - } + Draw3D_ArcSegment( GetCenter(), GetArcStart(), + GetAngle(), GetWidth(), thickness, + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); break; case S_POLYGON: @@ -897,13 +866,12 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) pt += module->m_Pos; } - Draw3D_HorizontalPolygon( points, izpos, 0, g_Parm_3D_Visu.m_BiuTo3Dunits ); + Draw3D_HorizontalPolygon( points, zpos, 0, g_Parm_3D_Visu.m_BiuTo3Dunits ); } break; default: - s.Printf( wxT( "Error: Shape nr %d not implemented!\n" ), m_Shape ); - D( printf( "%s", TO_UTF8( s ) ); ) + D( printf( "Error: Shape nr %d not implemented!\n", m_Shape ); ) break; } } diff --git a/3d-viewer/3d_draw_basic_functions.cpp b/3d-viewer/3d_draw_basic_functions.cpp index 0680745a63..b4c92e7a5f 100644 --- a/3d-viewer/3d_draw_basic_functions.cpp +++ b/3d-viewer/3d_draw_basic_functions.cpp @@ -39,6 +39,8 @@ extern void Set_Object_Data( std::vector& aVertices, double aBiuTo3DUnits ); extern void CheckGLError(); +// Number of segments to approximate a circle by segments +#define SEGM_PER_CIRCLE 16 #ifndef CALLBACK #define CALLBACK @@ -210,11 +212,11 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius, int aHeight, int aThickness, int aZpos, double aBiuTo3DUnits ) { - const int slice = 12; + const int slice = SEGM_PER_CIRCLE; std::vector outer_cornerBuffer; TransformCircleToPolygon( outer_cornerBuffer, aCenterPos, - aRadius + (aThickness / 2), slice ); + aRadius + (aThickness / 2), SEGM_PER_CIRCLE ); std::vector coords; coords.resize( 4 ); @@ -229,11 +231,11 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius, coords[2].z = coords[1].z; coords[3].z = coords[0].z; - for( int ii = 0; ii < slice; ii++ ) + for( unsigned ii = 0; ii < outer_cornerBuffer.size(); ii++ ) { - int jj = ii + 1; + unsigned jj = ii + 1; - if( jj >= slice ) + if( jj >= outer_cornerBuffer.size() ) jj = 0; // Build the 4 vertices of each GL_QUAD @@ -277,11 +279,11 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius, TransformCircleToPolygon( inner_cornerBuffer, aCenterPos, aRadius - (aThickness / 2), slice ); - for( int ii = 0; ii < slice; ii++ ) + for( unsigned ii = 0; ii < inner_cornerBuffer.size(); ii++ ) { - int jj = ii + 1; + unsigned jj = ii + 1; - if( jj >= slice ) + if( jj >= inner_cornerBuffer.size() ) jj = 0; // Build the 4 vertices of each GL_QUAD @@ -311,7 +313,7 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos, int aRadius, int aHeight, int aThickness, int aZpos, double aBiuTo3DUnits ) { - const int slice = 12; + const int slice = SEGM_PER_CIRCLE; // Build the points to approximate oblong cylinder by segments std::vector cornerBuffer; @@ -329,11 +331,11 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos, coords[2].z = coords[1].z; coords[3].z = coords[0].z; - for( int ii = 0; ii < slice; ii++ ) + for( unsigned ii = 0; ii < cornerBuffer.size(); ii++ ) { - int jj = ii + 1; + unsigned jj = ii + 1; - if( jj >= slice ) + if( jj >= cornerBuffer.size() ) jj = 0; // Build the 4 vertices of each GL_QUAD @@ -363,7 +365,7 @@ void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd, int aWidth, int aThickness, int aZpos, double aBiuTo3DUnits ) { std::vector cornerBuffer; - const int slice = 16; + const int slice = SEGM_PER_CIRCLE; TransformRoundedEndsSegmentToPolygon( cornerBuffer, aStart, aEnd, slice, aWidth ); @@ -371,49 +373,18 @@ void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd, } -void Draw3D_ArcSegment( const S3D_VERTEX& aCenterPos, - double aStartPointX, double aStartPointY, - double aArcAngle, double aWidth ) +void Draw3D_ArcSegment( const wxPoint& aCenterPos, const wxPoint& aStartPoint, + int aArcAngle, int aWidth, int aThickness, + int aZpos, double aBiuTo3DUnits ) { - const int slice = 16; // Number of segments to approximate a circle by segments - double arcStart_Angle; + const int slice = SEGM_PER_CIRCLE; - arcStart_Angle = - (atan2( aStartPointX - aCenterPos.x, aStartPointY - aCenterPos.y ) * 1800 / M_PI ); - double radius = hypot( aStartPointX - aCenterPos.x, aStartPointY - aCenterPos.y ) - + ( aWidth / 2); - double hole = radius - aWidth; + std::vector cornerBuffer; + TransformArcToPolygon( cornerBuffer, aCenterPos, aStartPoint, aArcAngle, + slice, aWidth ); - // Calculate the number of segments to approximate this arc - int imax = (int) ( (double) aArcAngle / ANGLE_INC( slice ) ); + Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos, aThickness, aBiuTo3DUnits ); - if( imax < 0 ) - imax = -imax; - - if( imax == 0 ) - imax = 1; - - // Adjust delta_angle to have exactly imax segments in arc_angle - // i.e. arc_angle = imax delta_agnle. - double delta_angle = (double) aArcAngle / imax; - - glBegin( GL_QUAD_STRIP ); - - for( int ii = 0; ii <= imax; ii++ ) - { - double angle = (double) ii * delta_angle; - angle += arcStart_Angle + 900; - double dx = hole; - double dy = 0.0; - RotatePoint( &dx, &dy, (int) angle ); - glVertex3f( dx + aStartPointX, dy + aStartPointY, aCenterPos.z ); - dx = radius; - dy = 0.0; - RotatePoint( &dx, &dy, (int) angle ); - glVertex3f( dx + aStartPointX, dy + aStartPointY, aCenterPos.z ); - } - - glEnd(); } @@ -427,7 +398,7 @@ void Draw3D_ArcSegment( const S3D_VERTEX& aCenterPos, void Draw3D_FlatRing( wxPoint aCenterPos, int aOuterRadius, int aInnerRadius, int aZpos, double aBiuTo3DUnits ) { - const int slice = 16; + const int slice = SEGM_PER_CIRCLE; const int rot_angle = ANGLE_INC( slice ); double cposx = aCenterPos.x * aBiuTo3DUnits; double cposy = - aCenterPos.y * aBiuTo3DUnits; @@ -518,13 +489,11 @@ void Draw3D_HorizontalPolygon( std::vector& aCornersList, int aZpos, vertices[2].z = vertices[1].z; vertices[3].z = vertices[0].z; - int slice = (int) aCornersList.size(); - - for( int ii = 0; ii < slice; ii++ ) + for( unsigned ii = 0; ii < aCornersList.size(); ii++ ) { - int jj = ii + 1; + unsigned jj = ii + 1; - if( jj >=slice ) + if( jj >=aCornersList.size() ) jj = 0; vertices[0].x = aCornersList[ii].x; diff --git a/3d-viewer/3d_draw_basic_functions.h b/3d-viewer/3d_draw_basic_functions.h index 8ec8550e8a..f31534e0fa 100644 --- a/3d-viewer/3d_draw_basic_functions.h +++ b/3d-viewer/3d_draw_basic_functions.h @@ -80,6 +80,7 @@ void Draw3D_SolidHorizontalPolygonWithHoles( const std::vector& aPol * @param aWidth = width of segment in board units * @param aThickness = thickness of segment in board units * @param aZpos = z position of segment in board units + * @param aBiuTo3DUnits = board internal units to 3D units scaling value * If aThickness = 0, a polygon area is drawn in a XY plane at Z position = aZpos. * If aThickness 1 0, a solid object is drawn. * The top side is located at aZpos + aThickness / 2 @@ -89,16 +90,19 @@ void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd, int aWidth, int aThickness, int aZpos, double aBiuTo3DUnits ); -/** draw an arc using 3D primitives, in a plane parallel to the XY plane - * @param aCenterPos = 3D position of the center - * @param aStartPointX, aStartPointY = start point coordinate of arc (3D units) - * @param aWidth = width of the circle (3D units) +/** draw an arc using 3D primitives, in a XY plane + * @param aCenterPos = XY position of the center in board units + * @param aStartPoint = start point coordinate of arc in board units + * @param aWidth = width of the circle in board units * @param aArcAngle = arc angle in 1/10 degrees * @param aWidth = thickness of arc + * @param aThickness = thickness of segment in board units + * @param aZpos = z position of segment in board units + * @param aBiuTo3DUnits = board internal units to 3D units scaling value */ -void Draw3D_ArcSegment( const S3D_VERTEX& aCenterPos, - double aStartPointX, double aStartPointY, - double aArcAngle, double aWidth ); +void Draw3D_ArcSegment( const wxPoint& aCenterPos, const wxPoint& aStartPoint, + int aArcAngle, int aWidth, int aThickness, + int aZpos, double aBiuTo3DUnits ); /** draw a thick cylinder (a tube) using 3D primitives.