Browse Source
3D viewer:
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.
pull/1/head
17 changed files with 1400 additions and 1057 deletions
-
403d-viewer/3d_aux.cpp
-
11453d-viewer/3d_draw.cpp
-
5913d-viewer/3d_draw_basic_functions.cpp
-
1343d-viewer/3d_draw_basic_functions.h
-
423d-viewer/3d_frame.cpp
-
73d-viewer/3d_read_mesh.cpp
-
43d-viewer/3d_toolbar.cpp
-
243d-viewer/3d_viewer.h
-
13d-viewer/3d_viewer_id.h
-
23d-viewer/CMakeLists.txt
-
1943d-viewer/info3d_visu.cpp
-
763d-viewer/info3d_visu.h
-
1bitmaps_png/CMakeLists.txt
-
43bitmaps_png/cpp_26/use_3D_copper_thickness.cpp
-
109bitmaps_png/sources/use_3D_copper_thickness.svg
-
43eeschema/eeschema_config.cpp
-
1include/bitmaps.h
1145
3d-viewer/3d_draw.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,591 @@ |
|||
/*
|
|||
* 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
|
|||
} |
|||
@ -0,0 +1,134 @@ |
|||
/* |
|||
* 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.h |
|||
*/ |
|||
#ifndef _3D_DRAW_BASIC_FUNCTIONS_H_ |
|||
#define _3D_DRAW_BASIC_FUNCTIONS_H_ |
|||
|
|||
// angle increment to draw a circle, approximated by segments |
|||
#define ANGLE_INC( x ) ( 3600 / (x) ) |
|||
|
|||
|
|||
/** |
|||
* Function Draw3D_HorizontalPolygon |
|||
* draw one solid polygon |
|||
* @param aCornersList = a std::vector<wxPoint> list of corners, in board internal units |
|||
* @param aZpos = z position in board internal units |
|||
* @param aThickness = thickness in board internal 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 |
|||
* The bottom side is located at aZpos - aThickness / 2 |
|||
*/ |
|||
void Draw3D_HorizontalPolygon( std::vector<wxPoint>& aCornersList, int aZpos, |
|||
int aThickness, double aBiuTo3DUnits ); |
|||
|
|||
/** draw all solid polygons found in aPolysList |
|||
* @param aPolysList = the poligon list to draw |
|||
* @param aZpos = z position in board internal units |
|||
* @param aThickness = thickness in board internal 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 |
|||
* The bottom side is located at aZpos - aThickness / 2 |
|||
*/ |
|||
void Draw3D_SolidHorizontalPolyPolygons( const std::vector<CPolyPt>& aPolysList, |
|||
int aZpos, int aThickness, double aBiuTo3DUnits ); |
|||
|
|||
/** draw the solid polygon found in aPolysList |
|||
* The first polygonj is the main polygon, others are holes |
|||
* @param aPolysList = the polygon with holes to draw |
|||
* @param aZpos = z position in board internal units |
|||
* @param aThickness = thickness in board internal 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 |
|||
* The bottom side is located at aZpos - aThickness / 2 |
|||
*/ |
|||
void Draw3D_SolidHorizontalPolygonWithHoles( const std::vector<CPolyPt>& aPolysList, |
|||
int aZpos, int aThickness, double aBiuTo3DUnits ); |
|||
|
|||
/** draw a thick segment using 3D primitives, in a XY plane |
|||
* @param wxPoint aStart = YX position of start point in board units |
|||
* @param wxPoint aEnd = YX position of end point in board units |
|||
* @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 |
|||
* 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_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) |
|||
* @param aArcAngle = arc angle in 1/10 degrees |
|||
* @param aWidth = thickness of arc |
|||
*/ |
|||
void Draw3D_ArcSegment( const S3D_VERTEX& aCenterPos, |
|||
double aStartPointX, double aStartPointY, |
|||
double aArcAngle, double aWidth ); |
|||
|
|||
|
|||
/** draw a thick cylinder (a tube) using 3D primitives. |
|||
* the cylinder axis is parallel to the Z axis |
|||
* @param aCentPos = XY position of the axis cylinder ( board internal units) |
|||
* @param aRadius = radius of the cylinder ( board internal units) |
|||
* @param aHeight = height of the cylinder ( boardinternal units) |
|||
* @param aThickness = tichkness of tube ( boardinternal units) |
|||
* @param aZpos = Z position of the bottom side of the cylinder ( board internal units) |
|||
* @param aBiuTo3DUnits = board internal units to 3D units scaling value |
|||
* |
|||
* If aHeight = height of the cylinder is 0, only one ring will be drawn |
|||
* If aThickness = 0, only one cylinder (not a tube) will be drawn |
|||
*/ |
|||
void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius, |
|||
int aHeight, int aThickness, |
|||
int aZpos, double aBiuTo3DUnits ); |
|||
|
|||
/** draw an oblong cylinder (oblong tube) using 3D primitives. |
|||
* the cylinder axis are parallel to the Z axis |
|||
* @param aAxis1Pos = position of the first axis cylinder |
|||
* @param aAxis2Pos = position of the second axis cylinder |
|||
* @param aRadius = radius of the cylinder ( board internal units ) |
|||
* @param aHeight = height of the cylinder ( board internal units ) |
|||
* @param aThickness = tichkness of tube ( board internal units ) |
|||
* @param aZpos = Z position of the bottom side of the cylinder ( board internal units ) |
|||
* @param aBiuTo3DUnits = board internal units to 3D units scaling value |
|||
*/ |
|||
void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos, |
|||
int aRadius, int aHeight, int aThickness, |
|||
int aZpos, double aBiuTo3DUnits ); |
|||
|
|||
#endif // _3D_DRAW_BASIC_FUNCTIONS_H_ |
|||
@ -0,0 +1,194 @@ |
|||
/*
|
|||
* 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-2011 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 info3d_visu.cpp |
|||
*/ |
|||
|
|||
#include <fctsys.h>
|
|||
|
|||
#include <common.h>
|
|||
|
|||
#include <class_board_design_settings.h>
|
|||
#include <class_board.h>
|
|||
|
|||
#include <3d_viewer.h>
|
|||
#include <info3d_visu.h>
|
|||
#include <trackball.h>
|
|||
|
|||
// Thickness of copper
|
|||
// TODO: define the actual copper thickness by user
|
|||
#define COPPER_THICKNESS (int)(0.035 * IU_PER_MM) // for 35 u
|
|||
#define TECH_LAYER_THICKNESS (int)(0.04 * IU_PER_MM)
|
|||
#define EPOXY_THICKNESS (int)(1.6 * IU_PER_MM) // for 1.6 mm
|
|||
|
|||
|
|||
/* INFO3D_VISU in an helper class to store parameters like scaling factors,
|
|||
* board size, Z coordinates of layers ... |
|||
* to create the 3D 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; |
|||
m_CopperThickness = 0; |
|||
m_EpoxyThickness = 0; |
|||
m_NonCopperLayerThickness = 0; |
|||
|
|||
// default all special item layers Visible
|
|||
for( ii = 0; ii < FL_LAST; ii++ ) |
|||
m_DrawFlags[ii] = true; |
|||
|
|||
m_DrawFlags[FL_GRID] = false; |
|||
m_DrawFlags[FL_USE_COPPER_THICKNESS] = false; |
|||
} |
|||
|
|||
|
|||
INFO3D_VISU::~INFO3D_VISU() |
|||
{ |
|||
} |
|||
|
|||
|
|||
/* Initialize info 3D Parameters from aBoard
|
|||
*/ |
|||
void INFO3D_VISU::InitSettings( BOARD* aBoard ) |
|||
{ |
|||
EDA_RECT bbbox = aBoard->ComputeBoundingBox( false ); |
|||
|
|||
if( bbbox.GetWidth() == 0 && bbbox.GetHeight() == 0 ) |
|||
{ |
|||
bbbox.SetWidth( 100 * IU_PER_MM ); |
|||
bbbox.SetHeight( 100 * IU_PER_MM ); |
|||
} |
|||
|
|||
m_BoardSettings = &aBoard->GetDesignSettings(); |
|||
|
|||
m_BoardSize = bbbox.GetSize(); |
|||
m_BoardPos = bbbox.Centre(); |
|||
|
|||
m_BoardPos.y = -m_BoardPos.y; |
|||
m_CopperLayersCount = aBoard->GetCopperLayerCount(); |
|||
|
|||
// Ensure the board has 2 sides for 3D views, because it is hard to find
|
|||
// a *really* single side board in the true life...
|
|||
if( m_CopperLayersCount < 2 ) |
|||
m_CopperLayersCount = 2; |
|||
|
|||
m_BiuTo3Dunits = 2.0 / std::max( m_BoardSize.x, m_BoardSize.y ); |
|||
|
|||
m_EpoxyThickness = aBoard->GetDesignSettings().GetBoardThickness() * m_BiuTo3Dunits; |
|||
|
|||
// TODO use value defined by user (currently use default values by ctor
|
|||
m_CopperThickness = COPPER_THICKNESS * m_BiuTo3Dunits; |
|||
m_NonCopperLayerThickness = TECH_LAYER_THICKNESS * m_BiuTo3Dunits; |
|||
|
|||
// Init Z position of each layer
|
|||
// calculate z position for each copper layer
|
|||
int layer; |
|||
int copper_layers_cnt = m_CopperLayersCount; |
|||
|
|||
for( layer = 0; layer < copper_layers_cnt; layer++ ) |
|||
{ |
|||
m_LayerZcoord[layer] = |
|||
m_EpoxyThickness * layer / (copper_layers_cnt - 1); |
|||
} |
|||
|
|||
double zpos_copper_back = m_LayerZcoord[0]; |
|||
double zpos_copper_front = m_EpoxyThickness; |
|||
|
|||
// Fill remaining unused copper layers and front layer zpos
|
|||
// with m_EpoxyThickness
|
|||
for( ; layer <= LAST_COPPER_LAYER; layer++ ) |
|||
{ |
|||
m_LayerZcoord[layer] = m_EpoxyThickness; |
|||
} |
|||
|
|||
// calculate z position for each non copper layer
|
|||
for( int layer_id = FIRST_NO_COPPER_LAYER; layer_id < NB_LAYERS; layer_id++ ) |
|||
{ |
|||
double zpos; |
|||
#define NonCopperLayerThicknessMargin 1.1
|
|||
|
|||
switch( layer_id ) |
|||
{ |
|||
case ADHESIVE_N_BACK: |
|||
zpos = zpos_copper_back - |
|||
4 * m_NonCopperLayerThickness * NonCopperLayerThicknessMargin; |
|||
break; |
|||
|
|||
case ADHESIVE_N_FRONT: |
|||
zpos = zpos_copper_front + |
|||
4 * m_NonCopperLayerThickness * NonCopperLayerThicknessMargin; |
|||
break; |
|||
|
|||
case SOLDERPASTE_N_BACK: |
|||
zpos = zpos_copper_back - |
|||
3 * m_NonCopperLayerThickness * NonCopperLayerThicknessMargin; |
|||
break; |
|||
|
|||
case SOLDERPASTE_N_FRONT: |
|||
zpos = zpos_copper_front + |
|||
3 * m_NonCopperLayerThickness * NonCopperLayerThicknessMargin; |
|||
break; |
|||
|
|||
case SOLDERMASK_N_BACK: |
|||
zpos = zpos_copper_back - |
|||
1 * m_NonCopperLayerThickness * NonCopperLayerThicknessMargin; |
|||
break; |
|||
|
|||
case SOLDERMASK_N_FRONT: |
|||
zpos = zpos_copper_front + |
|||
1 * m_NonCopperLayerThickness * NonCopperLayerThicknessMargin; |
|||
break; |
|||
|
|||
case SILKSCREEN_N_BACK: |
|||
zpos = zpos_copper_back - |
|||
2 * m_NonCopperLayerThickness * NonCopperLayerThicknessMargin; |
|||
break; |
|||
|
|||
case SILKSCREEN_N_FRONT: |
|||
zpos = zpos_copper_front + |
|||
2 * m_NonCopperLayerThickness * NonCopperLayerThicknessMargin; |
|||
break; |
|||
|
|||
default: |
|||
zpos = zpos_copper_front + |
|||
(layer_id - FIRST_NO_COPPER_LAYER + 5) * |
|||
m_NonCopperLayerThickness * NonCopperLayerThicknessMargin; |
|||
break; |
|||
} |
|||
|
|||
m_LayerZcoord[layer_id] = zpos; |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
|
|||
/* Do not modify this file, it was automatically generated by the
|
|||
* PNG2cpp CMake script, using a *.png file as input. |
|||
*/ |
|||
|
|||
#include <bitmaps.h>
|
|||
|
|||
static const unsigned char png[] = { |
|||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, |
|||
0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c, |
|||
0xce, 0x00, 0x00, 0x01, 0xa6, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xbd, 0xd5, 0xbf, 0x4b, 0xc3, |
|||
0x50, 0x10, 0x07, 0xf0, 0x4b, 0xfa, 0xde, 0x8b, 0x4e, 0x16, 0x71, 0x12, 0x2b, 0x0e, 0x2e, 0xa5, |
|||
0x43, 0x71, 0x12, 0x1c, 0xc4, 0xa5, 0xe8, 0x22, 0x76, 0x71, 0xd0, 0xa1, 0xa3, 0x4b, 0x41, 0x6c, |
|||
0x5a, 0x7f, 0x80, 0x08, 0x2e, 0x82, 0xe0, 0xa2, 0x83, 0xae, 0x2a, 0x45, 0x11, 0x9c, 0x15, 0x5c, |
|||
0x0a, 0x8a, 0xe0, 0xe0, 0xa0, 0x50, 0xf0, 0x0f, 0x28, 0x2a, 0x16, 0xc4, 0x22, 0x0e, 0x6a, 0xa1, |
|||
0x3d, 0xbf, 0x95, 0x0e, 0x6a, 0x92, 0xa9, 0x87, 0x90, 0x6f, 0x08, 0x21, 0xe4, 0x93, 0xbb, 0xe4, |
|||
0x5d, 0x88, 0x99, 0xe9, 0x3f, 0x42, 0xd8, 0x1c, 0xa4, 0x4d, 0x28, 0xa1, 0x60, 0xc8, 0x98, 0x3c, |
|||
0xc2, 0x22, 0x71, 0x9c, 0x0b, 0xdc, 0xd2, 0x0e, 0xaa, 0x28, 0x8c, 0x8b, 0xee, 0x05, 0x31, 0xd7, |
|||
0x17, 0xca, 0x11, 0xed, 0xec, 0xda, 0x76, 0x59, 0x0c, 0x32, 0xe6, 0x1d, 0x89, 0x7a, 0xa0, 0x05, |
|||
0xa2, 0x6e, 0x60, 0x2f, 0x57, 0x4a, 0xb1, 0x20, 0x76, 0x8d, 0x5b, 0xab, 0xdf, 0xad, 0xc3, 0x0e, |
|||
0xd0, 0xf4, 0x32, 0x0e, 0x9f, 0xb5, 0x96, 0xc4, 0x56, 0x3c, 0x50, 0x13, 0x3b, 0xde, 0xb6, 0x2c, |
|||
0xae, 0xcb, 0x41, 0x55, 0xd6, 0x7a, 0xc0, 0x03, 0x65, 0x89, 0xba, 0xe6, 0x89, 0x9e, 0xce, 0x43, |
|||
0x21, 0xc9, 0xaa, 0x8a, 0xdf, 0xcb, 0xe7, 0x27, 0xd4, 0xac, 0x6a, 0x62, 0x09, 0xa7, 0xca, 0xb2, |
|||
0x2d, 0x5c, 0xf7, 0x40, 0x4d, 0x6c, 0x6f, 0x0b, 0x2d, 0xac, 0xc9, 0x41, 0x35, 0x56, 0x6a, 0xc8, |
|||
0x03, 0x2d, 0x12, 0x75, 0x00, 0x2b, 0xed, 0xdb, 0x36, 0x9f, 0xa0, 0x8d, 0xad, 0xe6, 0x46, 0xa9, |
|||
0x53, 0x60, 0x93, 0xbe, 0xe3, 0x02, 0xef, 0x2b, 0x01, 0xac, 0x8e, 0xb0, 0x40, 0x3e, 0xf0, 0xf0, |
|||
0xb1, 0xc0, 0x21, 0x88, 0x0b, 0xdc, 0x46, 0x1b, 0x85, 0x32, 0x4b, 0x59, 0x56, 0xc3, 0x19, 0x76, |
|||
0xc6, 0x64, 0x62, 0x62, 0x81, 0x43, 0xd5, 0x65, 0x27, 0xed, 0xb2, 0x61, 0xa1, 0x54, 0x5c, 0x6e, |
|||
0x8f, 0xf8, 0x42, 0x3d, 0xe3, 0x14, 0x4d, 0xbf, 0xe9, 0x4b, 0x39, 0x4c, 0x17, 0x30, 0xa9, 0x2d, |
|||
0x3f, 0x28, 0xd7, 0x9f, 0xb2, 0x38, 0xfd, 0x2a, 0x56, 0x15, 0xe2, 0xe4, 0xfc, 0x20, 0x0b, 0x29, |
|||
0x0c, 0xae, 0xd9, 0x82, 0x90, 0xf9, 0x44, 0x65, 0x71, 0xcf, 0xac, 0x03, 0x14, 0x41, 0x2a, 0xc9, |
|||
0x33, 0x25, 0x89, 0x15, 0x57, 0x19, 0x7f, 0xdd, 0xbf, 0xb3, 0x0e, 0xd0, 0x54, 0x1f, 0x96, 0xd5, |
|||
0xcc, 0xa3, 0x16, 0xc3, 0x32, 0xac, 0x37, 0x3d, 0x50, 0x13, 0x3b, 0x88, 0xe7, 0x2c, 0xce, 0xd4, |
|||
0xc4, 0xaa, 0xaa, 0x67, 0xd9, 0x49, 0xf8, 0x41, 0x61, 0xa4, 0x34, 0x7a, 0x18, 0x92, 0x6c, 0xe1, |
|||
0x43, 0x86, 0xa9, 0xd3, 0xf3, 0xbd, 0x03, 0x1a, 0xe9, 0x4d, 0x52, 0x2d, 0x75, 0xa7, 0x79, 0xae, |
|||
0x6a, 0x5a, 0x8e, 0x5b, 0x37, 0x55, 0x60, 0x79, 0xdf, 0x55, 0x0c, 0x6c, 0x03, 0x61, 0xa1, 0x94, |
|||
0x1a, 0x9d, 0x0a, 0x82, 0x0c, 0x72, 0x2b, 0x88, 0x1d, 0x7d, 0x01, 0xbf, 0xeb, 0x9b, 0xb8, 0x05, |
|||
0x3e, 0x9f, 0x36, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, |
|||
}; |
|||
|
|||
const BITMAP_OPAQUE use_3D_copper_thickness_xpm[1] = {{ png, sizeof( png ), "use_3D_copper_thickness_xpm" }}; |
|||
|
|||
//EOF
|
|||
@ -0,0 +1,109 @@ |
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
|||
<svg |
|||
xmlns:dc="http://purl.org/dc/elements/1.1/" |
|||
xmlns:cc="http://creativecommons.org/ns#" |
|||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
|||
xmlns:svg="http://www.w3.org/2000/svg" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
|||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
|||
height="26" |
|||
width="26" |
|||
version="1.1" |
|||
id="svg2" |
|||
inkscape:version="0.48.1 " |
|||
sodipodi:docname="3d_use_copper_thickness.svg"> |
|||
<metadata |
|||
id="metadata26"> |
|||
<rdf:RDF> |
|||
<cc:Work |
|||
rdf:about=""> |
|||
<dc:format>image/svg+xml</dc:format> |
|||
<dc:type |
|||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
|||
<dc:title /> |
|||
</cc:Work> |
|||
</rdf:RDF> |
|||
</metadata> |
|||
<sodipodi:namedview |
|||
pagecolor="#ffffff" |
|||
bordercolor="#666666" |
|||
borderopacity="1" |
|||
objecttolerance="10" |
|||
gridtolerance="10" |
|||
guidetolerance="10" |
|||
inkscape:pageopacity="0" |
|||
inkscape:pageshadow="2" |
|||
inkscape:window-width="1280" |
|||
inkscape:window-height="968" |
|||
id="namedview24" |
|||
showgrid="false" |
|||
inkscape:zoom="32.120513" |
|||
inkscape:cx="12.060967" |
|||
inkscape:cy="11.98812" |
|||
inkscape:window-x="-4" |
|||
inkscape:window-y="-4" |
|||
inkscape:window-maximized="1" |
|||
inkscape:current-layer="svg2" |
|||
showguides="true" |
|||
inkscape:guide-bbox="true" |
|||
showborder="true"> |
|||
<sodipodi:guide |
|||
orientation="0,1" |
|||
position="45.626168,30.620228" |
|||
id="guide3799" /> |
|||
</sodipodi:namedview> |
|||
<defs |
|||
id="defs4"> |
|||
<filter |
|||
id="c" |
|||
height="1.212" |
|||
width="1.059" |
|||
color-interpolation-filters="sRGB" |
|||
y="-0.10598" |
|||
x="-0.029501"> |
|||
<feGaussianBlur |
|||
stdDeviation="0.52522041" |
|||
id="feGaussianBlur7" /> |
|||
</filter> |
|||
<filter |
|||
id="d" |
|||
height="1.212" |
|||
width="1.059" |
|||
color-interpolation-filters="sRGB" |
|||
y="-0.10598" |
|||
x="-0.029501"> |
|||
<feGaussianBlur |
|||
stdDeviation="0.52522041" |
|||
id="feGaussianBlur10" /> |
|||
</filter> |
|||
</defs> |
|||
<g |
|||
id="g3879" |
|||
transform="matrix(1.079734,0,0,0.8805836,0.04176086,4.8713303)"> |
|||
<path |
|||
style="fill:#1c4d00;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none" |
|||
inkscape:connector-curvature="0" |
|||
id="path22-1-0" |
|||
d="M 0.00743077,13.573317 H 18.058057 l 6.017018,10.471372 H 6.0244485 L 0.00816177,13.573317 z" /> |
|||
<path |
|||
style="fill:#72ff06;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none" |
|||
inkscape:connector-curvature="0" |
|||
id="path22-9" |
|||
d="M -0.01750581,11.199955 H 18.033121 l 6.017018,10.471372 H 5.999512 L -0.01677418,11.199955 z" /> |
|||
</g> |
|||
<g |
|||
id="g3873" |
|||
transform="matrix(1.0749484,0,0,0.90644265,-0.0011,1.998042)"> |
|||
<path |
|||
style="fill:#740000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none" |
|||
inkscape:connector-curvature="0" |
|||
id="path22-1" |
|||
d="M 0.03961332,2.3524334 H 18.09024 L 24.107258,12.823805 H 6.056631 L 0.04034432,2.3524334 z" /> |
|||
<path |
|||
style="fill:#ff0606;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none" |
|||
inkscape:connector-curvature="0" |
|||
id="path22" |
|||
d="M 0.01467674,-0.02092885 H 18.065304 L 24.082322,10.450443 H 6.0316946 L 0.01540837,-0.02092885 z" /> |
|||
</g> |
|||
</svg> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue