Commit 31ff1bac authored by jean-pierre charras's avatar jean-pierre charras
Browse files

3D viewer:

  *  serious code cleanup (remove duplicate code)
  *  shows (option in 3D preference menu) the copper items (tracks, zones...)  in 3D, using 35 microns copper thickness.
      However, because there are a lot more3D data to show (roughly 4 times more), this is slower.
parent 0c4c65d7
Loading
Loading
Loading
Loading
+7 −33
Original line number Original line Diff line number Diff line
@@ -44,6 +44,9 @@
#include <info3d_visu.h>
#include <info3d_visu.h>
#include <trackball.h>
#include <trackball.h>


// Exported function:
void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits );



void S3D_MASTER::Set_Object_Coords( std::vector< S3D_VERTEX >& aVertices )
void S3D_MASTER::Set_Object_Coords( std::vector< S3D_VERTEX >& aVertices )
{
{
@@ -75,7 +78,7 @@ void S3D_MASTER::Set_Object_Coords( std::vector< S3D_VERTEX >& aVertices )
}
}




void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices )
void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits )
{
{
    unsigned ii;
    unsigned ii;
    GLfloat ax, ay, az, bx, by, bz, nx, ny, nz, r;
    GLfloat ax, ay, az, bx, by, bz, nx, ny, nz, r;
@@ -126,9 +129,9 @@ void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices )
    /* draw polygon/triangle/quad */
    /* draw polygon/triangle/quad */
    for( ii = 0; ii < aVertices.size(); ii++ )
    for( ii = 0; ii < aVertices.size(); ii++ )
    {
    {
        glVertex3f( aVertices[ii].x * DataScale3D,
        glVertex3f( aVertices[ii].x * aBiuTo3DUnits,
                    aVertices[ii].y * DataScale3D,
                    aVertices[ii].y * aBiuTo3DUnits,
                    aVertices[ii].z * DataScale3D );
                    aVertices[ii].z * aBiuTo3DUnits );
    }
    }


    glEnd();
    glEnd();
@@ -172,35 +175,6 @@ GLuint EDA_3D_CANVAS::DisplayCubeforTest()
    return gllist;
    return gllist;
}
}



INFO3D_VISU::INFO3D_VISU()
{
    int ii;

    m_Beginx = m_Beginy = 0.0;      // position of mouse
    m_Zoom   = 1.0;
    m_3D_Grid = 10.0;               // Grid value in mm
    trackball( m_Quat, 0.0, 0.0, 0.0, 0.0 );

    for( ii = 0; ii < 4; ii++ )
        m_Rot[ii] = 0.0;

    m_CopperLayersCount = 2;
    m_BoardSettings  = NULL;

    // default all special item layers Visible
    for( ii = 0; ii < FL_LAST; ii++)
        m_DrawFlags[ii] = true;

    m_DrawFlags[FL_GRID] = false;
}


INFO3D_VISU::~INFO3D_VISU()
{
}


VERTEX_VALUE_CTRL::VERTEX_VALUE_CTRL( wxWindow* parent, const wxString& title,
VERTEX_VALUE_CTRL::VERTEX_VALUE_CTRL( wxWindow* parent, const wxString& title,
                                      wxBoxSizer* BoxSizer )
                                      wxBoxSizer* BoxSizer )
{
{
+223 −922

File changed.

Preview size limit exceeded, changes collapsed.

+591 −0
Original line number Original line Diff line number Diff line
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
 * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you may find one here:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * or you may search the http://www.gnu.org website for the version 2 license,
 * or you may write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */

/**
 * @file 3d_draw_basic_functions.cpp
 */

#include <fctsys.h>
#include <trigo.h>
#include <convert_basic_shapes_to_polygon.h>

#include <3d_viewer.h>
#include <info3d_visu.h>
#include <3d_draw_basic_functions.h>


// Imported function:
extern void Set_Object_Data( std::vector<S3D_VERTEX>& aVertices, double aBiuTo3DUnits );
extern void CheckGLError();


#ifndef CALLBACK
#define CALLBACK
#endif

// CALLBACK functions for GLU_TESS
static void CALLBACK    tessBeginCB( GLenum which );
static void CALLBACK    tessEndCB();
static void CALLBACK    tessErrorCB( GLenum errorCode );
static void CALLBACK    tessCPolyPt2Vertex( const GLvoid* data );
static void CALLBACK    tesswxPoint2Vertex( const GLvoid* data );

/** draw a ring using 3D primitives, in a plane parallel to the XY plane
 * @param aCenterPos = position of the center (Board internal units)
 * @param aOuterRadius = radius of the external circle (Board internal units)
 * @param aInnerRadius = radius of the circle (Board internal units)
 * @param aZpos = z position in board internal units
 * @param aBiuTo3DUnits = board internal units to 3D units scaling value
 */
static void             Draw3D_FlatRing( wxPoint aCenterPos, int aOuterRadius,
                                     int aInnerRadius, int aZpos, double aBiuTo3DUnits );


void SetGLColor( int color )
{
    double          red, green, blue;
    StructColors    colordata = ColorRefs[color & MASKCOLOR];

    red     = colordata.m_Red / 255.0;
    blue    = colordata.m_Blue / 255.0;
    green   = colordata.m_Green / 255.0;
    glColor3f( red, green, blue );
}


/* draw all solid polygons found in aPolysList
 * aZpos = z position in board internal units
 * aThickness = thickness in board internal units
 * 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
 *  The bottom side is located at aZpos - aThickness / 2
 */
void Draw3D_SolidHorizontalPolyPolygons( const std::vector<CPolyPt>& aPolysList,
                                         int aZpos, int aThickness, double aBiuTo3DUnits )
{
    GLUtesselator* tess = gluNewTess();

    gluTessCallback( tess, GLU_TESS_BEGIN, ( void (CALLBACK*) () )tessBeginCB );
    gluTessCallback( tess, GLU_TESS_END, ( void (CALLBACK*) () )tessEndCB );
    gluTessCallback( tess, GLU_TESS_ERROR, ( void (CALLBACK*) () )tessErrorCB );
    gluTessCallback( tess, GLU_TESS_VERTEX, ( void (CALLBACK*) () )tessCPolyPt2Vertex );

    GLdouble    v_data[3];
    double      zpos = ( aZpos + (aThickness / 2) ) * aBiuTo3DUnits;
    g_Parm_3D_Visu.m_CurrentZpos = zpos;
    v_data[2] = aZpos + (aThickness / 2);

    // Set normal to toward positive Z axis, for a solid object only (to draw the top side)
    if( aThickness )
        glNormal3f( 0.0, 0.0, 1.0 );

    // gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);

    // Draw solid areas contained in this list
    std::vector<CPolyPt> polylist = aPolysList;    // temporary copy for gluTessVertex

    for( int side = 0; side < 2; side++ )
    {
        int startContour = 1;

        for( unsigned ii = 0; ii < polylist.size(); ii++ )
        {
            if( startContour == 1 )
            {
                gluTessBeginPolygon( tess, NULL );
                gluTessBeginContour( tess );
                startContour = 0;
            }

            v_data[0]   = polylist[ii].x * aBiuTo3DUnits;
            v_data[1]   = -polylist[ii].y * aBiuTo3DUnits;
            // gluTessVertex store pointers on data, not data, so do not store
            // different corners values in a temporary variable
            // but send pointer on each CPolyPt value in polylist
            // before calling gluDeleteTess
            gluTessVertex( tess, v_data, &polylist[ii] );

            if( polylist[ii].end_contour == 1 )
            {
                gluTessEndContour( tess );
                gluTessEndPolygon( tess );
                startContour = 1;
            }
        }

        if( aThickness == 0 )
            break;

        // Prepare the bottom side of solid areas
        zpos = ( aZpos - (aThickness / 2) ) * aBiuTo3DUnits;
        g_Parm_3D_Visu.m_CurrentZpos = zpos;
        v_data[2] = zpos;
        // Now;, set normal to toward negative Z axis, for the solid object bottom side
        glNormal3f( 0.0, 0.0, -1.0 );
    }

    gluDeleteTess( tess );

    if( aThickness == 0 )
        return;

    // Build the 3D data : vertical sides
    std::vector<S3D_VERTEX> vertices;
    vertices.resize( 4 );

    vertices[0].z   = aZpos + (aThickness / 2);
    vertices[1].z   = aZpos - (aThickness / 2);
    vertices[2].z   = vertices[1].z;
    vertices[3].z   = vertices[0].z;

    int startContour = 0;
    for( unsigned ii = 0; ii < polylist.size(); ii++ )
    {
        int jj = ii + 1;

        if( polylist[ii].end_contour == 1 )
        {
            jj = startContour;
            startContour = ii + 1;
        }

        vertices[0].x   = polylist[ii].x;
        vertices[0].y   = -polylist[ii].y;
        vertices[1].x   = vertices[0].x;
        vertices[1].y   = vertices[0].y;    // Z only changes.
        vertices[2].x   = polylist[jj].x;
        vertices[2].y   = -polylist[jj].y;
        vertices[3].x   = vertices[2].x;
        vertices[3].y   = vertices[2].y;    // Z only changes.

        Set_Object_Data( vertices, aBiuTo3DUnits );
    }

    glNormal3f( 0.0, 0.0, 1.0 );
}


/* draw the solid polygon found in aPolysList
 * The first polygonj is the main polygon, others are holes
 * See Draw3D_SolidHorizontalPolyPolygons for more info
 */
void Draw3D_SolidHorizontalPolygonWithHoles( const std::vector<CPolyPt>& aPolysList,
                                             int aZpos, int aThickness, double aBiuTo3DUnits )
{
    std::vector<CPolyPt> polygon;

    ConvertPolysListWithHolesToOnePolygon( aPolysList, polygon );
    Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, aThickness, aBiuTo3DUnits );
}


/* draw a cylinder (a tube) using 3D primitives.
 * the cylinder axis is parallel to the Z axis
 * If aHeight = height of the cylinder is 0, only one ring will be drawn
 * If aThickness = 0, only one cylinder will be drawn
 */
void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
                           int aHeight, int aThickness,
                           int aZpos, double aBiuTo3DUnits )
{
    const int slice = 12;
    std::vector <CPolyPt> outer_cornerBuffer;

    TransformCircleToPolygon( outer_cornerBuffer, aCenterPos,
                              aRadius + (aThickness / 2), slice );

    std::vector<S3D_VERTEX> coords;
    coords.resize( 4 );

    if( aHeight )
    {
        // Draw the outer vertical side

        // Init Z position of the 4 points of a GL_QUAD
        coords[0].z = aZpos;
        coords[1].z = aZpos + aHeight;
        coords[2].z = coords[1].z;
        coords[3].z = coords[0].z;

        for( int ii = 0; ii < slice; ii++ )
        {
            int jj = ii + 1;

            if( jj >= slice )
                jj = 0;

            // Build the 4 vertices of each GL_QUAD
            coords[0].x = outer_cornerBuffer[jj].x;
            coords[0].y = -outer_cornerBuffer[jj].y;
            coords[1].x = coords[0].x;
            coords[1].y = coords[0].y;              // only z change
            coords[2].x = outer_cornerBuffer[ii].x;
            coords[2].y = -outer_cornerBuffer[ii].y;
            coords[3].x = coords[2].x;
            coords[3].y = coords[2].y;              // only z change

            // Creates the GL_QUAD
            Set_Object_Data( coords, aBiuTo3DUnits );
        }

        glNormal3f( 0.0, 0.0, 1.0 );    // Normal is Z axis
    }

    if( aThickness == 0 )
        return;

    // draw top (front) and bottom (back) horizontal sides (rings)
    S3D_VERTEX centerPos;
    centerPos.x = aCenterPos.x * aBiuTo3DUnits;
    centerPos.y = -aCenterPos.y * aBiuTo3DUnits;

    Draw3D_FlatRing( aCenterPos, aRadius + aThickness / 2, aRadius - aThickness / 2,
                 aZpos + aHeight, aBiuTo3DUnits );


    glNormal3f( 0.0, 0.0, -1.0 );
    Draw3D_FlatRing( aCenterPos, aRadius + aThickness / 2, aRadius - aThickness / 2,
                 aZpos, aBiuTo3DUnits );


    if( aHeight )
    {
    // Draws the vertical inner side (hole)
        std::vector <CPolyPt> inner_cornerBuffer;
        TransformCircleToPolygon( inner_cornerBuffer, aCenterPos,
                                  aRadius - (aThickness / 2), slice );

        for( int ii = 0; ii < slice; ii++ )
        {
            int jj = ii + 1;

            if( jj >= slice )
                jj = 0;

            // Build the 4 vertices of each GL_QUAD
            coords[0].x = inner_cornerBuffer[ii].x;
            coords[0].y = -inner_cornerBuffer[ii].y;
            coords[1].x = coords[0].x;
            coords[1].y = coords[0].y;              // only z change
            coords[2].x = inner_cornerBuffer[jj].x;
            coords[2].y = -inner_cornerBuffer[jj].y;
            coords[3].x = coords[2].x;
            coords[3].y = coords[2].y;              // only z change

            Set_Object_Data( coords, aBiuTo3DUnits );
        }
    }

    glNormal3f( 0.0, 0.0, 1.0 );    // Normal is Z axis
}


/*
 * Function Draw3D_ZaxisOblongCylinder:
 * draw a segment with an oblong hole.
 * Used to draw oblong holes
 */
void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
                                 int aRadius, int aHeight, int aThickness,
                                 int aZpos, double aBiuTo3DUnits  )
{
    const int slice = 12;

    // Build the points to approximate oblong cylinder by segments
    std::vector <CPolyPt> cornerBuffer;

    TransformRoundedEndsSegmentToPolygon( cornerBuffer, aAxis1Pos,
                                          aAxis2Pos, slice, aRadius * 2 );

    // Draw the cylinder
    std::vector<S3D_VERTEX> coords;
    coords.resize( 4 );

    // Init Z position of the 4 points of a GL_QUAD
    coords[0].z = aZpos;
    coords[1].z = aZpos + aHeight;
    coords[2].z = coords[1].z;
    coords[3].z = coords[0].z;

    for( int ii = 0; ii < slice; ii++ )
    {
        int jj = ii + 1;

        if( jj >= slice )
            jj = 0;

        // Build the 4 vertices of each GL_QUAD
        coords[0].x = cornerBuffer[ii].x;
        coords[0].y = -cornerBuffer[ii].y;
        coords[1].x = coords[0].x;
        coords[1].y = coords[0].y;              // only z change
        coords[2].x = cornerBuffer[jj].x;
        coords[2].y = -cornerBuffer[jj].y;
        coords[3].x = coords[2].x;
        coords[3].y = coords[2].y;              // only z change

        Set_Object_Data( coords, aBiuTo3DUnits );
    }

    glNormal3f( 0.0, 0.0, 1.0 );    // Normal is Z axis
}


/* draw a thick segment using 3D primitives, in a XY plane
 * wxPoint aStart, wxPoint aEnd = YX position of end in board units
 * aWidth = width of segment in board units
 * aThickness = thickness of segment in board units
 * aZpos = z position of segment in board units
 */
void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd,
                          int aWidth, int aThickness, int aZpos, double aBiuTo3DUnits )
{
    std::vector <CPolyPt>   cornerBuffer;
    const int               slice = 16;

    TransformRoundedEndsSegmentToPolygon( cornerBuffer, aStart, aEnd, slice, aWidth );

    Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos, aThickness, aBiuTo3DUnits );
}


void Draw3D_ArcSegment( const S3D_VERTEX& aCenterPos,
                        double aStartPointX, double aStartPointY,
                        double aArcAngle, double aWidth )
{
    const int   slice = 16;           // Number of segments to approximate a circle by segments
    double      arcStart_Angle;

    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;

    // Calculate the number of segments to approximate this arc
    int     imax = (int) ( (double) aArcAngle / ANGLE_INC( slice ) );

    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();
}


/** draw a ring using 3D primitives, in a plane parallel to the XY plane
 * @param aCenterPos = position of the center (Board internal units)
 * @param aOuterRadius = radius of the external circle (Board internal units)
 * @param aInnerRadius = radius of the circle (Board internal units)
 * @param aZpos = z position in board internal units
 * @param aBiuTo3DUnits = board internal units to 3D units scaling value
 */
void Draw3D_FlatRing( wxPoint aCenterPos, int aOuterRadius,
                  int aInnerRadius, int aZpos, double aBiuTo3DUnits )
{
    const int   slice = 16;
    const int   rot_angle   = ANGLE_INC( slice );
    double      cposx       = aCenterPos.x * aBiuTo3DUnits;
    double      cposy       = - aCenterPos.y * aBiuTo3DUnits;

    glBegin( GL_QUAD_STRIP );

    double zpos = aZpos * aBiuTo3DUnits;

    for( int ii = 0; ii <= slice; ii++ )
    {
        double  x   = aInnerRadius * aBiuTo3DUnits;
        double  y   = 0.0;
        RotatePoint( &x, &y, ii * rot_angle );
        glVertex3f( x + cposx, y + cposy, zpos );
        x   = aOuterRadius * aBiuTo3DUnits;
        y   = 0.0;
        RotatePoint( &x, &y, ii * rot_angle );
        glVertex3f( x + cposx, y + cposy, zpos );
    }

    glEnd();
}


/* draw one solid polygon
 * aCornersList = a std::vector<wxPoint> list of corners, in board internal units
 * aZpos = z position in board internal units
 * aThickness = thickness in board internal units
 * aIu_to_3Dunits = board internal units to 3D units scaling value
 */
void   Draw3D_HorizontalPolygon( std::vector<wxPoint>& aCornersList, int aZpos,
                                 int aThickness, double aBiuTo3DUnits )
{
    GLUtesselator* tess = gluNewTess();

    gluTessCallback( tess, GLU_TESS_BEGIN, ( void (CALLBACK*) () )tessBeginCB );
    gluTessCallback( tess, GLU_TESS_END, ( void (CALLBACK*) () )tessEndCB );
    gluTessCallback( tess, GLU_TESS_ERROR, ( void (CALLBACK*) () )tessErrorCB );
    gluTessCallback( tess, GLU_TESS_VERTEX, ( void (CALLBACK*) () )tesswxPoint2Vertex );

    GLdouble v_data[3];
    v_data[2] = ( aZpos + (aThickness / 2) ) * aBiuTo3DUnits;
    g_Parm_3D_Visu.m_CurrentZpos = v_data[2];

    // gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);

    // Draw solid polygon
    if( aThickness )
        glNormal3f( 0.0, 0.0, 1.0 );

    for( int side = 0; side < 2; side++ )
    {
        gluTessBeginPolygon( tess, NULL );
        gluTessBeginContour( tess );

        for( unsigned ii = 0; ii < aCornersList.size(); ii++ )
        {
            v_data[0]   = aCornersList[ii].x * g_Parm_3D_Visu.m_BiuTo3Dunits;
            v_data[1]   = -aCornersList[ii].y * g_Parm_3D_Visu.m_BiuTo3Dunits;
            // gluTessVertex store pointers on data, not data, so do not store
            // different corners values in a temporary variable
            // but send pointer on each corner value in aCornersList
            gluTessVertex( tess, v_data, &aCornersList[ii] );
        }

        gluTessEndContour( tess );
        gluTessEndPolygon( tess );

        if( aThickness == 0 )
            break;

        glNormal3f( 0.0, 0.0, -1.0 );
        v_data[2] = ( aZpos - (aThickness / 2) ) * aBiuTo3DUnits;
        g_Parm_3D_Visu.m_CurrentZpos = v_data[2];
    }

    gluDeleteTess( tess );

    if( aThickness == 0 )
        return;

    // Build the 3D data : vertical sides
    std::vector<S3D_VERTEX> vertices;
    vertices.resize( 4 );

    vertices[0].z   = aZpos + (aThickness / 2);
    vertices[1].z   = aZpos - (aThickness / 2);
    vertices[2].z   = vertices[1].z;
    vertices[3].z   = vertices[0].z;

    int slice = (int) aCornersList.size();

    for( int ii = 0; ii < slice; ii++ )
    {
        int jj = ii + 1;

        if( jj >=slice )
            jj = 0;

        vertices[0].x   = aCornersList[ii].x;
        vertices[0].y   = -aCornersList[ii].y;
        vertices[1].x   = vertices[0].x;
        vertices[1].y   = vertices[0].y;    // Z only changes.
        vertices[2].x   = aCornersList[jj].x;
        vertices[2].y   = -aCornersList[jj].y;
        vertices[3].x   = vertices[2].x;
        vertices[3].y   = vertices[2].y;    // Z only changes.

        Set_Object_Data( vertices, aBiuTo3DUnits );
    }
}


// /////////////////////////////////////////////////////////////////////////////
// GLU_TESS CALLBACKS
// /////////////////////////////////////////////////////////////////////////////

void CALLBACK tessBeginCB( GLenum which )
{
    glBegin( which );
}


void CALLBACK tessEndCB()
{
    glEnd();
}


void CALLBACK tessCPolyPt2Vertex( const GLvoid* data )
{
    // cast back to double type
    const CPolyPt* ptr = (const CPolyPt*) data;

    glVertex3f( ptr->x * g_Parm_3D_Visu.m_BiuTo3Dunits,
                -ptr->y * g_Parm_3D_Visu.m_BiuTo3Dunits,
                g_Parm_3D_Visu.m_CurrentZpos );
}


void CALLBACK tesswxPoint2Vertex( const GLvoid* data )
{
    const wxPoint* ptr = (const wxPoint*) data;

    glVertex3f( ptr->x * g_Parm_3D_Visu.m_BiuTo3Dunits,
                -ptr->y * g_Parm_3D_Visu.m_BiuTo3Dunits,
                g_Parm_3D_Visu.m_CurrentZpos );
}


void CALLBACK tessErrorCB( GLenum errorCode )
{
#if defined(DEBUG)
    const GLubyte* errorStr;

    errorStr = gluErrorString( errorCode );

    // DEBUG //
    D( printf( "Tess ERROR: %s\n", errorStr ); )
#endif
}
+134 −0

File added.

Preview size limit exceeded, changes collapsed.

+26 −16
Original line number Original line Diff line number Diff line
@@ -37,8 +37,6 @@
#include <3d_viewer_id.h>
#include <3d_viewer_id.h>


INFO3D_VISU g_Parm_3D_Visu;
INFO3D_VISU g_Parm_3D_Visu;
double       DataScale3D; // 3D conversion units.



BEGIN_EVENT_TABLE( EDA_3D_FRAME, wxFrame )
BEGIN_EVENT_TABLE( EDA_3D_FRAME, wxFrame )
    EVT_ACTIVATE( EDA_3D_FRAME::OnActivate )
    EVT_ACTIVATE( EDA_3D_FRAME::OnActivate )
@@ -130,6 +128,13 @@ void EDA_3D_FRAME::OnCloseWindow( wxCloseEvent& Event )
    Destroy();
    Destroy();
}
}


static const wxString keyPosx( wxT( "Pos_x" ) );
static const wxString keyPosy( wxT( "Pos_y" ) );
static const wxString keySizex( wxT( "Size_x" ) );
static const wxString keySizey( wxT( "Size_y" ) );
static const wxString keyBgColor_Red( wxT( "BgColor_Red" ) );
static const wxString keyBgColor_Green( wxT( "BgColor_Green" ) );
static const wxString keyBgColor_Blue( wxT( "BgColor_Blue" ) );


void EDA_3D_FRAME::GetSettings()
void EDA_3D_FRAME::GetSettings()
{
{
@@ -138,17 +143,17 @@ void EDA_3D_FRAME::GetSettings()


    if( config )
    if( config )
    {
    {
        text = m_FrameName + wxT( "Pos_x" );
        text = m_FrameName + keyPosx;
        config->Read( text, &m_FramePos.x );
        config->Read( text, &m_FramePos.x );
        text = m_FrameName + wxT( "Pos_y" );
        text = m_FrameName + keyPosy;
        config->Read( text, &m_FramePos.y );
        config->Read( text, &m_FramePos.y );
        text = m_FrameName + wxT( "Size_x" );
        text = m_FrameName + keySizex;
        config->Read( text, &m_FrameSize.x, 600 );
        config->Read( text, &m_FrameSize.x, 600 );
        text = m_FrameName + wxT( "Size_y" );
        text = m_FrameName + keySizey;
        config->Read( text, &m_FrameSize.y, 400 );
        config->Read( text, &m_FrameSize.y, 400 );
        config->Read( wxT( "BgColor_Red" ), &g_Parm_3D_Visu.m_BgColor.m_Red, 0.0 );
        config->Read( keyBgColor_Red, &g_Parm_3D_Visu.m_BgColor.m_Red, 0.0 );
        config->Read( wxT( "BgColor_Green" ), &g_Parm_3D_Visu.m_BgColor.m_Green, 0.0 );
        config->Read( keyBgColor_Green, &g_Parm_3D_Visu.m_BgColor.m_Green, 0.0 );
        config->Read( wxT( "BgColor_Blue" ), &g_Parm_3D_Visu.m_BgColor.m_Blue, 0.0 );
        config->Read( keyBgColor_Blue, &g_Parm_3D_Visu.m_BgColor.m_Blue, 0.0 );
    }
    }
#if defined( __WXMAC__ )
#if defined( __WXMAC__ )
    // for macOSX, the window must be below system (macOSX) toolbar
    // for macOSX, the window must be below system (macOSX) toolbar
@@ -166,9 +171,9 @@ void EDA_3D_FRAME::SaveSettings()
    if( !Config )
    if( !Config )
        return;
        return;


    Config->Write( wxT( "BgColor_Red" ), g_Parm_3D_Visu.m_BgColor.m_Red );
    Config->Write( keyBgColor_Red, g_Parm_3D_Visu.m_BgColor.m_Red );
    Config->Write( wxT( "BgColor_Green" ), g_Parm_3D_Visu.m_BgColor.m_Green );
    Config->Write( keyBgColor_Green, g_Parm_3D_Visu.m_BgColor.m_Green );
    Config->Write( wxT( "BgColor_Blue" ), g_Parm_3D_Visu.m_BgColor.m_Blue );
    Config->Write( keyBgColor_Blue, g_Parm_3D_Visu.m_BgColor.m_Blue );


    if( IsIconized() )
    if( IsIconized() )
        return;
        return;
@@ -176,13 +181,13 @@ void EDA_3D_FRAME::SaveSettings()
    m_FrameSize = GetSize();
    m_FrameSize = GetSize();
    m_FramePos  = GetPosition();
    m_FramePos  = GetPosition();


    text = m_FrameName + wxT( "Pos_x" );
    text = m_FrameName + keyPosx;
    Config->Write( text, (long) m_FramePos.x );
    Config->Write( text, (long) m_FramePos.x );
    text = m_FrameName + wxT( "Pos_y" );
    text = m_FrameName + keyPosy;
    Config->Write( text, (long) m_FramePos.y );
    Config->Write( text, (long) m_FramePos.y );
    text = m_FrameName + wxT( "Size_x" );
    text = m_FrameName + keySizex;
    Config->Write( text, (long) m_FrameSize.x );
    Config->Write( text, (long) m_FrameSize.x );
    text = m_FrameName + wxT( "Size_y" );
    text = m_FrameName + keySizey;
    Config->Write( text, (long) m_FrameSize.y );
    Config->Write( text, (long) m_FrameSize.y );
}
}


@@ -322,6 +327,11 @@ void EDA_3D_FRAME::Process_Special_Functions( wxCommandEvent& event )
        NewDisplay();
        NewDisplay();
        return;
        return;


    case ID_MENU3D_USE_COPPER_THICKNESS:
        g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_USE_COPPER_THICKNESS] = isChecked;
        NewDisplay();
        return;

    case ID_MENU3D_ZONE_ONOFF:
    case ID_MENU3D_ZONE_ONOFF:
        g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_ZONE] = isChecked;
        g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_ZONE] = isChecked;
        NewDisplay();
        NewDisplay();
Loading