kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #08407
patch to add some 3d-viewer features
Hi,
finally i found some time to package some additions for 3d-viewer
(board outline, solder mask and paste mask rendering)
Maybe somebody can check and commit it.
Thanks,
Thomas
Attachment:
3d-viewer.png
Description: PNG image
diff -rup 3d-viewer.orig//3d_aux.cpp 3d-viewer//3d_aux.cpp
--- 3d-viewer.orig//3d_aux.cpp 2012-06-03 22:21:14.095611510 +0200
+++ 3d-viewer//3d_aux.cpp 2012-06-03 22:16:21.653545422 +0200
@@ -192,6 +192,9 @@ Info_3D_Visu::Info_3D_Visu()
// default all special item layers Visible
for (ii=0; ii< FL_LAST; ii++)
m_DrawFlags[ii]=true;
+#ifdef TSP_20120603
+ m_DrawFlags[g_Parm_3D_Visu.FL_AXIS]=false;
+#endif // TSP_20120603
}
diff -rup 3d-viewer.orig//3d_draw.cpp 3d-viewer//3d_draw.cpp
--- 3d-viewer.orig//3d_draw.cpp 2012-06-03 22:21:14.095611510 +0200
+++ 3d-viewer//3d_draw.cpp 2012-06-03 22:16:21.653545422 +0200
@@ -1,3 +1,5 @@
+#define TSP_20120407
+
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
@@ -25,7 +27,7 @@
/**
* @file 3d_draw.cpp
-*/
+ */
#include <fctsys.h>
#include <common.h>
@@ -53,26 +55,53 @@
#error Please set wxUSE_GLCANVAS to 1 in setup.h.
#endif
-extern void CheckGLError();
+extern void CheckGLError();
-static void Draw3D_FilledCircle( double posx, double posy, double rayon,
- double hole_rayon, double zpos );
-static void Draw3D_FilledSegment( double startx, double starty,
+static void Draw3D_FilledCircle( double posx, double posy, double rayon,
+ double hole_rayon, double zpos );
+static void Draw3D_FilledSegment( double startx, double starty,
+ double endx, double endy,
+ double width, double zpos );
+static void Draw3D_FilledCylinder( double posx, double posy, double rayon,
+ double height, double zpos );
+static void Draw3D_FilledSegmentWithHole( double startx, double starty,
+ double endx, double endy,
+ double width, double holex,
+ double holey, double holeradius,
+ double zpos, double offX, double offY );
+static void Draw3D_ArcSegment( double startx, double starty, double centrex,
+ double centrey, double arc_angle, double width, double zpos );
+static void Draw3D_CircleSegment( double startx, double starty, double endx,
+ double endy, double width, double zpos );
+static int Get3DLayerEnable( int act_layer );
+static GLfloat Get3DLayerSide( int act_layer );
+static void Draw3D_FilledOblong( double startx, double starty,
double endx, double endy,
- double width, double zpos );
-static void Draw3D_FilledCylinder( double posx, double posy, double rayon,
- double height, double zpos );
-static void Draw3D_FilledSegmentWithHole( double startx, double starty,
- double endx, double endy,
- double width, double holex,
- double holey, double holeradius,
- double zpos );
-static void Draw3D_ArcSegment( double startx, double starty, double centrex,
- double centrey, double arc_angle, double width, double zpos );
-static void Draw3D_CircleSegment( double startx, double starty, double endx,
- double endy, double width, double zpos );
-static int Get3DLayerEnable( int act_layer );
-static GLfloat Get3DLayerSide( int act_layer );
+ double holex,
+ double holey, double holeradius,
+ double height, double zpos );
+static void Draw3D_FilledOblongMask( double startx, double starty,
+ double endx, double endy,
+ double holex,
+ double holey, double holeradius,
+ double height, double zpos );
+static void Draw3D_Mask( double startx, double starty, double endx,
+ double endy, double width, double zpos );
+static void Draw3D_ArcSegmentMask( double startx, double starty, double centrex,
+ double centrey, double arc_angle, double width,
+ double zpos );
+static void Draw3D_CircleSegmentMask( double startx, double starty, double endx,
+ double endy, double width, double zpos );
+static void Draw3D_FilledCircleMask( double posx, double posy, double rayon,
+ double hole_rayon, double zpos );
+static void Draw3D_FilledSegmentWithHoleMask( double startx, double starty,
+ double endx, double endy,
+ double width, double holex,
+ double holey, double holeradius,
+ double zpos, double offX, double offY );
+static void Draw3D_FilledCylinderMask( double posx, double posy, double rayon,
+ double height, double zpos );
+void MySetGLColor( int color, int layer );
#ifndef CALLBACK
@@ -80,16 +109,37 @@ static GLfloat Get3DLayerSide( int act_l
#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 );
+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 );
+
+static void CALLBACK mytessBeginCB( GLenum which );
+static void CALLBACK mytessEndCB();
+static void CALLBACK mytessErrorCB( GLenum errorCode );
+static void CALLBACK mytessCPolyPt2Vertex( const GLvoid* data );
+
+static void CALLBACK mytessCombineCB( GLdouble coords[3],
+ void* vertex_data[4],
+ GLfloat weight[4],
+ void** outData );
+
+
+std::vector<CPolyPt> e_data;
+std::vector<CPolyPt> p_data;
+int eii = 0;
+int pii = 0;
+int tmonly = 0;
+int do_values = 0;
+int do_ref = 0;
+#define Set_tmonly( x ) tmonly = x
+#define Get_tmonly() tmonly
void EDA_3D_CANVAS::Redraw( bool finish )
{
- // SwapBuffer requires the window to be shown before calling
+// SwapBuffer requires the window to be shown before calling
if( !IsShown() )
return;
@@ -99,12 +149,12 @@ void EDA_3D_CANVAS::Redraw( bool finish
SetCurrent();
#endif
- // 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.
+// 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.
const wxSize ClientSize = GetClientSize();
// *MUST* be called *after* SetCurrent( ):
@@ -136,34 +186,106 @@ void EDA_3D_CANVAS::Redraw( bool finish
}
glFlush();
- if( finish );
- glFinish();
+
+ if( finish )
+ ;
+
+ glFinish();
SwapBuffers();
}
-GLuint EDA_3D_CANVAS::CreateDrawGL_List()
+int orient( int mini, int spii, int pii )
{
- PCB_BASE_FRAME* pcbframe = Parent()->Parent();
- BOARD* pcb = pcbframe->GetBoard();
- TRACK* track;
- SEGZONE* segzone;
- int ii;
+ int qdx1, qdx2;
+ int qdy1, qdy2;
+
+ if( (pii - spii) < 2 )
+ return 0;
+
+ if( mini == spii )
+ {
+ qdy1 = (p_data[mini + 1].y - p_data[mini].y);
+ qdx1 = (p_data[mini + 1].x - p_data[mini].x);
+ qdy2 = (p_data[mini].y - p_data[pii - 1].y);
+ qdx2 = (p_data[mini].x - p_data[pii - 1].x);
+ }
+ else if( mini >= pii - 1 )
+ {
+ qdy1 = (p_data[spii].y - p_data[mini].y);
+ qdx1 = (p_data[spii].x - p_data[mini].x);
+ qdy2 = (p_data[mini].y - p_data[mini - 1].y);
+ qdx2 = (p_data[mini].x - p_data[mini - 1].x);
+ }
+ else
+ {
+ qdy1 = (p_data[mini + 1].y - p_data[mini].y);
+ qdx1 = (p_data[mini + 1].x - p_data[mini].x);
+ qdy2 = (p_data[mini].y - p_data[mini - 1].y);
+ qdx2 = (p_data[mini].x - p_data[mini - 1].x);
+ }
+
+ if( qdx1 | qdx2 )
+ {
+ if( qdx1 && qdx2 )
+ {
+ if( (double) qdy1 / (double) qdx1 > (double) qdy2 / (double) qdx2 )
+ {
+ return 1;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ if( qdx1 )
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+}
- wxBusyCursor dummy;
+GLuint EDA_3D_CANVAS::CreateDrawGL_List()
+{
+ PCB_BASE_FRAME* pcbframe = Parent()->Parent();
+ BOARD* pcb = pcbframe->GetBoard();
+ TRACK* track;
+ SEGZONE* segzone;
+ int ii;
+
+ wxBusyCursor dummy;
+ int bpii;
+
+ do_values = pcb->IsElementVisible( MOD_VALUES_VISIBLE );
+ do_ref = pcb->IsElementVisible( MOD_REFERENCES_VISIBLE );
+ Set_tmonly( 0 );
+ e_data.clear();
+ p_data.reserve( 1000000 );
+ p_data.clear();
+ eii = 0;
+ pii = 0;
m_gllist = glGenLists( 1 );
- EDA_RECT bbbox = pcbframe->GetBoardBoundingBox();
+ EDA_RECT bbbox = pcbframe->GetBoardBoundingBox();
g_Parm_3D_Visu.m_BoardSettings = &pcb->GetDesignSettings();
- g_Parm_3D_Visu.m_BoardSize = bbbox.GetSize();
- g_Parm_3D_Visu.m_BoardPos = bbbox.Centre();
+ g_Parm_3D_Visu.m_BoardSize = bbbox.GetSize();
+ g_Parm_3D_Visu.m_BoardPos = bbbox.Centre();
- g_Parm_3D_Visu.m_BoardPos.y = -g_Parm_3D_Visu.m_BoardPos.y;
- g_Parm_3D_Visu.m_Layers = pcb->GetCopperLayerCount();
+ g_Parm_3D_Visu.m_BoardPos.y = -g_Parm_3D_Visu.m_BoardPos.y;
+ g_Parm_3D_Visu.m_Layers = pcb->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...
@@ -184,29 +306,41 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
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;
+ {
+ if( ii <= SOLDERMASK_N_FRONT )
+ {
+ double offs = g_Parm_3D_Visu.m_Epoxy_Width * ( 4 - ( (ii >> 1) & 7 ) ) / 100.0;
+ g_Parm_3D_Visu.m_LayerZcoord[ii] =
+ (ii & 1) ? (g_Parm_3D_Visu.m_Epoxy_Width + offs) : -offs;
+ }
+ else
+ {
+ g_Parm_3D_Visu.m_LayerZcoord[ii] = g_Parm_3D_Visu.m_Epoxy_Width;
+ }
+ }
}
- GLfloat zpos_cu = 10 * 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_BACK] = -zpos_cu * 2;
- g_Parm_3D_Visu.m_LayerZcoord[ADHESIVE_N_FRONT] = zpos_cmp + zpos_cu;
- g_Parm_3D_Visu.m_LayerZcoord[SILKSCREEN_N_BACK] = -zpos_cu;
- g_Parm_3D_Visu.m_LayerZcoord[SILKSCREEN_N_FRONT] = zpos_cmp;
+ GLfloat zpos_cu = 10 * 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_BACK] = -zpos_cu * 2;
+ g_Parm_3D_Visu.m_LayerZcoord[ADHESIVE_N_FRONT] = zpos_cmp + zpos_cu;
+ g_Parm_3D_Visu.m_LayerZcoord[SILKSCREEN_N_BACK] = -zpos_cu - 0.004;
+ g_Parm_3D_Visu.m_LayerZcoord[SILKSCREEN_N_FRONT] = zpos_cmp * 1.07;
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( m_gllist, GL_COMPILE_AND_EXECUTE );
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
// draw axis
- if (g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_AXIS])
+ if( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_AXIS] )
{
glEnable( GL_COLOR_MATERIAL );
SetGLColor( WHITE );
@@ -223,14 +357,13 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
}
// Draw epoxy limits (do not use, works and test in progress)
- // TODO
// move the board in order to draw it with its center at 0,0 3D coordinates
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
+ glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
// draw tracks and vias :
for( track = pcb->m_Track; track != NULL; track = track->Next() )
@@ -241,13 +374,15 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
Draw3D_Track( track );
}
- if (g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_ZONE])
+ if( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_ZONE] )
{
// Draw segments used to fill copper areas. outdated!
for( segzone = pcb->m_Zone; segzone != NULL; segzone = segzone->Next() )
{
if( segzone->Type() == PCB_ZONE_T )
+ {
Draw3D_Track( segzone );
+ }
}
// Draw new segments
@@ -272,10 +407,10 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
dummysegment.SetLayer( curr_zone->GetLayer() );
dummysegment.m_Width = curr_zone->m_ZoneMinThickness;
- dummysegment.m_Start.x = curr_zone->m_FillSegmList[iseg].m_Start.x;
- dummysegment.m_Start.y = curr_zone->m_FillSegmList[iseg].m_Start.y;
- dummysegment.m_End.x = curr_zone->m_FillSegmList[iseg].m_End.x;
- dummysegment.m_End.y = curr_zone->m_FillSegmList[iseg].m_End.y;
+ dummysegment.m_Start.x = curr_zone->m_FillSegmList[iseg].m_Start.x;
+ dummysegment.m_Start.y = curr_zone->m_FillSegmList[iseg].m_Start.y;
+ dummysegment.m_End.x = curr_zone->m_FillSegmList[iseg].m_End.x;
+ dummysegment.m_End.y = curr_zone->m_FillSegmList[iseg].m_End.y;
Draw3D_Track( &dummysegment );
}
}
@@ -284,9 +419,9 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
// Draw copper areas outlines
for( ii = 0; ii < pcb->GetAreaCount(); ii++ )
{
- ZONE_CONTAINER* zone = pcb->GetArea( ii );
+ ZONE_CONTAINER* zone = pcb->GetArea( ii );
- std::vector<CPolyPt> polysList = zone->GetFilledPolysList();
+ std::vector<CPolyPt> polysList = zone->GetFilledPolysList();
if( polysList.size() == 0 )
continue;
@@ -294,10 +429,10 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
if( zone->m_ZoneMinThickness <= 1 )
continue;
- int imax = polysList.size() - 1;
- CPolyPt* firstcorner = &polysList[0];
- CPolyPt* begincorner = firstcorner;
- SEGZONE dummysegment( pcb );
+ int imax = polysList.size() - 1;
+ CPolyPt* firstcorner = &polysList[0];
+ CPolyPt* begincorner = firstcorner;
+ SEGZONE dummysegment( pcb );
dummysegment.SetLayer( zone->GetLayer() );
dummysegment.m_Width = zone->m_ZoneMinThickness;
@@ -308,10 +443,10 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
if( begincorner->utility == 0 )
{
// Draw only basic outlines, not extra segments
- dummysegment.m_Start.x = begincorner->x;
- dummysegment.m_Start.y = begincorner->y;
- dummysegment.m_End.x = endcorner->x;
- dummysegment.m_End.y = endcorner->y;
+ dummysegment.m_Start.x = begincorner->x;
+ dummysegment.m_Start.y = begincorner->y;
+ dummysegment.m_End.x = endcorner->x;
+ dummysegment.m_End.y = endcorner->y;
Draw3D_Track( &dummysegment );
}
@@ -321,10 +456,10 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
if( endcorner->utility == 0 )
{
// Draw only basic outlines, not extra segments
- dummysegment.m_Start.x = endcorner->x;
- dummysegment.m_Start.y = endcorner->y;
- dummysegment.m_End.x = firstcorner->x;
- dummysegment.m_End.y = firstcorner->y;
+ dummysegment.m_Start.x = endcorner->x;
+ dummysegment.m_Start.y = endcorner->y;
+ dummysegment.m_End.x = firstcorner->x;
+ dummysegment.m_End.y = firstcorner->y;
Draw3D_Track( &dummysegment );
}
@@ -345,7 +480,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
// draw graphic items
EDA_ITEM* PtStruct;
- for( PtStruct = pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
+ for( PtStruct = pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
{
switch( PtStruct->Type() )
{
@@ -365,9 +500,537 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
// draw footprints
MODULE* Module = pcb->m_Modules;
- for( ; Module != NULL; Module = Module->Next() )
+ if( eii )
{
- Module->Draw3D( this );
+ {
+ int ax, ay;
+ int ecnt = eii;
+ int need_cont;
+ int dlim = 100;
+
+ int gxmin = 0x7fffffff;
+ int xmin = 0x7fffffff;
+ int ymax = 0x80000000;
+ int gmini = -1;
+ int mini = -1;
+ int spii = 0;
+ int gspii = 0;
+ int gpii = 0;
+ pii = 0;
+ need_cont = 0;
+ p_data.clear();
+ p_data.push_back( CPolyPt( e_data[0].x, e_data[0].y ) );
+ e_data[0].x = 0x80000000;
+ ax = p_data[pii].x;
+ ay = p_data[pii].y;
+
+ if( ax < xmin )
+ {
+ xmin = ax;
+ ymax = ay;
+ mini = pii;
+ }
+ else if( ax == xmin )
+ {
+ if( ymax < ay )
+ {
+ ymax = ay;
+ mini = pii;
+ }
+ }
+
+ pii++;
+
+ p_data.push_back( CPolyPt( e_data[1].x, e_data[1].y ) );
+ e_data[1].x = 0x80000000;
+ ax = p_data[pii].x;
+ ay = p_data[pii].y;
+
+ if( ax < xmin )
+ {
+ xmin = ax;
+ ymax = ay;
+ mini = pii;
+ }
+ else if( ax == xmin )
+ {
+ if( ymax < ay )
+ {
+ ymax = ay;
+ mini = pii;
+ }
+ }
+
+ ecnt -= 1;
+ pii++;
+ ecnt -= 1;
+
+ while( ecnt > 2 )
+ {
+ int jj;
+ int lecnt = ecnt;
+
+ for( jj = 2; jj < eii; jj += 1 )
+ {
+ if( e_data[jj].x != (int) 0x80000000 )
+ {
+ int d = abs( ax - e_data[jj].x ) + abs( ay - e_data[jj].y );
+
+ if( d < dlim )
+ {
+ if( dlim > 100 )
+ {
+ dlim = 100;
+ p_data.push_back( CPolyPt( e_data[jj].x, e_data[jj].y ) );
+ e_data[jj].x = 0x80000000;
+ ax = p_data[pii].x;
+ ay = p_data[pii].y;
+
+ if( ax < xmin )
+ {
+ xmin = ax;
+ ymax = ay;
+ mini = pii;
+ }
+ else if( ax == xmin )
+ {
+ if( ymax < ay )
+ {
+ ymax = ay;
+ mini = pii;
+ }
+ }
+
+ if( need_cont )
+ {
+ need_cont = 0;
+ }
+
+ pii++;
+ }
+
+ p_data.push_back( CPolyPt( e_data[jj ^ 1].x, e_data[jj ^ 1].y ) );
+ e_data[jj ^ 1].x = 0x80000000;
+ ax = p_data[pii].x;
+ ay = p_data[pii].y;
+
+ if( ax < xmin )
+ {
+ xmin = ax;
+ ymax = ay;
+ mini = pii;
+ }
+ else if( ax == xmin )
+ {
+ if( ymax < ay )
+ {
+ ymax = ay;
+ mini = pii;
+ }
+ }
+
+ e_data[jj].x = 0x80000000;
+ ecnt -= 2;
+
+ if( need_cont )
+ {
+ need_cont = 0;
+ }
+
+ pii++;
+ continue;
+ }
+ }
+ }
+
+ if( lecnt == ecnt )
+ {
+ // close patch, open new...
+ if( need_cont == 0 )
+ {
+ int d;
+ pii--;
+ d =
+ abs( p_data[spii].x -
+ p_data[pii].x ) + abs( p_data[spii].y - p_data[pii].y );
+
+ if( d > 100 )
+ {
+ pii++;
+ }
+ else
+ {
+ p_data.pop_back();
+ }
+
+ need_cont = 1;
+ dlim = 0x7fffffff;
+ p_data.push_back( CPolyPt( 0x80000000, mini ) );
+
+ if( xmin < gxmin )
+ {
+ gpii = pii;
+ gspii = spii;
+ gmini = mini;
+ gxmin = xmin;
+ }
+
+ pii++;
+ spii = pii;
+ xmin = 0x7fffffff;
+ ymax = 0x80000000;
+ mini = -1;
+ }
+ }
+ }
+
+ if( need_cont == 0 )
+ {
+ int d;
+ pii--;
+ d = abs( p_data[spii].x - p_data[pii].x ) + abs( p_data[spii].y - p_data[pii].y );
+
+ if( d > 100 )
+ {
+ pii++;
+ }
+ else
+ {
+ p_data.pop_back();
+ }
+
+ if( gmini < 0 )
+ {
+ int o = orient( mini, spii, pii );
+
+ if( o > 0 )
+ {
+ int i;
+
+ for( i = 0; i < (pii - spii) / 2; i++ )
+ {
+ CPolyPt h = p_data[spii + i];
+ p_data[spii + i] = p_data[pii - i - 1];
+ p_data[pii - i - 1] = h;
+ }
+ }
+ }
+ else
+ {
+ int o = orient( gmini, gspii, gpii );
+
+ if( o > 0 )
+ {
+ int i;
+
+ for( i = 0; i < (gpii - gspii) / 2; i++ )
+ {
+ CPolyPt h = p_data[gspii + i];
+ p_data[gspii + i] = p_data[gpii - i - 1];
+ p_data[gpii - i - 1] = h;
+ }
+ }
+ }
+
+ p_data.push_back( CPolyPt( 0x80000000, mini ) );
+ pii++;
+ }
+ }
+
+ GLUtesselator* tess = gluNewTess();
+ GLdouble v_data[3];
+ g_Parm_3D_Visu.m_ActZpos =
+ g_Parm_3D_Visu.m_LayerZcoord[(g_Parm_3D_Visu.m_Layers - 1)] * 0.95;
+ v_data[2] = g_Parm_3D_Visu.m_ActZpos;
+ glColor4f( 0, 0.4, 0,
+ ( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible(
+ SOLDERMASK_N_FRONT ) ) ? 1.0 : 0.5 );
+ glNormal3f( 0.0, 0.0, 1.0 );
+ gluTessCallback( tess, GLU_TESS_BEGIN, ( void (CALLBACK*) () )mytessBeginCB );
+ gluTessCallback( tess, GLU_TESS_END, ( void (CALLBACK*) () )mytessEndCB );
+ gluTessCallback( tess, GLU_TESS_ERROR, ( void (CALLBACK*) () )mytessErrorCB );
+ gluTessCallback( tess, GLU_TESS_VERTEX, ( void (CALLBACK*) () )mytessCPolyPt2Vertex );
+ gluTessCallback( tess, GLU_TESS_COMBINE, ( void (CALLBACK*) () )mytessCombineCB );
+ gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD );
+
+ gluTessBeginPolygon( tess, NULL );
+
+ gluTessBeginContour( tess );
+
+ for( ii = 0; ii < pii; ii++ )
+ {
+ if( p_data[ii].x != (int) 0x80000000 )
+ {
+ v_data[0] = p_data[ii].x * g_Parm_3D_Visu.m_BoardScale;
+ v_data[1] = -p_data[ii].y * g_Parm_3D_Visu.m_BoardScale;
+ gluTessVertex( tess, v_data, &p_data[ii] );
+ }
+ else
+ {
+ gluTessEndContour( tess );
+ gluTessBeginContour( tess );
+ }
+ }
+
+ gluTessEndContour( tess );
+ bpii = pii;
+
+ // process holes & drills
+ Set_tmonly( 2 );
+
+ for( Module = pcb->m_Modules; Module != NULL; Module = Module->Next() )
+ {
+ D_PAD* pad;
+ int lpii;
+
+ for( pad = Module->m_Pads; pad != NULL; pad = pad->Next() )
+ {
+ lpii = pii;
+ pad->Draw3D( this );
+
+ if( pii > lpii )
+ {
+ gluTessBeginContour( tess );
+
+ for( ii = lpii; ii < pii; ii++ )
+ {
+ v_data[0] = p_data[ii].x * g_Parm_3D_Visu.m_BoardScale;
+ v_data[1] = -p_data[ii].y * g_Parm_3D_Visu.m_BoardScale;
+ gluTessVertex( tess, v_data, &p_data[ii] );
+ }
+
+ gluTessEndContour( tess );
+ p_data.push_back( CPolyPt( 0x80000000, 0 ) );
+ pii++;
+ }
+ }
+ }
+
+ // draw tracks and vias :
+ for( track = pcb->m_Track; track != NULL; track = track->Next() )
+ {
+ int lpii;
+
+ if( track->Type() == PCB_VIA_T )
+ {
+ lpii = pii;
+ Draw3D_Via( (SEGVIA*) track );
+
+ if( pii > lpii )
+ {
+ gluTessBeginContour( tess );
+
+ for( ii = lpii; ii < pii; ii++ )
+ {
+ v_data[0] = p_data[ii].x * g_Parm_3D_Visu.m_BoardScale;
+ v_data[1] = -p_data[ii].y * g_Parm_3D_Visu.m_BoardScale;
+ gluTessVertex( tess, v_data, &p_data[ii] );
+ }
+
+ gluTessEndContour( tess );
+ p_data.push_back( CPolyPt( 0x80000000, 0 ) );
+ pii++;
+ }
+ }
+ }
+
+ gluTessEndPolygon( tess );
+
+ gluDeleteTess( tess );
+
+ tess = gluNewTess();
+ g_Parm_3D_Visu.m_ActZpos = g_Parm_3D_Visu.m_Epoxy_Width * 0.05;
+ v_data[2] = g_Parm_3D_Visu.m_ActZpos;
+ glColor4f( 0, 0.4, 0,
+ ( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible(
+ SOLDERMASK_N_FRONT ) ) ? 1.0 : 0.5 );
+ glNormal3f( 0.0, 0.0, -1.0 );
+ gluTessCallback( tess, GLU_TESS_BEGIN, ( void (CALLBACK*) () )mytessBeginCB );
+ gluTessCallback( tess, GLU_TESS_END, ( void (CALLBACK*) () )mytessEndCB );
+ gluTessCallback( tess, GLU_TESS_ERROR, ( void (CALLBACK*) () )mytessErrorCB );
+ gluTessCallback( tess, GLU_TESS_VERTEX, ( void (CALLBACK*) () )mytessCPolyPt2Vertex );
+ gluTessCallback( tess, GLU_TESS_COMBINE, ( void (CALLBACK*) () )mytessCombineCB );
+ gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD );
+ gluTessBeginPolygon( tess, NULL );
+
+ gluTessBeginContour( tess );
+
+ for( ii = 0; ii < pii; ii++ )
+ {
+ if( p_data[ii].x != (int) 0x80000000 )
+ {
+ v_data[0] = p_data[ii].x * g_Parm_3D_Visu.m_BoardScale;
+ v_data[1] = -p_data[ii].y * g_Parm_3D_Visu.m_BoardScale;
+ gluTessVertex( tess, v_data, &p_data[ii] );
+ }
+ else
+ {
+ gluTessEndContour( tess );
+ gluTessBeginContour( tess );
+ }
+ }
+
+ gluTessEndContour( tess );
+ gluTessEndPolygon( tess );
+ gluDeleteTess( tess );
+
+
+ Set_tmonly( 0 );
+
+ for( Module = pcb->m_Modules; Module != NULL; Module = Module->Next() )
+ {
+ TEXTE_MODULE* ref = Module->m_Reference;
+ Module->Draw3D( this );
+ double rot = Module->GetOrientation();
+
+ // Draw Reference...
+ if( do_ref )
+ {
+ for( ; ref != NULL; ref = ref->Next() )
+ {
+ Draw3D_DrawText( ref, rot );
+ }
+ }
+ }
+
+ if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( SOLDERMASK_N_FRONT ) )
+ {
+ p_data.erase( p_data.begin() + bpii, p_data.end() );
+ pii = bpii;
+ tess = gluNewTess();
+ g_Parm_3D_Visu.m_ActZpos =
+ g_Parm_3D_Visu.m_LayerZcoord[(g_Parm_3D_Visu.m_Layers - 1)] * 1.05;
+ v_data[2] = g_Parm_3D_Visu.m_ActZpos;
+ glColor4f( 0.1, 0.25, 0.1, 0.75 );
+ glNormal3f( 0.0, 0.0, 1.0 );
+ gluTessCallback( tess, GLU_TESS_BEGIN, ( void (CALLBACK*) () )mytessBeginCB );
+ gluTessCallback( tess, GLU_TESS_END, ( void (CALLBACK*) () )mytessEndCB );
+ gluTessCallback( tess, GLU_TESS_ERROR, ( void (CALLBACK*) () )mytessErrorCB );
+ gluTessCallback( tess, GLU_TESS_VERTEX, ( void (CALLBACK*) () )mytessCPolyPt2Vertex );
+ gluTessCallback( tess, GLU_TESS_COMBINE, ( void (CALLBACK*) () )mytessCombineCB );
+ gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
+ gluTessBeginPolygon( tess, NULL );
+ gluTessBeginContour( tess );
+
+ for( ii = 0; ii < pii; ii++ )
+ {
+ if( p_data[ii].x != (int) 0x80000000 )
+ {
+ v_data[0] = p_data[ii].x * g_Parm_3D_Visu.m_BoardScale;
+ v_data[1] = -p_data[ii].y * g_Parm_3D_Visu.m_BoardScale;
+ gluTessVertex( tess, v_data, &p_data[ii] );
+ }
+ else
+ {
+ gluTessEndContour( tess );
+ gluTessBeginContour( tess );
+ }
+ }
+
+ gluTessEndContour( tess );
+ // redo for top mask....
+ Set_tmonly( 1 );
+
+ for( Module = pcb->m_Modules; Module != NULL; Module = Module->Next() )
+ {
+ D_PAD* pad;
+ int lpii;
+
+ for( pad = Module->m_Pads; pad != NULL; pad = pad->Next() )
+ {
+ lpii = pii;
+ pad->Draw3D( this );
+
+ if( pii > lpii )
+ {
+ gluTessBeginContour( tess );
+
+ for( ii = lpii; ii < pii; ii++ )
+ {
+ v_data[0] = p_data[ii].x * g_Parm_3D_Visu.m_BoardScale;
+ v_data[1] = -p_data[ii].y * g_Parm_3D_Visu.m_BoardScale;
+ gluTessVertex( tess, v_data, &p_data[ii] );
+ }
+
+ gluTessEndContour( tess );
+ }
+ }
+ }
+
+ gluTessEndPolygon( tess );
+ gluDeleteTess( tess );
+ }
+
+ if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( SOLDERMASK_N_BACK ) )
+ {
+ p_data.erase( p_data.begin() + bpii, p_data.end() );
+ pii = bpii;
+ // bottom mask
+ tess = gluNewTess();
+ g_Parm_3D_Visu.m_ActZpos = -g_Parm_3D_Visu.m_Epoxy_Width * 0.05;
+ v_data[2] = g_Parm_3D_Visu.m_ActZpos;
+ glColor4f( 0.1, 0.25, 0.1, 0.75 );
+ glNormal3f( 0.0, 0.0, -1.0 );
+ gluTessCallback( tess, GLU_TESS_BEGIN, ( void (CALLBACK*) () )mytessBeginCB );
+ gluTessCallback( tess, GLU_TESS_END, ( void (CALLBACK*) () )mytessEndCB );
+ gluTessCallback( tess, GLU_TESS_ERROR, ( void (CALLBACK*) () )mytessErrorCB );
+ gluTessCallback( tess, GLU_TESS_VERTEX, ( void (CALLBACK*) () )mytessCPolyPt2Vertex );
+ gluTessCallback( tess, GLU_TESS_COMBINE, ( void (CALLBACK*) () )mytessCombineCB );
+ gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
+ gluTessBeginPolygon( tess, NULL );
+ gluTessBeginContour( tess );
+
+ for( ii = 0; ii < pii; ii++ )
+ {
+ if( p_data[ii].x != (int) 0x80000000 )
+ {
+ v_data[0] = p_data[ii].x * g_Parm_3D_Visu.m_BoardScale;
+ v_data[1] = -p_data[ii].y * g_Parm_3D_Visu.m_BoardScale;
+ gluTessVertex( tess, v_data, &p_data[ii] );
+ }
+ else
+ {
+ gluTessEndContour( tess );
+ gluTessBeginContour( tess );
+ }
+ }
+
+ gluTessEndContour( tess );
+ // redo for top mask....
+ Set_tmonly( 3 );
+
+ for( Module = pcb->m_Modules; Module != NULL; Module = Module->Next() )
+ {
+ D_PAD* pad;
+ int lpii;
+
+ for( pad = Module->m_Pads; pad != NULL; pad = pad->Next() )
+ {
+ lpii = pii;
+ pad->Draw3D( this );
+
+ if( pii > lpii )
+ {
+ gluTessBeginContour( tess );
+
+ for( ii = lpii; ii < pii; ii++ )
+ {
+ v_data[0] = p_data[ii].x * g_Parm_3D_Visu.m_BoardScale;
+ v_data[1] = -p_data[ii].y * g_Parm_3D_Visu.m_BoardScale;
+ gluTessVertex( tess, v_data, &p_data[ii] );
+ }
+
+ gluTessEndContour( tess );
+ }
+ }
+ }
+
+ gluTessEndPolygon( tess );
+ gluDeleteTess( tess );
+ }
+
+ p_data.clear();
+ pii = 0;
}
glEndList();
@@ -381,10 +1044,10 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List(
void EDA_3D_CANVAS::Draw3D_Track( TRACK* track )
{
- double zpos;
- int layer = track->GetLayer();
- double ox, oy, fx, fy;
- double w;
+ double zpos;
+ int layer = track->GetLayer();
+ double ox, oy, fx, fy;
+ double w;
if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
return;
@@ -396,22 +1059,23 @@ void EDA_3D_CANVAS::Draw3D_Track( TRACK*
zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
- SetGLColor( color );
+ MySetGLColor( color, layer );
glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -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;
+ 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 );
}
+/* XXX TSP */
void EDA_3D_CANVAS::Draw3D_SolidPolygonsInZones( ZONE_CONTAINER* aZone )
{
- double zpos;
- int layer = aZone->GetLayer();
+ double zpos;
+ int layer = aZone->GetLayer();
if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
return;
@@ -425,24 +1089,23 @@ void EDA_3D_CANVAS::Draw3D_SolidPolygons
g_Parm_3D_Visu.m_ActZpos = zpos;
- SetGLColor( color );
+ MySetGLColor( color, layer );
glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 );
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 );
+ 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];
v_data[2] = zpos;
- //gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
-
// Draw solid areas contained in this zone
int StartContour = 1;
std::vector<CPolyPt> polysList = aZone->GetFilledPolysList();
+
for( unsigned ii = 0; ii < polysList.size(); ii++ )
{
if( StartContour == 1 )
@@ -452,8 +1115,8 @@ void EDA_3D_CANVAS::Draw3D_SolidPolygons
StartContour = 0;
}
- v_data[0] = polysList[ii].x * g_Parm_3D_Visu.m_BoardScale;
- v_data[1] = -polysList[ii].y * g_Parm_3D_Visu.m_BoardScale;
+ v_data[0] = polysList[ii].x * g_Parm_3D_Visu.m_BoardScale;
+ v_data[1] = -polysList[ii].y * g_Parm_3D_Visu.m_BoardScale;
gluTessVertex( tess, v_data, &polysList[ii] );
if( polysList[ii].end_contour == 1 )
@@ -470,84 +1133,93 @@ void EDA_3D_CANVAS::Draw3D_SolidPolygons
void EDA_3D_CANVAS::Draw3D_Via( SEGVIA* via )
{
- 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 = via->GetDrillValue();
- hole *= 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;
+ double x, y, r, hole;
+ int layer, top_layer, bottom_layer;
+ double zpos, height = 0;
+ int color;
- via->ReturnLayerPair( &top_layer, &bottom_layer );
+ r = via->m_Width * g_Parm_3D_Visu.m_BoardScale / 2;
+ hole = via->GetDrillValue();
+ hole *= 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;
- // Drawing filled circles:
- for( layer = bottom_layer; layer < g_Parm_3D_Visu.m_Layers; layer++ )
+ if( Get_tmonly() == 0 )
{
- zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
-
- if( layer < g_Parm_3D_Visu.m_Layers - 1 )
- {
- if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
- continue;
+ via->ReturnLayerPair( &top_layer, &bottom_layer );
- color = g_ColorsSettings.GetLayerColor( layer );
- }
- else
+ // Drawing filled circles:
+ for( layer = bottom_layer; layer < g_Parm_3D_Visu.m_Layers; layer++ )
{
- if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( LAYER_N_FRONT ) == false )
- continue;
+ zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
- color = g_ColorsSettings.GetLayerColor( LAYER_N_FRONT );
- }
+ if( layer < g_Parm_3D_Visu.m_Layers - 1 )
+ {
+ if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
+ continue;
- SetGLColor( color );
+ color = g_ColorsSettings.GetLayerColor( layer );
+ }
+ else
+ {
+ if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( LAYER_N_FRONT ) == false )
+ continue;
- // SetGLColor( LIGHTGRAY );
- glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 );
+ color = g_ColorsSettings.GetLayerColor( LAYER_N_FRONT );
+ }
- if( layer == LAYER_N_BACK )
- zpos = zpos - 5 * g_Parm_3D_Visu.m_BoardScale;
- else
- zpos = zpos + 5 * g_Parm_3D_Visu.m_BoardScale;
+ MySetGLColor( color, layer );
- Draw3D_FilledCircle( x, -y, r, hole, zpos );
+ glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 );
- if( layer >= top_layer )
- break;
- }
+ if( layer == LAYER_N_BACK )
+ zpos = zpos - 5 * g_Parm_3D_Visu.m_BoardScale;
+ else
+ zpos = zpos + 5 * g_Parm_3D_Visu.m_BoardScale;
+
+ Draw3D_FilledCircle( x, -y, r, hole, zpos );
+
+ if( layer >= top_layer )
+ break;
+ }
- // Drawing hole:
- color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + via->m_Shape );
- SetGLColor( color );
- 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] );
+ // Drawing hole:
+ color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + via->m_Shape );
+ MySetGLColor( color, layer );
+ 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] );
+ }
+ else
+ {
+ bottom_layer = 0;
+ Draw3D_FilledCylinderMask( x, -y, hole, height,
+ g_Parm_3D_Visu.m_LayerZcoord[bottom_layer] );
+ }
}
void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment )
{
- double x, y, xf, yf;
- double zpos, w;
+ double x, y, xf, yf;
+ double zpos, w;
- int layer = segment->GetLayer();
+ int layer = segment->GetLayer();
if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
return;
int color = g_ColorsSettings.GetLayerColor( layer );
- SetGLColor( color );
+ MySetGLColor( color, layer );
- w = segment->GetWidth() * g_Parm_3D_Visu.m_BoardScale;
+ w = segment->GetWidth() * g_Parm_3D_Visu.m_BoardScale;
- x = segment->GetStart().x * g_Parm_3D_Visu.m_BoardScale;
- y = segment->GetStart().y * g_Parm_3D_Visu.m_BoardScale;
+ x = segment->GetStart().x * g_Parm_3D_Visu.m_BoardScale;
+ y = segment->GetStart().y * g_Parm_3D_Visu.m_BoardScale;
- xf = segment->GetEnd().x * g_Parm_3D_Visu.m_BoardScale;
- yf = segment->GetEnd().y * g_Parm_3D_Visu.m_BoardScale;
+ xf = segment->GetEnd().x * g_Parm_3D_Visu.m_BoardScale;
+ yf = segment->GetEnd().y * g_Parm_3D_Visu.m_BoardScale;
if( layer == EDGE_N )
{
@@ -560,14 +1232,32 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment(
{
case S_ARC:
Draw3D_ArcSegment( x, -y, xf, -yf, segment->GetAngle(), w, zpos );
+
+ if( layer == 1 )
+ {
+ Draw3D_ArcSegmentMask( x, -y, xf, -yf, segment->GetAngle(), w, zpos );
+ }
+
break;
case S_CIRCLE:
Draw3D_CircleSegment( x, -y, xf, -yf, w, zpos );
+
+ if( layer == 1 )
+ {
+ Draw3D_CircleSegmentMask( x, y, xf, yf, w, zpos );
+ }
+
break;
default:
Draw3D_FilledSegment( x, -y, xf, -yf, w, zpos );
+
+ if( layer == 1 )
+ {
+ Draw3D_Mask( x, y, xf, yf, w, zpos );
+ }
+
break;
}
}
@@ -601,10 +1291,10 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment(
static double s_Text3DWidth, s_Text3DZPos;
static void Draw3dTextSegm( int x0, int y0, int xf, int yf )
{
- double startx = x0 * g_Parm_3D_Visu.m_BoardScale;
- double starty = y0 * g_Parm_3D_Visu.m_BoardScale;
- double endx = xf * g_Parm_3D_Visu.m_BoardScale;
- double endy = yf * g_Parm_3D_Visu.m_BoardScale;
+ double startx = x0 * g_Parm_3D_Visu.m_BoardScale;
+ double starty = y0 * g_Parm_3D_Visu.m_BoardScale;
+ double endx = xf * g_Parm_3D_Visu.m_BoardScale;
+ double endy = yf * g_Parm_3D_Visu.m_BoardScale;
Draw3D_FilledSegment( startx, -starty, endx, -endy, s_Text3DWidth, s_Text3DZPos );
}
@@ -618,10 +1308,9 @@ void EDA_3D_CANVAS::Draw3D_DrawText( TEX
return;
int color = g_ColorsSettings.GetLayerColor( layer );
-
- SetGLColor( color );
- s_Text3DZPos = g_Parm_3D_Visu.m_LayerZcoord[layer];
- s_Text3DWidth = text->GetThickness() * g_Parm_3D_Visu.m_BoardScale;
+ MySetGLColor( color, layer );
+ s_Text3DZPos = g_Parm_3D_Visu.m_LayerZcoord[layer];
+ s_Text3DWidth = text->GetThickness() * g_Parm_3D_Visu.m_BoardScale;
glNormal3f( 0.0, 0.0, Get3DLayerSide( layer ) );
wxSize size = text->m_Size;
@@ -630,9 +1319,9 @@ void EDA_3D_CANVAS::Draw3D_DrawText( TEX
if( text->m_MultilineAllowed )
{
- wxPoint pos = text->m_Pos;
- wxArrayString* list = wxStringSplit( text->m_Text, '\n' );
- wxPoint offset;
+ wxPoint pos = text->m_Pos;
+ wxArrayString* list = wxStringSplit( text->m_Text, '\n' );
+ wxPoint offset;
offset.y = text->GetInterline();
@@ -663,24 +1352,93 @@ void EDA_3D_CANVAS::Draw3D_DrawText( TEX
}
+void EDA_3D_CANVAS::Draw3D_DrawText( TEXTE_MODULE* text, double rot )
+{
+ int layer = text->GetLayer();
+
+ int color = g_ColorsSettings.GetLayerColor( layer );
+
+ MySetGLColor( color, layer );
+ s_Text3DZPos = g_Parm_3D_Visu.m_LayerZcoord[layer];
+ s_Text3DWidth = text->GetThickness() * g_Parm_3D_Visu.m_BoardScale;
+ glNormal3f( 0.0, 0.0, Get3DLayerSide( layer ) );
+ wxSize size = text->m_Size;
+
+ if( text->m_Mirror )
+ NEGATE( size.x );
+
+ if( text->m_MultilineAllowed )
+ {
+ wxPoint pos = text->m_Pos;
+ wxArrayString* list = wxStringSplit( text->m_Text, '\n' );
+ wxPoint offset;
+ double newrot = text->GetOrientation() + rot;
+
+ while( newrot < -900.0 )
+ newrot += 1800.0;
+
+ while( newrot > 900.0 )
+ newrot -= 1800.0;
+
+ offset.y = text->GetInterline();
+
+ RotatePoint( &offset, text->GetOrientation() + rot );
+
+ for( unsigned i = 0; i<list->Count(); i++ )
+ {
+ wxString txt = list->Item( i );
+ DrawGraphicText( NULL, NULL, pos, (EDA_COLOR_T) color,
+ txt, newrot, size,
+ text->m_HJustify, text->m_VJustify,
+ text->GetThickness(), text->m_Italic,
+ true, Draw3dTextSegm );
+ pos += offset;
+ }
+
+ delete list;
+ }
+ else
+ {
+ double newrot = text->GetOrientation() + rot;
+
+ while( newrot < -900.0 )
+ newrot += 1800.0;
+
+ while( newrot > 900.0 )
+ newrot -= 1800.0;
+
+ DrawGraphicText( NULL, NULL, text->m_Pos, (EDA_COLOR_T) color,
+ text->m_Text, newrot, size,
+ text->m_HJustify, text->m_VJustify,
+ text->GetThickness(), text->m_Italic,
+ true,
+ Draw3dTextSegm );
+ }
+}
+
+
void MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
{
D_PAD* pad = m_Pads;
// Draw pads
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
- glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
+ glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
+
for( ; pad != NULL; pad = pad->Next() )
{
pad->Draw3D( glcanvas );
}
+ if( Get_tmonly() )
+ return;
+
// Draw module shape: 3D shape if exists (or module outlines if not exists)
- S3D_MASTER* Struct3D = m_3D_Drawings;
- bool As3dShape = false;
+ S3D_MASTER* Struct3D = m_3D_Drawings;
+ bool As3dShape = false;
- if (g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_MODULE])
+ if( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_MODULE] )
{
glPushMatrix();
@@ -705,8 +1463,109 @@ void MODULE::Draw3D( EDA_3D_CANVAS* glca
{
if( !Struct3D->m_Shape3DName.IsEmpty() )
{
+ std::vector<S3D_Vertex> minmax;
+ Struct3D->m_MinPos.x = Struct3D->m_MinPos.y = Struct3D->m_MinPos.z = 1E30;
+ Struct3D->m_MaxPos.x = Struct3D->m_MaxPos.y = Struct3D->m_MaxPos.z = -1E30;
As3dShape = true;
Struct3D->ReadData();
+ minmax.push_back( Struct3D->m_MinPos );
+ minmax.push_back( Struct3D->m_MaxPos );
+ Struct3D->Set_Object_Coords( minmax );
+ double hi = minmax[1].y - minmax[0].y;
+ double hix = minmax[1].x - minmax[0].x;
+
+ if( hi < 0 )
+ hi = -hi;
+
+ if( hix < 0 )
+ hix = -hix;
+
+ if( do_values )
+ {
+ wxString txt = m_Value->m_Text;
+ wxPoint pos;
+ wxSize size;
+ pos.x = 0;
+ pos.y = 0;
+
+ if( hi > 0.5 )
+ hi = 0.5;
+
+ size.x = (int) (hi * 300);
+ size.y = (int) (hi * 300);
+ glPushMatrix();
+ glTranslatef( 0,
+ 0,
+ g_Parm_3D_Visu.m_BoardScale * minmax[1].z * 1000.0 - 0 *
+ g_Parm_3D_Visu.m_LayerZcoord[m_Layer] );
+ glColor4f( 0.2, 0.2, 0.2, 0.7 );
+ s_Text3DWidth = 100 * g_Parm_3D_Visu.m_BoardScale;
+ s_Text3DZPos = g_Parm_3D_Visu.m_BoardScale * 9;
+ glTranslatef(
+ g_Parm_3D_Visu.m_BoardScale * 1000 * (minmax[1].x + minmax[0].x) / 2,
+ g_Parm_3D_Visu.m_BoardScale * 1000 * (minmax[1].y + minmax[0].y) / 2,
+ 0 );
+ double o = m_Orient;
+ double ro = 0;
+
+ while( o < -900.0 )
+ {
+ o += 1800.0; ro += 180;
+ }
+
+ while( o > 900.0 )
+ {
+ o -= 1800.0; ro -= 180;
+ }
+
+ glRotatef( -ro, 0.0, 0.0, 1.0 );
+ double bscf = g_Parm_3D_Visu.m_BoardScale;
+ double scf = 1e-4;
+ double pw = scf * 1000 * fabs( minmax[1].x - minmax[0].x );
+ double ph = scf * 1000 * fabs( minmax[1].y - minmax[0].y );
+ double slen = NegableTextLength( txt );
+
+ if( slen > 0 )
+ {
+ size.x = (int) ( (10000 * pw) / (slen + 1) );
+
+ if( size.x < 100 )
+ size.x = 100;
+
+ if( size.x > 400 )
+ size.x = 400;
+
+ size.y = (size.x * 120) / 100;
+
+ if( size.y > 10000.0 * ph / 1.8 )
+ {
+ size.y = (int) ( (10000.0 * ph / 1.8) );
+ size.x = (size.y * 100) / 120;
+ }
+
+ pw = size.x * (slen) * bscf;
+ double ph = 1.5 * size.y * bscf;
+ {
+ glBegin( GL_POLYGON );
+ glVertex3f( pw / 2, ph / 2, s_Text3DZPos );
+ glVertex3f( pw / 2, -ph / 2, s_Text3DZPos );
+ glVertex3f( -pw / 2, -ph / 2, s_Text3DZPos );
+ glVertex3f( -pw / 2, ph / 2, s_Text3DZPos );
+ glEnd();
+ }
+ glColor3f( 0.8, 0.8, 0.8 );
+ glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
+ s_Text3DZPos = g_Parm_3D_Visu.m_BoardScale * 10;
+ s_Text3DWidth = 20 * g_Parm_3D_Visu.m_BoardScale;
+ DrawGraphicText( NULL, NULL, pos, RED,
+ txt, 0, size,
+ GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
+ 20, 0, true,
+ Draw3dTextSegm );
+ }
+
+ glPopMatrix();
+ }
}
}
@@ -714,7 +1573,7 @@ void MODULE::Draw3D( EDA_3D_CANVAS* glca
}
EDA_ITEM* Struct = m_Drawings;
- glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
+ glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
for( ; Struct != NULL; Struct = Struct->Next() )
{
@@ -724,15 +1583,16 @@ void MODULE::Draw3D( EDA_3D_CANVAS* glca
break;
case PCB_MODULE_EDGE_T:
- {
- EDGE_MODULE* edge = (EDGE_MODULE*) Struct;
+ {
+ EDGE_MODULE* edge = (EDGE_MODULE*) Struct;
- // Draw module edges when no 3d shape exists.
- // Always draw pcb edges.
- if( !As3dShape || edge->GetLayer() == EDGE_N )
- edge->Draw3D( glcanvas );
- }
- break;
+ // Draw module edges when no 3d shape exists.
+ // Always draw pcb edges.
+ /* if( !As3dShape || edge->GetLayer() == EDGE_N ) */ {
+ edge->Draw3D( glcanvas );
+ }
+ }
+ break;
default:
break;
@@ -743,24 +1603,24 @@ void MODULE::Draw3D( EDA_3D_CANVAS* glca
void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
{
- wxString s;
- int dx, dy;
- double x, y, fx, fy, w, zpos;
+ wxString s;
+ int dx, dy;
+ double x, y, fx, fy, w, zpos;
if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( m_Layer ) == false )
return;
int color = g_ColorsSettings.GetLayerColor( m_Layer );
- SetGLColor( color );
+ MySetGLColor( color, m_Layer );
- dx = m_End.x;
- dy = m_End.y;
- w = m_Width * g_Parm_3D_Visu.m_BoardScale;
- 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;
+ dx = m_End.x;
+ dy = m_End.y;
+ w = m_Width * g_Parm_3D_Visu.m_BoardScale;
+ 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;
if( m_Layer == EDGE_N )
@@ -785,26 +1645,26 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS*
break;
case S_POLYGON:
- {
- // We must compute true coordinates from m_PolyPoints
- // which are relative to module position and module orientation = 0
- std::vector<wxPoint> points = m_PolyPoints;
- MODULE* module = (MODULE*) m_Parent;
+ {
+ // We must compute true coordinates from m_PolyPoints
+ // which are relative to module position and module orientation = 0
+ std::vector<wxPoint> points = m_PolyPoints;
+ MODULE* module = (MODULE*) m_Parent;
- if( module == NULL )
- break;
+ if( module == NULL )
+ break;
- for( unsigned ii = 0; ii < points.size(); ii++ )
- {
- wxPoint& pt = points[ii];
+ for( unsigned ii = 0; ii < points.size(); ii++ )
+ {
+ wxPoint& pt = points[ii];
- RotatePoint( &pt.x, &pt.y, module->GetOrientation() );
- pt += module->m_Pos;
- }
+ RotatePoint( &pt.x, &pt.y, module->GetOrientation() );
+ pt += module->m_Pos;
+ }
- glcanvas->Draw3D_Polygon( points, zpos );
- }
- break;
+ glcanvas->Draw3D_Polygon( points, zpos );
+ }
+ break;
default:
s.Printf( wxT( "Error: Shape nr %d not implemented!\n" ), m_Shape );
@@ -815,7 +1675,9 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS*
}
else
{
- glNormal3f( 0.0, 0.0, (m_Layer == LAYER_N_BACK) ? -1.0 : 1.0 );
+ glNormal3f( 0.0,
+ 0.0,
+ ( (m_Layer == LAYER_N_BACK) || (m_Layer == SILKSCREEN_N_BACK) ) ? -1.0 : 1.0 );
zpos = g_Parm_3D_Visu.m_LayerZcoord[m_Layer];
switch( m_Shape )
@@ -833,26 +1695,26 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS*
break;
case S_POLYGON:
- {
- // We must compute true coordinates from m_PolyPoints
- // which are relative to module position and module orientation = 0
- std::vector<wxPoint> points = m_PolyPoints;
- MODULE* module = (MODULE*) m_Parent;
+ {
+ // We must compute true coordinates from m_PolyPoints
+ // which are relative to module position and module orientation = 0
+ std::vector<wxPoint> points = m_PolyPoints;
+ MODULE* module = (MODULE*) m_Parent;
- if( module == NULL )
- break;
+ if( module == NULL )
+ break;
- for( unsigned ii = 0; ii < points.size(); ii++ )
- {
- wxPoint& pt = points[ii];
+ for( unsigned ii = 0; ii < points.size(); ii++ )
+ {
+ wxPoint& pt = points[ii];
- RotatePoint( &pt.x, &pt.y, module->GetOrientation() );
- pt += module->m_Pos;
- }
+ RotatePoint( &pt.x, &pt.y, module->GetOrientation() );
+ pt += module->m_Pos;
+ }
- glcanvas->Draw3D_Polygon( points, zpos );
- }
- break;
+ glcanvas->Draw3D_Polygon( points, zpos );
+ }
+ break;
default:
s.Printf( wxT( "Error: Shape nr %d not implemented!\n" ), m_Shape );
@@ -879,46 +1741,258 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcan
double drillx, drilly;
bool Oncu, Oncmp, Both;
int color;
-
- scale = g_Parm_3D_Visu.m_BoardScale;
- holeX = (double) m_Drill.x * scale / 2;
- holeY = (double) m_Drill.y * scale / 2;
- hole = fmin( holeX, holeY );
+ double rm = GetSolderMaskMargin();
+ wxSize rp = GetSolderPasteMargin();
+ double offX, offY;
+
+ scale = g_Parm_3D_Visu.m_BoardScale;
+ holeX = (double) m_Drill.x * scale / 2;
+ holeY = (double) m_Drill.y * scale / 2;
+ offX = (double) m_Offset.x * scale;
+ offY = (double) m_Offset.y * scale;
+ hole = fmin( holeX, holeY );
// Calculate the center of the pad.
- shape_pos = ReturnShapePos();
+ // shape_pos = ReturnShapePos();
+ shape_pos = m_Pos;
ux0 = shape_pos.x;
uy0 = shape_pos.y;
xc = ux0;
yc = uy0;
- dx = dx0 = m_Size.x >> 1;
- dy = dy0 = m_Size.y >> 1;
+ dx = dx0 = m_Size.x / 2;
+ dy = dy0 = m_Size.y / 2;
+
+ angle = m_Orient;
+ drillx = m_Pos.x * scale;
+ drilly = m_Pos.y * scale;
+
+ if( (tmonly & 1) == 1 )
+ {
+ // glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
+ nlmax = g_Parm_3D_Visu.m_Layers - 1;
+ Oncu = (m_layerMask & LAYER_BACK) ? true : false;
+ Oncmp = (m_layerMask & LAYER_FRONT) ? true : false;
+ Both = Oncu && Oncmp;
+
+ switch( m_PadShape & 0x7F )
+ {
+ case PAD_CIRCLE:
+ x = xc * scale;
+ y = yc * scale;
+ r = (double) dx * scale;
+ rm *= scale;
+
+ layer = (tmonly & 2) ? SOLDERMASK_N_BACK : SOLDERMASK_N_FRONT;
+
+ if( ( (1 << layer) & m_layerMask ) != 0 )
+ {
+ #define ZLO ( 9 - ( (layer & 6) >> 1 ) )
+ Draw3D_FilledCircleMask( x, -y, r + rm, hole, zpos );
+ }
+ break;
+
+ case PAD_OVAL:
+ rm *= scale;
+
+ if( dx > dy ) // Horizontal ellipse
+ {
+ delta_cx = dx - dy;
+ delta_cy = 0;
+ w = m_Size.y * scale;
+ }
+ else // Vertical ellipse
+ {
+ delta_cx = 0;
+ delta_cy = dy - dx;
+ w = m_Size.x * scale;
+ }
+
+ 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;
+
+ layer = (tmonly & 2) ? SOLDERMASK_N_BACK : SOLDERMASK_N_FRONT;
+
+ if( ( (1 << layer) & m_layerMask ) != 0 )
+ {
+ RotatePoint( &offX, &offY, angle );
+ Draw3D_FilledSegmentWithHoleMask( ox,
+ -oy,
+ fx,
+ -fy,
+ w + rm,
+ drillx,
+ -drilly,
+ hole,
+ zpos,
+ offX,
+ offY );
+ }
+ }
+ break;
+
+ case PAD_RECT:
+ case PAD_TRAPEZOID:
+ {
+ wxPoint coord[5];
+ wxRealPoint fcoord[8], f_hole_coord[8];
+ layer = (tmonly & 2) ? SOLDERMASK_N_BACK : SOLDERMASK_N_FRONT;
+
+ if( ( (1 << layer) & m_layerMask ) != 0 )
+ {
+ wxSize lrp;
+ lrp.x = rm;
+ lrp.y = rm;
+ BuildPadPolygon( coord, lrp, angle );
+
+ for( ii = 0; ii < 4; ii++ )
+ {
+ coord[ii].x += ux0;
+ coord[ii].y += uy0;
+ ll = ii * 2;
+ fcoord[ll].x = coord[ii].x * scale;
+ fcoord[ll].y = coord[ii].y * scale;
+ }
+
+ for( ii = 0; ii < 7; ii += 2 )
+ {
+ ll = ll + 2;
+
+ if( ll > 7 )
+ ll -= 8;
+
+ fcoord[ii + 1].x = (fcoord[ii].x + fcoord[ll].x) / 2;
+ fcoord[ii + 1].y = (fcoord[ii].y + fcoord[ll].y) / 2;
+ }
+
+ for( ii = 0; ii < 8; ii++ )
+ {
+ f_hole_coord[ii].x = -hole * 0.707;
+ f_hole_coord[ii].y = hole * 0.707;
+ RotatePoint( &f_hole_coord[ii].x, &f_hole_coord[ii].y, angle -
+ (ii * 450) );
+ f_hole_coord[ii].x += drillx;
+ f_hole_coord[ii].y += drilly;
+ }
+
+ for( ii = 0; ii < 4; ii++ )
+ {
+ p_data.push_back( CPolyPt( coord[ii].x, coord[ii].y ) );
+ pii++;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return;
+ }
+ else if( tmonly == 2 )
+ {
+ // Draw the pad hole
+ if( holeX && holeY )
+ {
+ if( holeX == holeY )
+ {
+ Draw3D_FilledCylinderMask( drillx, -drilly, hole,
+ g_Parm_3D_Visu.m_LayerZcoord[LAYER_N_FRONT], 0.0 );
+ }
+ else
+ {
+ if( dx > dy ) // Horizontal oval
+ {
+ delta_cx = dx - dy;
+ delta_cy = 0;
+ w = m_Size.y * scale;
+ }
+ else // Vertical oval
+ {
+ delta_cx = 0;
+ delta_cy = dy - dx;
+ w = m_Size.x * scale;
+ }
+
+ 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;
+
+ double height = g_Parm_3D_Visu.m_LayerZcoord[LAYER_N_FRONT];
+ Draw3D_FilledOblongMask( ox, -oy, fx, -fy, drillx, -drilly, hole, height,
+ 0.0 );
+ }
+ }
+ }
- angle = m_Orient;
- drillx = m_Pos.x * scale;
- drilly = m_Pos.y * scale;
+ return;
+ }
- // Draw the pad hole (TODO: draw OBLONG hole)
+ // Draw the pad hole
if( holeX && holeY )
{
SetGLColor( DARKGRAY );
- Draw3D_FilledCylinder( drillx, -drilly, hole,
- g_Parm_3D_Visu.m_LayerZcoord[LAYER_N_FRONT], 0.0 );
+
+ if( holeX == holeY )
+ {
+ Draw3D_FilledCylinder( drillx, -drilly, hole,
+ g_Parm_3D_Visu.m_LayerZcoord[LAYER_N_FRONT], 0.0 );
+ }
+ else
+ {
+ if( dx > dy ) // Horizontal oval
+ {
+ delta_cx = dx - dy;
+ delta_cy = 0;
+ w = m_Size.y * scale;
+ }
+ else // Vertical oval
+ {
+ delta_cx = 0;
+ delta_cy = dy - dx;
+ w = m_Size.x * scale;
+ }
+
+ 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;
+
+ double height = g_Parm_3D_Visu.m_LayerZcoord[LAYER_N_FRONT];
+ Draw3D_FilledOblong( ox, -oy, fx, -fy, drillx, -drilly, hole, height, 0.0 );
+ }
+ }
}
- glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
- nlmax = g_Parm_3D_Visu.m_Layers - 1;
- Oncu = (m_layerMask & LAYER_BACK) ? true : false;
- Oncmp = (m_layerMask & LAYER_FRONT) ? true : false;
- Both = Oncu && Oncmp;
+ glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
+ nlmax = g_Parm_3D_Visu.m_Layers - 1;
+ Oncu = (m_layerMask & LAYER_BACK) ? true : false;
+ Oncmp = (m_layerMask & LAYER_FRONT) ? true : false;
+ Both = Oncu && Oncmp;
switch( m_PadShape & 0x7F )
{
case PAD_CIRCLE:
- x = xc * scale;
- y = yc * scale;
- r = (double) dx * scale;
+ x = xc * scale;
+ y = yc * scale;
+ r = (double) dx * scale;
+ rp *= scale;
+ rm *= scale;
for( layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; layer++ )
{
@@ -939,31 +2013,65 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcan
if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
continue;
- SetGLColor( color );
+ MySetGLColor( color, layer );
glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 );
zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
+ Draw3D_FilledCircle( x, -y, r, hole, zpos );
+ }
- if( layer == LAYER_N_BACK )
- zpos = zpos - 5 * g_Parm_3D_Visu.m_BoardScale;
+#ifdef TSP_20120407
+
+ for( layer = FIRST_NO_COPPER_LAYER; layer <= SILKSCREEN_N_FRONT; layer++ )
+ {
+ if( ( (1 << layer) & m_layerMask ) == 0 )
+ continue;
+
+ color = g_ColorsSettings.GetLayerColor( layer );
+
+
+ if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
+ continue;
+
+ MySetGLColor( color, layer );
+ glNormal3f( 0.0, 0.0, (layer & 1) ? 1.0 : -1.0 );
+ zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
+
+ if( (layer & 1) == 0 )
+ zpos = zpos - ZLO * g_Parm_3D_Visu.m_BoardScale;
else
- zpos = zpos + 5 * g_Parm_3D_Visu.m_BoardScale;
+ zpos = zpos + ZLO * g_Parm_3D_Visu.m_BoardScale;
- Draw3D_FilledCircle( x, -y, r, hole, zpos );
+ if( (layer == SOLDERPASTE_N_BACK) || (layer == SOLDERPASTE_N_FRONT) )
+ {
+ Draw3D_FilledCircle( x, -y, r + rp.x, hole, zpos );
+ }
+ else if( (layer == SILKSCREEN_N_BACK) || (layer == SILKSCREEN_N_FRONT) )
+ {
+ }
+ else
+ {
+ Draw3D_FilledCircle( x, -y, r, hole, zpos );
+ }
}
+#endif // TSP_20120407
+
break;
case PAD_OVAL:
- if( dx > dy ) // Horizontal ellipse
+ rp *= scale;
+ rm *= scale;
+
+ if( dx > dy ) // Horizontal ellipse
{
- delta_cx = dx - dy;
- delta_cy = 0;
+ delta_cx = dx - dy;
+ delta_cy = 0;
w = m_Size.y * scale;
}
- else // Vertical ellipse
+ else // Vertical ellipse
{
- delta_cx = 0;
- delta_cy = dy - dx;
+ delta_cx = 0;
+ delta_cy = dy - dx;
w = m_Size.x * scale;
}
@@ -971,10 +2079,10 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcan
{
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;
+ 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 = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; layer++ )
{
@@ -996,7 +2104,7 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcan
if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
continue;
- SetGLColor( color );
+ MySetGLColor( color, layer );
zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
if( layer == LAYER_N_BACK )
@@ -1004,90 +2112,292 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcan
else
zpos = zpos + 5 * g_Parm_3D_Visu.m_BoardScale;
- Draw3D_FilledSegmentWithHole( ox, -oy, fx, -fy, w, drillx, -drilly, hole, zpos );
+ RotatePoint( &offX, &offY, angle );
+
+ if( holeX == holeY )
+ {
+ Draw3D_FilledSegmentWithHole( ox,
+ -oy,
+ fx,
+ -fy,
+ w,
+ drillx,
+ -drilly,
+ hole,
+ zpos,
+ offX,
+ offY );
+ }
+ else
+ {
+ if( dx > dy ) // Horizontal oval
+ {
+ delta_cx = dx - dy;
+ delta_cy = 0;
+ w = m_Size.y * scale;
+ }
+ else // Vertical oval
+ {
+ delta_cx = 0;
+ delta_cy = dy - dx;
+ w = m_Size.x * scale;
+ }
+
+ 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;
+
+ Draw3D_FilledSegmentWithHole( ox,
+ -oy,
+ fx,
+ -fy,
+ w,
+ drillx,
+ -drilly,
+ hole,
+ zpos,
+ offX,
+ offY );
+ }
+ }
+ }
+
+#ifdef TSP_20120407
+
+ for( layer = FIRST_NO_COPPER_LAYER; layer <= SILKSCREEN_N_FRONT; layer++ )
+ {
+ if( ( (1 << layer) & m_layerMask ) == 0 )
+ continue;
+
+ if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
+ continue;
+
+ color = g_ColorsSettings.GetLayerColor( layer );
+ glNormal3f( 0.0, 0.0, (layer & 1) ? 1.0 : -1.0 );
+
+ SetGLColor( color );
+ zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
+
+ if( layer & 1 )
+ zpos = zpos + ZLO * g_Parm_3D_Visu.m_BoardScale;
+ else
+ zpos = zpos - ZLO * g_Parm_3D_Visu.m_BoardScale;
+
+ RotatePoint( &offX, &offY, angle );
+
+ if( (layer == SOLDERPASTE_N_BACK) || (layer == SOLDERPASTE_N_FRONT) )
+ {
+ Draw3D_FilledSegmentWithHole( ox,
+ -oy,
+ fx,
+ -fy,
+ w + rp.x,
+ drillx,
+ -drilly,
+ hole,
+ zpos,
+ offX,
+ offY );
+ }
+ else if( (layer == SILKSCREEN_N_BACK) || (layer == SILKSCREEN_N_FRONT) )
+ {
+ }
+ else
+ {
+ Draw3D_FilledSegmentWithHole( ox,
+ -oy,
+ fx,
+ -fy,
+ w,
+ drillx,
+ -drilly,
+ hole,
+ zpos,
+ offX,
+ offY );
+ }
}
+
+#endif // TSP_20120407
}
break;
case PAD_RECT:
case PAD_TRAPEZOID:
- {
- wxPoint coord[5];
- wxRealPoint fcoord[8], f_hole_coord[8];
- BuildPadPolygon( coord, wxSize(0,0), angle );
-
- for( ii = 0; ii < 4; ii++ )
{
- coord[ii].x += ux0;
- coord[ii].y += uy0;
- ll = ii * 2;
- fcoord[ll].x = coord[ii].x *scale;
- fcoord[ll].y = coord[ii].y *scale;
- }
+ wxPoint coord[5];
+ wxRealPoint fcoord[8], f_hole_coord[8];
+ {
+ BuildPadPolygon( coord, wxSize( 0, 0 ), angle );
- for( ii = 0; ii < 7; ii += 2 )
- {
- ll = ii + 2;
+ for( ii = 0; ii < 4; ii++ )
+ {
+ coord[ii].x += ux0;
+ coord[ii].y += uy0;
+ ll = ii * 2;
+ fcoord[ll].x = coord[ii].x * scale;
+ fcoord[ll].y = coord[ii].y * scale;
+ }
+
+ for( ii = 0; ii < 7; ii += 2 )
+ {
+ ll = ll + 2;
- if( ll > 7 )
- ll -= 8;
+ if( ll > 7 )
+ ll -= 8;
- fcoord[ii + 1].x = (fcoord[ii].x + fcoord[ll].x) / 2;
- fcoord[ii + 1].y = (fcoord[ii].y + fcoord[ll].y) / 2;
- }
+ fcoord[ii + 1].x = (fcoord[ii].x + fcoord[ll].x) / 2;
+ fcoord[ii + 1].y = (fcoord[ii].y + fcoord[ll].y) / 2;
+ }
- for( ii = 0; ii < 8; ii++ )
- {
- f_hole_coord[ii].x = -hole * 0.707;
- f_hole_coord[ii].y = hole * 0.707;
- RotatePoint( &f_hole_coord[ii].x, &f_hole_coord[ii].y, angle - (ii * 450) );
- f_hole_coord[ii].x += drillx;
- f_hole_coord[ii].y += drilly;
- }
+ for( ii = 0; ii < 8; ii++ )
+ {
+ f_hole_coord[ii].x = -hole * 0.707;
+ f_hole_coord[ii].y = hole * 0.707;
+ RotatePoint( &f_hole_coord[ii].x, &f_hole_coord[ii].y, angle - (ii * 450) );
+ f_hole_coord[ii].x += drillx;
+ f_hole_coord[ii].y += drilly;
+ }
+ }
- for( layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; layer++ )
- {
- if( layer && (layer == nlmax) )
- layer = LAYER_N_FRONT;
+ for( layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; layer++ )
+ {
+ if( layer && (layer == nlmax) )
+ layer = LAYER_N_FRONT;
- if( (layer == LAYER_N_FRONT) && !Oncmp )
- continue;
+ if( (layer == LAYER_N_FRONT) && !Oncmp )
+ continue;
- if( (layer == LAYER_N_BACK) && !Oncu )
- continue;
+ if( (layer == LAYER_N_BACK) && !Oncu )
+ continue;
- if( (layer > FIRST_COPPER_LAYER) && (layer < LAST_COPPER_LAYER) && !Both )
- continue;
+ if( (layer > FIRST_COPPER_LAYER) && (layer < LAST_COPPER_LAYER) && !Both )
+ continue;
- color = g_ColorsSettings.GetLayerColor( layer );
- glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 );
+ color = g_ColorsSettings.GetLayerColor( layer );
+ glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 );
- if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
- continue;
+ if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
+ continue;
- SetGLColor( color );
- zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
+ MySetGLColor( color, layer );
+ zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
- if( layer == LAYER_N_BACK )
- zpos = zpos - 5 * g_Parm_3D_Visu.m_BoardScale;
- else
- zpos = zpos + 5 * g_Parm_3D_Visu.m_BoardScale;
+ if( layer == LAYER_N_BACK )
+ zpos = zpos - 5 * g_Parm_3D_Visu.m_BoardScale;
+ else
+ zpos = zpos + 5 * g_Parm_3D_Visu.m_BoardScale;
+
+ glBegin( GL_QUAD_STRIP );
+
+ for( ii = 0; ii < 8; ii++ )
+ {
+ glVertex3f( f_hole_coord[ii].x, -f_hole_coord[ii].y, zpos );
+ glVertex3f( fcoord[ii].x, -fcoord[ii].y, zpos );
+ }
+
+ glVertex3f( f_hole_coord[0].x, -f_hole_coord[0].y, zpos );
+ glVertex3f( fcoord[0].x, -fcoord[0].y, zpos );
+ glEnd();
+ }
- glBegin( GL_QUAD_STRIP );
+#ifdef TSP_20120407
- for( ii = 0; ii < 8; ii++ )
+ for( layer = FIRST_NO_COPPER_LAYER; layer <= SILKSCREEN_N_FRONT; layer++ )
{
- glVertex3f( f_hole_coord[ii].x, -f_hole_coord[ii].y, zpos );
- glVertex3f( fcoord[ii].x, -fcoord[ii].y, zpos );
+ if( ( (1 << layer) & m_layerMask ) == 0 )
+ continue;
+
+ color = g_ColorsSettings.GetLayerColor( layer );
+
+ glNormal3f( 0.0, 0.0, (layer & 1) ? 1.0 : -1.0 );
+
+ if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) == false )
+ continue;
+
+ {
+ wxSize lrp;
+
+ if( (layer == SOLDERPASTE_N_BACK) || (layer == SOLDERPASTE_N_FRONT) )
+ {
+ lrp = rp;
+ }
+ else
+ {
+ lrp.x = 0;
+ lrp.y = 0;
+ }
+
+ BuildPadPolygon( coord, lrp, angle );
+
+ for( ii = 0; ii < 4; ii++ )
+ {
+ coord[ii].x += ux0;
+ coord[ii].y += uy0;
+ ll = ii * 2;
+ fcoord[ll].x = coord[ii].x * scale;
+ fcoord[ll].y = coord[ii].y * scale;
+ }
+
+ for( ii = 0; ii < 7; ii += 2 )
+ {
+ ll = ll + 2;
+
+ if( ll > 7 )
+ ll -= 8;
+
+ fcoord[ii + 1].x = (fcoord[ii].x + fcoord[ll].x) / 2;
+ fcoord[ii + 1].y = (fcoord[ii].y + fcoord[ll].y) / 2;
+ }
+
+ for( ii = 0; ii < 8; ii++ )
+ {
+ f_hole_coord[ii].x = -hole * 0.707;
+ f_hole_coord[ii].y = hole * 0.707;
+ RotatePoint( &f_hole_coord[ii].x, &f_hole_coord[ii].y, angle -
+ (ii * 450) );
+ f_hole_coord[ii].x += drillx;
+ f_hole_coord[ii].y += drilly;
+ }
+ }
+
+ SetGLColor( color );
+ zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
+
+ if( layer & 1 )
+ zpos = zpos + ZLO * g_Parm_3D_Visu.m_BoardScale;
+ else
+ zpos = zpos - ZLO * g_Parm_3D_Visu.m_BoardScale;
+
+ if( (layer == SILKSCREEN_N_BACK) || (layer == SILKSCREEN_N_FRONT) )
+ {
+ }
+ else
+ {
+ glBegin( GL_QUAD_STRIP );
+ {
+ for( ii = 0; ii < 8; ii++ )
+ {
+ glVertex3f( f_hole_coord[ii].x, -f_hole_coord[ii].y, zpos );
+ glVertex3f( fcoord[ii].x, -fcoord[ii].y, zpos );
+ }
+
+ glVertex3f( f_hole_coord[0].x, -f_hole_coord[0].y, zpos );
+ glVertex3f( fcoord[0].x, -fcoord[0].y, zpos );
+ }
+ glEnd();
+ }
}
- glVertex3f( f_hole_coord[0].x, -f_hole_coord[0].y, zpos );
- glVertex3f( fcoord[0].x, -fcoord[0].y, zpos );
- glEnd();
+#endif // TSP_20120407
}
- }
- break;
+ break;
default:
break;
@@ -1097,32 +2407,53 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcan
void SetGLColor( int color )
{
- double red, green, blue;
+ 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;
+ red = colordata.m_Red / 255.0;
+ blue = colordata.m_Blue / 255.0;
+ green = colordata.m_Green / 255.0;
glColor3f( red, green, blue );
}
+void MySetGLColor( int color, int layer )
+{
+ double red, green, blue;
+ StructColors colordata = ColorRefs[color & MASKCOLOR];
+
+ if( ( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( SOLDERMASK_N_FRONT )
+ || g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( SOLDERMASK_N_FRONT ) )
+ && (layer < 16) )
+ {
+ glColor3f( 0.6, 0.55, 0.2 );
+ }
+ else
+ {
+ red = colordata.m_Red / 255.0;
+ blue = colordata.m_Blue / 255.0;
+ green = colordata.m_Green / 255.0;
+ glColor3f( red, green, blue );
+ }
+}
+
+
static void Draw3D_FilledCircle( double posx, double posy,
double rayon, double hole, double zpos )
{
- int ii, slice = 16;
+ int ii, slice = 16;
double x, y;
glBegin( GL_QUAD_STRIP );
for( ii = 0; ii <= slice; ii++ )
{
- x = hole;
- y = 0.0;
+ x = hole;
+ y = 0.0;
RotatePoint( &x, &y, ii * 225 );
glVertex3f( x + posx, y + posy, zpos );
- x = rayon;
- y = 0.0;
+ x = rayon;
+ y = 0.0;
RotatePoint( &x, &y, ii * 225 );
glVertex3f( x + posx, y + posy, zpos );
}
@@ -1131,19 +2462,39 @@ static void Draw3D_FilledCircle( double
}
+static void Draw3D_FilledCircleMask( double posx, double posy,
+ double rayon, double hole, double zpos )
+{
+ int ii, slice = 16;
+ double x, y;
+
+ for( ii = 0; ii <= slice; ii++ )
+ {
+ x = rayon;
+ y = 0.0;
+ RotatePoint( &x, &y, ii * 225.0 );
+ x = (x + posx) / g_Parm_3D_Visu.m_BoardScale;
+ y = -( (y + posy) / g_Parm_3D_Visu.m_BoardScale );
+
+ p_data.push_back( CPolyPt( (int) x, (int) y ) );
+ pii++;
+ }
+}
+
+
static void Draw3D_FilledCylinder( double posx, double posy, double rayon,
double height, double zpos )
{
- int ii;
- double x, y;
+ int ii;
+ double x, y;
#define NB_SEGM 12
- std::vector< S3D_Vertex > coords;
+ std::vector<S3D_Vertex> coords;
coords.resize( 4 );
- double tmp = DataScale3D;
+ double tmp = DataScale3D;
- DataScale3D = 1.0; // Coordinate is already in range for Set_Object_Data();
+ DataScale3D = 1.0; // Coordinate is already in range for Set_Object_Data();
coords[0].x = coords[1].x = posx + rayon;
coords[0].y = coords[1].y = posy;
coords[0].z = coords[3].z = zpos;
@@ -1151,8 +2502,8 @@ static void Draw3D_FilledCylinder( doubl
for( ii = 0; ii <= NB_SEGM; ii++ )
{
- x = rayon;
- y = 0.0;
+ x = rayon;
+ y = 0.0;
RotatePoint( &x, &y, ii * (3600 / NB_SEGM) );
coords[2].x = coords[3].x = posx + x;
coords[2].y = coords[3].y = posy + y;
@@ -1163,23 +2514,175 @@ static void Draw3D_FilledCylinder( doubl
coords[1].y = coords[3].y;
}
- glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
+ glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
+ DataScale3D = tmp;
+}
+
+
+static void Draw3D_FilledOblong( double startx, double starty,
+ double endx, double endy,
+ double holex,
+ double holey, double holeradius,
+ double height, double zpos )
+{
+ double ddx, ddy, dx, dy;
+ int ii, angle;
+ std::vector<S3D_Vertex> coords;
+
+ coords.resize( 4 );
+
+ double tmp = DataScale3D;
+
+ DataScale3D = 1.0; // Coordinate is already in range for Set_Object_Data();
+
+ dx = endx - startx;
+ dy = endy - starty;
+ angle = (int) ( ( atan2( dy, dx ) * 1800 / M_PI ) + 0.5 );
+ dx = 0;
+ dy = holeradius;
+ RotatePoint( &dx, &dy, angle );
+ coords[0].x = coords[1].x = startx + dx;
+ coords[0].y = coords[1].y = starty - dy;
+ coords[2].x = coords[3].x = endx + dx;
+ coords[2].y = coords[3].y = endy - dy;
+ coords[0].z = coords[3].z = zpos;
+ coords[1].z = coords[2].z = zpos + height;
+ Set_Object_Data( coords );
+
+ for( ii = 1; ii <= 9; ii++ )
+ {
+ ddx = dx;
+ ddy = -dy;
+ RotatePoint( &ddx, &ddy, -ii * 200 );
+ coords[0].x = coords[2].x;
+ coords[0].y = coords[2].y;
+ coords[1].x = coords[3].x;
+ coords[1].y = coords[3].y;
+ coords[2].x = coords[3].x = endx + ddx;
+ coords[2].y = coords[3].y = endy + ddy;
+ Set_Object_Data( coords );
+ }
+
+ coords[0].x = coords[1].x = endx - dx;
+ coords[0].y = coords[1].y = endy + dy;
+ coords[2].x = coords[3].x = startx - dx;
+ coords[2].y = coords[3].y = starty + dy;
+ coords[0].z = coords[3].z = zpos;
+ coords[1].z = coords[2].z = zpos + height;
+ Set_Object_Data( coords );
+
+ for( ii = 1; ii <= 9; ii++ )
+ {
+ ddx = -dx;
+ ddy = dy;
+ RotatePoint( &ddx, &ddy, -ii * 200 );
+ coords[0].x = coords[2].x;
+ coords[0].y = coords[2].y;
+ coords[1].x = coords[3].x;
+ coords[1].y = coords[3].y;
+ coords[2].x = coords[3].x = startx + ddx;
+ coords[2].y = coords[3].y = starty + ddy;
+ Set_Object_Data( coords );
+ }
+
+ // Calculate the coordinates of the segment assumed horizontal.
+ // Then turn the strips of the desired angle.
+
+ glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
DataScale3D = tmp;
}
+static void Draw3D_FilledOblongMask( double startx, double starty,
+ double endx, double endy,
+ double holex,
+ double holey, double holeradius,
+ double height, double zpos )
+{
+ double ddx, ddy, dx, dy;
+ int spii = pii, ii, angle;
+
+ dx = endx - startx;
+ dy = endy - starty;
+ angle = (int) ( ( atan2( dy, dx ) * 1800 / M_PI ) + 0.5 );
+ dx = 0;
+ dy = holeradius;
+ RotatePoint( &dx, &dy, angle );
+
+ for( ii = 0; ii <= 9; ii++ )
+ {
+ ddx = dx;
+ ddy = -dy;
+ RotatePoint( &ddx, &ddy, -ii * 200 );
+ p_data.push_back( CPolyPt( (int) ( (endx + ddx) / g_Parm_3D_Visu.m_BoardScale ),
+ (int) (-(endy + ddy) / g_Parm_3D_Visu.m_BoardScale) ) );
+ pii++;
+ }
+
+ for( ii = 0; ii <= 9; ii++ )
+ {
+ ddx = -dx;
+ ddy = dy;
+ RotatePoint( &ddx, &ddy, -ii * 200 );
+ p_data.push_back( CPolyPt( (int) ( (startx + ddx) / g_Parm_3D_Visu.m_BoardScale ),
+ (int) (-(starty + ddy) / g_Parm_3D_Visu.m_BoardScale) ) );
+ pii++;
+ }
+
+ for( ii = 0; ii < (pii - spii) / 2; ii++ )
+ {
+ CPolyPt h = p_data[spii + ii];
+ p_data[spii + ii] = p_data[pii - ii - 1];
+ p_data[pii - ii - 1] = h;
+ }
+}
+
+
+static void Draw3D_FilledCylinderMask( double posx, double posy, double rayon,
+ double height, double zpos )
+{
+ int ii, slice = 16;
+ double x, y;
+
+ for( ii = 0; ii <= slice; ii++ )
+ {
+ x = rayon;
+ y = 0.0;
+ RotatePoint( &x, &y, ii * 225.0 );
+ x = (x + posx) / g_Parm_3D_Visu.m_BoardScale;
+ y = -( (y + posy) / g_Parm_3D_Visu.m_BoardScale );
+
+ p_data.push_back( CPolyPt( (int) x, (int) y ) );
+ pii++;
+ }
+}
+
+
+static void Draw3D_Mask( double startx, double starty, double endx,
+ double endy, double width, double zpos )
+{
+ startx /= g_Parm_3D_Visu.m_BoardScale;
+ starty /= g_Parm_3D_Visu.m_BoardScale;
+ endx /= g_Parm_3D_Visu.m_BoardScale;
+ endy /= g_Parm_3D_Visu.m_BoardScale;
+ e_data.push_back( CPolyPt( (int) startx, (int) starty ) );
+ e_data.push_back( CPolyPt( (int) endx, (int) endy ) );
+ eii += 2;
+}
+
+
// Draw a polygon similar to a segment has rounded tips
static void Draw3D_FilledSegment( double startx, double starty, double endx,
double endy, double width, double zpos )
{
double dx, dy, x, y, firstx = 0, firsty = 0;
- int ii, angle;
+ int ii, angle;
// Calculate the coordinates of the segment assumed horizontal.
// Then turn the strips of the desired angle.
- dx = endx - startx;
- dy = endy - starty;
- angle = (int) ( ( atan2( dy, dx ) * 1800 / M_PI ) + 0.5 );
+ dx = endx - startx;
+ dy = endy - starty;
+ angle = (int) ( ( atan2( dy, dx ) * 1800 / M_PI ) + 0.5 );
RotatePoint( &dx, &dy, angle );
width /= 2;
@@ -1189,8 +2692,8 @@ static void Draw3D_FilledSegment( double
// Trace the flare to right (1st half polygon at the end of the segment)
for( ii = 0; ii <= 8; ii++ )
{
- x = 0.0;
- y = -width;
+ x = 0.0;
+ y = -width;
RotatePoint( &x, &y, -ii * 225 );
x += dx;
RotatePoint( &x, &y, -angle );
@@ -1198,8 +2701,8 @@ static void Draw3D_FilledSegment( double
if( ii == 0 )
{
- firstx = startx + x;
- firsty = starty + y;
+ firstx = startx + x;
+ firsty = starty + y;
}
}
@@ -1207,8 +2710,8 @@ static void Draw3D_FilledSegment( double
for( ii = 0; ii <= 8; ii++ )
{
int jj = ii * 225;
- x = 0.0;
- y = width;
+ x = 0.0;
+ y = width;
RotatePoint( &x, &y, -angle - jj );
glVertex3f( startx + x, starty + y, zpos );
}
@@ -1224,20 +2727,20 @@ static void Draw3D_FilledSegmentWithHole
double endx, double endy,
double width, double holex,
double holey, double holeradius,
- double zpos )
+ double zpos, double offX, double offY )
{
double x, y, xin, yin;
double firstx = 0, firsty = 0, firstxin = 0, firstyin = 0;
- int ii, angle, theta;
+ int ii, angle, theta;
// Calculate the coordinates of the segment assumed horizontal
// Then turn the strips of the desired angle
// All calculations are done with startx, starty as the origin of the route
- endx -= startx;
- endy -= starty;
- holex -= startx;
- holey -= starty;
- angle = (int) ( ( atan2( endy, endx ) * 1800 / M_PI ) + 0.5 );
+ endx -= startx;
+ endy -= starty;
+ holex -= startx;
+ holey -= starty;
+ angle = (int) ( ( atan2( endy, endx ) * 1800 / M_PI ) + 0.5 );
RotatePoint( &endx, &endy, angle );
RotatePoint( &holex, &holey, angle );
@@ -1249,26 +2752,26 @@ static void Draw3D_FilledSegmentWithHole
// around the half-hole drilling
for( ii = 0; ii <= 8; ii++ )
{
- x = 0.0;
- y = -width;
- xin = 0.0;
- yin = -holeradius;
- theta = -ii * 225;
+ x = 0.0;
+ y = -width;
+ xin = 0.0;
+ yin = -holeradius;
+ theta = -ii * 225;
RotatePoint( &x, &y, theta );
RotatePoint( &xin, &yin, theta );
x += endx;
RotatePoint( &x, &y, -angle );
- xin += holex;
+ xin += endx;
RotatePoint( &xin, &yin, -angle );
glVertex3f( startx + xin, starty + yin, zpos );
- glVertex3f( startx + x, starty + y, zpos );
+ glVertex3f( startx + x + offX, starty + y - offY, zpos );
if( ii == 0 )
{
- firstx = startx + x;
- firsty = starty + y;
- firstxin = startx + xin;
- firstyin = starty + yin;
+ firstx = startx + x + offX;
+ firsty = starty + y - offY;
+ firstxin = startx + xin;
+ firstyin = starty + yin;
}
}
@@ -1276,17 +2779,16 @@ static void Draw3D_FilledSegmentWithHole
// segment)
for( ii = 0; ii <= 8; ii++ )
{
- theta = -ii * 225;
- x = 0.0;
- y = width;
+ theta = -ii * 225;
+ x = 0.0;
+ y = width;
RotatePoint( &x, &y, -angle + theta );
xin = 0.0;
yin = holeradius;
RotatePoint( &xin, &yin, theta );
- xin += holex;
RotatePoint( &xin, &yin, -angle );
glVertex3f( startx + xin, starty + yin, zpos );
- glVertex3f( startx + x, starty + y, zpos );
+ glVertex3f( startx + x + offX, starty + y - offY, zpos );
}
glVertex3f( firstxin, firstyin, zpos );
@@ -1295,17 +2797,99 @@ static void Draw3D_FilledSegmentWithHole
}
+static void Draw3D_FilledSegmentWithHoleMask( double startx, double starty,
+ double endx, double endy,
+ double width, double holex,
+ double holey, double holeradius,
+ double zpos, double offX, double offY )
+{
+ double x, y, xin, yin;
+ double firstx = 0, firsty = 0, firstxin = 0, firstyin = 0;
+ int ii, angle, theta;
+
+ int spii = pii;
+
+ // Calculate the coordinates of the segment assumed horizontal
+ // Then turn the strips of the desired angle
+ // All calculations are done with startx, starty as the origin of the route
+ endx -= startx;
+ endy -= starty;
+ holex -= startx;
+ holey -= starty;
+ angle = (int) ( ( atan2( endy, endx ) * 1800 / M_PI ) + 0.5 );
+
+ RotatePoint( &endx, &endy, angle );
+ RotatePoint( &holex, &holey, angle );
+ width /= 2;
+
+ // Path of the flare to right (1st half polygon at the end of the segment)
+ // around the half-hole drilling
+ for( ii = 0; ii <= 8; ii++ )
+ {
+ x = 0.0;
+ y = -width;
+ xin = 0.0;
+ yin = -holeradius;
+ theta = -ii * 225;
+ RotatePoint( &x, &y, theta );
+ RotatePoint( &xin, &yin, theta );
+ x += endx;
+ RotatePoint( &x, &y, -angle );
+ xin += holex;
+ RotatePoint( &xin, &yin, -angle );
+ p_data.push_back( CPolyPt( (int) ( (startx + x + offX) / g_Parm_3D_Visu.m_BoardScale ),
+ -(int) ( (starty + y -
+ offY) / g_Parm_3D_Visu.m_BoardScale ) ) );
+ pii++;
+
+ if( ii == 0 )
+ {
+ firstx = startx + x;
+ firsty = starty + y;
+ firstxin = startx + xin;
+ firstyin = starty + yin;
+ }
+ }
+
+ // Layout of the rounded left (2nd half polygon is the origin of the
+ // segment)
+ for( ii = 0; ii <= 8; ii++ )
+ {
+ theta = -ii * 225;
+ x = 0.0;
+ y = width;
+ RotatePoint( &x, &y, -angle + theta );
+ xin = 0.0;
+ yin = holeradius;
+ RotatePoint( &xin, &yin, theta );
+ xin += holex;
+ RotatePoint( &xin, &yin, -angle );
+ p_data.push_back( CPolyPt( (int) ( (startx + x + offX) / g_Parm_3D_Visu.m_BoardScale ),
+ -(int) ( (starty + y -
+ offY) / g_Parm_3D_Visu.m_BoardScale ) ) );
+ pii++;
+ }
+
+ for( ii = 0; ii < (pii - spii) / 2; ii++ )
+ {
+ CPolyPt h = p_data[spii + ii];
+ p_data[spii + ii] = p_data[pii - ii - 1];
+ p_data[pii - ii - 1] = h;
+ }
+}
+
+
static void Draw3D_ArcSegment( double startx, double starty, double centrex,
double centrey, double arc_angle, double width, double zpos )
{
- int ii;
- int slice = 36; // Number of segments to approximate a circle by segments
+ int ii;
+ int slice = 36; // Number of segments to approximate a circle by segments
double hole, rayon;
double arcStart_Angle;
arcStart_Angle = (atan2( startx - centrex, starty - centrey ) * 1800 / M_PI );
- rayon = hypot( startx - centrex, starty - centrey ) + ( width / 2);
- hole = rayon - width;
+ rayon = hypot( startx - centrex, starty - centrey ) + ( width / 2);
+ hole = rayon - width;
// Calculate the number of segments to approximate this arc
int imax = (int) ( (double) arc_angle * slice / 3600.0 );
@@ -1326,12 +2910,12 @@ static void Draw3D_ArcSegment( double st
{
double angle = (double) ii * delta_angle;
angle += arcStart_Angle + 900;
- double dx = hole;
- double dy = 0.0;
+ double dx = hole;
+ double dy = 0.0;
RotatePoint( &dx, &dy, (int) angle );
glVertex3f( dx + startx, dy + starty, zpos );
- dx = rayon;
- dy = 0.0;
+ dx = rayon;
+ dy = 0.0;
RotatePoint( &dx, &dy, (int) angle );
glVertex3f( dx + startx, dy + starty, zpos );
}
@@ -1340,14 +2924,65 @@ static void Draw3D_ArcSegment( double st
}
+static void Draw3D_ArcSegmentMask( double startx, double starty, double centrex,
+ double centrey, double arc_angle, double width, double zpos )
+{
+ int ii;
+ int slice = 36; // Number of segments to approximate a circle by segments
+ double rayon;
+ double arcStart_Angle;
+ double lx, ly;
+
+ arcStart_Angle = (atan2( startx - centrex, starty - centrey ) * 1800 / M_PI );
+ rayon = hypot( startx - centrex, starty - centrey );
+
+ // Calculate the number of segments to approximate this arc
+ int imax = (int) ( (double) arc_angle * slice / 3600.0 );
+
+ 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) arc_angle / imax;
+
+ for( ii = 0; ii <= imax; ii++ )
+ {
+ double angle = (double) ii * delta_angle;
+ angle += arcStart_Angle + 900;
+ double dx = rayon;
+ double dy = 0.0;
+ dy = 0.0;
+ RotatePoint( &dx, &dy, (int) angle );
+ dx += startx;
+ dy += starty;
+ dx /= g_Parm_3D_Visu.m_BoardScale;
+ dy /= g_Parm_3D_Visu.m_BoardScale;
+
+ if( ii > 0 )
+ {
+ e_data.push_back( CPolyPt( (int) lx, (int) (-ly) ) );
+ e_data.push_back( CPolyPt( (int) dx, (int) (-dy) ) );
+ eii += 2;
+ }
+
+ lx = dx;
+ ly = dy;
+ }
+}
+
+
static void Draw3D_CircleSegment( double startx, double starty, double endx,
double endy, double width, double zpos )
{
- int ii, slice = 36;
+ int ii, slice = 36;
double x, y, hole, rayon;
- rayon = hypot( startx - endx, starty - endy ) + ( width / 2);
- hole = rayon - width;
+ rayon = hypot( startx - endx, starty - endy ) + ( width / 2);
+ hole = rayon - width;
glBegin( GL_QUAD_STRIP );
@@ -1365,29 +3000,66 @@ static void Draw3D_CircleSegment( double
}
+static void Draw3D_CircleSegmentMask( double startx, double starty, double endx,
+ double endy, double width, double zpos )
+{
+ int ii, slice = 36;
+ double lx, ly, x, y, rayon;
+
+ int seii = eii;
+
+ rayon = hypot( startx - endx, starty - endy );
+
+ for( ii = 0; ii <= slice; ii++ )
+ {
+ x = rayon; y = 0.0;
+ RotatePoint( &x, &y, ii * 3600 / slice );
+ x += startx;
+ y += starty;
+ x /= g_Parm_3D_Visu.m_BoardScale;
+ y /= g_Parm_3D_Visu.m_BoardScale;
+
+ if( ii > 0 )
+ {
+ e_data.push_back( CPolyPt( (int) lx, (int) ly ) );
+ e_data.push_back( CPolyPt( (int) x, (int) y ) );
+ eii += 2;
+ }
+
+ lx = x;
+ ly = y;
+ }
+
+ for( ii = 0; ii < (eii - seii) / 2; ii++ )
+ {
+ CPolyPt h = e_data[seii + ii];
+ e_data[seii + ii] = e_data[eii - ii - 1];
+ e_data[eii - ii - 1] = h;
+ }
+}
+
+
void EDA_3D_CANVAS::Draw3D_Polygon( std::vector<wxPoint>& aCornersList, double aZpos )
{
g_Parm_3D_Visu.m_ActZpos = aZpos;
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 );
+ 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;
- //gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
-
// Draw solid polygon
gluTessBeginPolygon( tess, NULL );
gluTessBeginContour( tess );
for( unsigned ii = 0; ii < aCornersList.size(); ii++ )
{
- v_data[0] = aCornersList[ii].x * g_Parm_3D_Visu.m_BoardScale;
- v_data[1] = -aCornersList[ii].y * g_Parm_3D_Visu.m_BoardScale;
+ v_data[0] = aCornersList[ii].x * g_Parm_3D_Visu.m_BoardScale;
+ v_data[1] = -aCornersList[ii].y * g_Parm_3D_Visu.m_BoardScale;
// 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
@@ -1404,28 +3076,41 @@ void EDA_3D_CANVAS::Draw3D_Polygon( std:
static int Get3DLayerEnable( int act_layer )
{
int i = -1;
+
// see if layer needs to be shown
// check the flags
- switch (act_layer)
+ switch( act_layer )
{
- case DRAW_N:
- i=g_Parm_3D_Visu.FL_DRAWINGS;
- break;
+ case ADHESIVE_N_FRONT:
+ case ADHESIVE_N_BACK:
+ case SOLDERMASK_N_FRONT:
+ case SOLDERMASK_N_BACK:
+ case SOLDERPASTE_N_FRONT:
+ case SOLDERPASTE_N_BACK:
+ case SILKSCREEN_N_FRONT:
+ case SILKSCREEN_N_BACK:
+ return g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( act_layer );
+ break;
- case COMMENT_N:
- i=g_Parm_3D_Visu.FL_COMMENTS;
- break;
+ case DRAW_N:
+ i = g_Parm_3D_Visu.FL_DRAWINGS;
+ break;
- case ECO1_N:
- i=g_Parm_3D_Visu.FL_ECO1;
- break;
+ case COMMENT_N:
+ i = g_Parm_3D_Visu.FL_COMMENTS;
+ break;
- case ECO2_N:
- i=g_Parm_3D_Visu.FL_ECO2;
- break;
+ case ECO1_N:
+ i = g_Parm_3D_Visu.FL_ECO1;
+ break;
+
+ case ECO2_N:
+ i = g_Parm_3D_Visu.FL_ECO2;
+ break;
}
+
// the layer was not a layer with a flag, so show it
- if (i < 0)
+ if( i < 0 )
return true;
// if the layer has a flag, return the flag
@@ -1440,18 +3125,19 @@ static GLfloat Get3DLayerSide( int act_l
nZ = 1.0;
if( ( act_layer <= LAST_COPPER_LAYER - 1 )
- || ( act_layer == ADHESIVE_N_BACK )
- || ( act_layer == SOLDERPASTE_N_BACK )
- || ( act_layer == SILKSCREEN_N_BACK )
- || ( act_layer == SOLDERMASK_N_BACK ) )
+ || ( act_layer == ADHESIVE_N_BACK )
+ || ( act_layer == SOLDERPASTE_N_BACK )
+ || ( act_layer == SILKSCREEN_N_BACK )
+ || ( act_layer == SOLDERMASK_N_BACK ) )
nZ = -1.0;
+
return nZ;
}
-///////////////////////////////////////////////////////////////////////////////
+// /////////////////////////////////////////////////////////////////////////////
// GLU_TESS CALLBACKS
-///////////////////////////////////////////////////////////////////////////////
+// /////////////////////////////////////////////////////////////////////////////
void CALLBACK tessBeginCB( GLenum which )
{
@@ -1475,6 +3161,7 @@ void CALLBACK tessCPolyPt2Vertex( const
g_Parm_3D_Visu.m_ActZpos );
}
+
void CALLBACK tesswxPoint2Vertex( const GLvoid* data )
{
const wxPoint* ptr = (const wxPoint*) data;
@@ -1496,3 +3183,56 @@ void CALLBACK tessErrorCB( GLenum errorC
D( printf( "Tess ERROR: %s\n", errorStr ); )
#endif
}
+
+
+// /////////////////////////////////////////////////////////////////////////////
+// MY GLU_TESS CALLBACKS
+// /////////////////////////////////////////////////////////////////////////////
+
+void CALLBACK mytessBeginCB( GLenum which )
+{
+ glBegin( which );
+}
+
+
+void CALLBACK mytessEndCB()
+{
+ glEnd();
+}
+
+
+void CALLBACK mytessCPolyPt2Vertex( const GLvoid* data )
+{
+ // cast back to double type
+ const CPolyPt* ptr = (const CPolyPt*) data;
+
+ glVertex3f( ptr->x * g_Parm_3D_Visu.m_BoardScale,
+ -ptr->y * g_Parm_3D_Visu.m_BoardScale,
+ g_Parm_3D_Visu.m_ActZpos );
+}
+
+
+void CALLBACK mytessCombineCB( GLdouble coords[3],
+ void* vertex_data[4],
+ GLfloat weight[4],
+ void** outData )
+{
+ CPolyPt* n =
+ new CPolyPt( (int) (coords[0] / g_Parm_3D_Visu.m_BoardScale),
+ -(int) (coords[1] / g_Parm_3D_Visu.m_BoardScale) );
+
+ *outData = n;
+}
+
+
+void CALLBACK mytessErrorCB( GLenum errorCode )
+{
+#if defined(DEBUG)
+ const GLubyte* errorStr;
+
+ errorStr = gluErrorString( errorCode );
+
+ // DEBUG //
+ fprintf( stderr, "Tess ERROR: %s\n", errorStr );
+#endif
+}
Only in 3d-viewer/: 3d_draw.cpp_20120521
Only in 3d-viewer/: 3d_draw.cpp_20120530
Only in 3d-viewer/: 3d_draw.cpp_20120603
Only in 3d-viewer/: 3d_draw.cpp.BASE
Only in 3d-viewer/: 3d_draw.cpp.BASE.moved
Only in 3d-viewer/: 3d_draw.cpp.OTHER
Only in 3d-viewer/: 3d_draw.cpp.OTHER.moved
Only in 3d-viewer/: 3d_draw.cpp.THIS
Only in 3d-viewer/: 3d_draw.cpp.THIS.moved
diff -rup 3d-viewer.orig//3d_read_mesh.cpp 3d-viewer//3d_read_mesh.cpp
--- 3d-viewer.orig//3d_read_mesh.cpp 2012-06-03 22:21:14.095611510 +0200
+++ 3d-viewer//3d_read_mesh.cpp 2012-06-03 22:16:21.654545402 +0200
@@ -35,14 +35,19 @@
#include <3d_viewer.h>
-
+#ifdef TSP_20120603
+wxString FullFilename;
+#endif // TSP_20120603
int S3D_MASTER::ReadData()
{
- char line[1024], * text;
- wxFileName fn;
- wxString FullFilename;
- FILE* file;
- int LineNum = 0;
+ char line[1024], * text;
+ wxFileName fn;
+
+#ifndef TSP_20120603
+ wxString FullFilename;
+#endif // TSP_20120603
+ FILE* file;
+ int LineNum = 0;
if( m_Shape3DName.IsEmpty() )
{
@@ -51,9 +56,9 @@ int S3D_MASTER::ReadData()
wxString shape3DNname = m_Shape3DName;
#ifdef __WINDOWS__
- shape3DNname.Replace( wxT("/"), wxT("\\") );
+ shape3DNname.Replace( wxT( "/" ), wxT( "\\" ) );
#else
- shape3DNname.Replace( wxT("\\"), wxT("/") );
+ shape3DNname.Replace( wxT( "\\" ), wxT( "/" ) );
#endif
if( wxFileName::FileExists( shape3DNname ) )
@@ -115,13 +120,13 @@ int S3D_MASTER::ReadData()
int S3D_MASTER::ReadMaterial( FILE* file, int* LineNum )
{
- char line[512], * text, * command;
- wxString mat_name;
- S3D_MATERIAL* material = NULL;
-
- command = strtok( NULL, " \t\n\r" );
- text = strtok( NULL, " \t\n\r" );
- mat_name = FROM_UTF8( text );
+ char line[512], * text, * command;
+ wxString mat_name;
+ S3D_MATERIAL* material = NULL;
+
+ command = strtok( NULL, " \t\n\r" );
+ text = strtok( NULL, " \t\n\r" );
+ mat_name = FROM_UTF8( text );
if( stricmp( command, "USE" ) == 0 )
{
@@ -134,7 +139,11 @@ int S3D_MASTER::ReadMaterial( FILE* file
}
}
+#ifdef TSP_20120603
+ printf( "ReadMaterial error: material not found %s\n", FullFilename.mb_str().data() );
+#else
printf( "ReadMaterial error: material not found\n" );
+#endif // TSP_20120603
return 0;
}
@@ -226,7 +235,12 @@ int S3D_MASTER::ReadChildren( FILE* file
}
else
{
+#ifdef TSP_20120603
+ printf( "ReadChildren error line %d <%s> %s\n", *LineNum, text,
+ FullFilename.mb_str().data() );
+#else
printf( "ReadChildren error line %d <%s> \n", *LineNum, text );
+#endif // TSP_20120603
break;
}
}
@@ -237,8 +251,8 @@ int S3D_MASTER::ReadChildren( FILE* file
int S3D_MASTER::ReadShape( FILE* file, int* LineNum )
{
- char line[1024], * text;
- int err = 1;
+ char line[1024], * text;
+ int err = 1;
while( GetLine( file, line, LineNum, 512 ) )
{
@@ -260,7 +274,12 @@ int S3D_MASTER::ReadShape( FILE* file, i
}
else
{
- printf( "ReadShape error line %d <%s> \n", *LineNum, text );
+#ifdef TSP_20120603
+ printf( "ReadShape error line %d <%s> \n", *LineNum, text,
+ FullFilename.mb_str().data() );
+#else
+ printf( "ReadShape error line %d \n", *LineNum, text );
+#endif // TSP_20120603
break;
}
}
@@ -271,8 +290,8 @@ int S3D_MASTER::ReadShape( FILE* file, i
int S3D_MASTER::ReadAppearance( FILE* file, int* LineNum )
{
- char line[1024], * text;
- int err = 1;
+ char line[1024], * text;
+ int err = 1;
while( GetLine( file, line, LineNum, 512 ) )
{
@@ -287,9 +306,30 @@ int S3D_MASTER::ReadAppearance( FILE* fi
{
ReadMaterial( file, LineNum );
}
+
+#ifdef TSP_20120603
+ else if( stricmp( text, "texture" ) == 0 )
+ {
+ char line[512], * text, * command;
+ command = strtok( NULL, " \t\n\r" );
+ printf( "ReadTexture: %s", command );
+
+ while( text = strtok( NULL, " \t\n\r" ) )
+ {
+ printf( " %s", text );
+ }
+
+ printf( "\n" );
+ }
+#endif // TSP_20120603
else
{
+#ifdef TSP_20120603
+ printf( "ReadAppearance error line %d <%s> %s\n", *LineNum, text,
+ FullFilename.mb_str().data() );
+#else
printf( "ReadAppearance error line %d <%s> \n", *LineNum, text );
+#endif // TSP_20120603
break;
}
}
@@ -317,20 +357,20 @@ int S3D_MASTER::ReadAppearance( FILE* fi
* text_buffer contains the first line of this node :
* "coord Coordinate { point ["
*/
-void ReadCoordsList( FILE* file, char* text_buffer, std::vector< double >& aList, int* LineNum )
+void ReadCoordsList( FILE* file, char* text_buffer, std::vector<double>& aList, int* LineNum )
{
- unsigned int ii = 0, jj = 0;
- char* text;
- bool HasData = false;
- bool StartData = false;
- bool EndNode = false;
- char string_num[512];
+ unsigned int ii = 0, jj = 0;
+ char* text;
+ bool HasData = false;
+ bool StartData = false;
+ bool EndNode = false;
+ char string_num[512];
text = text_buffer;
while( !EndNode )
{
- if( *text == 0 ) // Needs data !
+ if( *text == 0 ) // Needs data !
{
text = text_buffer;
GetLine( file, text_buffer, LineNum, 512 );
@@ -373,6 +413,7 @@ void ReadCoordsList( FILE* file, char* t
break;
default:
+
if( !StartData )
break;
@@ -395,9 +436,9 @@ void ReadCoordsList( FILE* file, char* t
int S3D_MASTER::ReadGeometry( FILE* file, int* LineNum )
{
char line[1024], buffer[1024], * text;
- int err = 1;
- std::vector< double > points;
- std::vector< double > list;
+ int err = 1;
+ std::vector<double> points;
+ std::vector<double> list;
while( GetLine( file, line, LineNum, 512 ) )
{
@@ -420,6 +461,7 @@ int S3D_MASTER::ReadGeometry( FILE* file
else
{
}
+
continue;
}
@@ -433,6 +475,7 @@ int S3D_MASTER::ReadGeometry( FILE* file
else
{
}
+
continue;
}
@@ -506,8 +549,8 @@ int S3D_MASTER::ReadGeometry( FILE* file
break;
}
- std::vector< int > coordIndex;
- std::vector< S3D_Vertex > vertices;
+ std::vector<int> coordIndex;
+ std::vector<S3D_Vertex> vertices;
while( GetLine( file, line, LineNum, 512 ) )
{
@@ -527,7 +570,7 @@ int S3D_MASTER::ReadGeometry( FILE* file
{
int kk = coordIndex[jj] * 3;
- if( (kk < 0) || ((kk + 3) > (int)points.size()) )
+ if( (kk < 0) || ( (kk + 3) > (int) points.size() ) )
{
wxLogError( wxT( "3D geometry index read error <%s> at line %d." ),
GetChars( FROM_UTF8( text ) ), *LineNum );
@@ -536,10 +579,29 @@ int S3D_MASTER::ReadGeometry( FILE* file
}
S3D_Vertex vertex;
- vertex.x = points[kk];
- vertex.y = points[kk + 1];
- vertex.z = points[kk + 2];
+ vertex.x = points[kk];
+ vertex.y = points[kk + 1];
+ vertex.z = points[kk + 2];
vertices.push_back( vertex );
+
+// fprintf(stderr, "V: %lf,%lf,%lf\n", vertex.x, vertex.y, vertex.z);
+ if( vertex.x < m_MinPos.x )
+ m_MinPos.x = vertex.x;
+
+ if( vertex.y < m_MinPos.y )
+ m_MinPos.y = vertex.y;
+
+ if( vertex.z < m_MinPos.z )
+ m_MinPos.z = vertex.z;
+
+ if( vertex.x > m_MaxPos.x )
+ m_MaxPos.x = vertex.x;
+
+ if( vertex.y > m_MaxPos.y )
+ m_MaxPos.y = vertex.y;
+
+ if( vertex.z > m_MaxPos.z )
+ m_MaxPos.z = vertex.z;
}
Set_Object_Coords( vertices );
diff -rup 3d-viewer.orig//3d_struct.h 3d-viewer//3d_struct.h
--- 3d-viewer.orig//3d_struct.h 2012-06-03 22:21:14.096611489 +0200
+++ 3d-viewer//3d_struct.h 2012-06-03 22:16:21.654545402 +0200
@@ -97,6 +97,8 @@ public:
S3D_Vertex m_MatPosition;
Struct3D_Shape* m_3D_Drawings;
S3D_MATERIAL* m_Materials;
+ S3D_Vertex m_MinPos;
+ S3D_Vertex m_MaxPos;
public:
S3D_MASTER( EDA_ITEM* aParent );
diff -rup 3d-viewer.orig//3d_toolbar.cpp 3d-viewer//3d_toolbar.cpp
--- 3d-viewer.orig//3d_toolbar.cpp 2012-06-03 22:21:14.096611489 +0200
+++ 3d-viewer//3d_toolbar.cpp 2012-06-03 22:16:21.654545402 +0200
@@ -133,13 +133,14 @@ void EDA_3D_FRAME::ReCreateMenuBar()
bool full_options = true;
// If called from the display frame of CvPcb, only some options are relevant
- if( Parent()->GetName() == wxT( "CmpFrame" ) ) {
+ if( Parent()->GetName() == wxT( "CmpFrame" ) )
+ {
full_options = false;
}
- wxMenuBar* menuBar = new wxMenuBar;
- wxMenu* fileMenu = new wxMenu;
- wxMenu* prefsMenu = new wxMenu;
+ wxMenuBar* menuBar = new wxMenuBar;
+ wxMenu* fileMenu = new wxMenu;
+ wxMenu* prefsMenu = new wxMenu;
menuBar->Append( fileMenu, _( "&File" ) );
@@ -161,36 +162,37 @@ void EDA_3D_FRAME::ReCreateMenuBar()
wxMenuItem* item;
item = AddMenuItem( prefsMenu, ID_MENU3D_AXIS_ONOFF,
- _( "Show 3D &Axis" ), KiBitmap( axis3d_front_xpm ), wxITEM_CHECK );
- item->Check(g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_AXIS]);
+ _( "Show 3D &Axis" ), KiBitmap( axis3d_front_xpm ), wxITEM_CHECK );
+ item->Check( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_AXIS] );
if( full_options )
{
- item = AddMenuItem( prefsMenu, ID_MENU3D_MODULE_ONOFF,
- _( "Show 3D F&ootprints" ), KiBitmap( shape_3d_xpm ), wxITEM_CHECK );
- item->Check(g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_MODULE]);
-
- item = AddMenuItem( prefsMenu, ID_MENU3D_ZONE_ONOFF,
- _( "Show Zone &Filling" ), KiBitmap( add_zone_xpm ), wxITEM_CHECK );
- item->Check(g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_ZONE]);
-
- item = AddMenuItem( prefsMenu, ID_MENU3D_COMMENTS_ONOFF,
- _( "Show &Comments Layer" ), KiBitmap( edit_sheet_xpm ), wxITEM_CHECK );
- item->Check(g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_COMMENTS]);
-
- item = AddMenuItem( prefsMenu, ID_MENU3D_DRAWINGS_ONOFF,
- _( "Show &Drawings Layer" ), KiBitmap( add_polygon_xpm ), wxITEM_CHECK );
- item->Check(g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_DRAWINGS]);
-
- item = AddMenuItem( prefsMenu, ID_MENU3D_ECO1_ONOFF,
- _( "Show Eco&1 Layer" ), KiBitmap( tools_xpm ), wxITEM_CHECK );
- item->Check(g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_ECO1]);
-
- item = AddMenuItem( prefsMenu, ID_MENU3D_ECO2_ONOFF,
- _( "Show Eco&2 Layer" ), KiBitmap( tools_xpm ), wxITEM_CHECK );
- item->Check(g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_ECO2]);
-
+ item = AddMenuItem( prefsMenu, ID_MENU3D_MODULE_ONOFF,
+ _( "Show 3D F&ootprints" ), KiBitmap( shape_3d_xpm ), wxITEM_CHECK );
+ item->Check( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_MODULE] );
+
+ item = AddMenuItem( prefsMenu, ID_MENU3D_ZONE_ONOFF,
+ _( "Show Zone &Filling" ), KiBitmap( add_zone_xpm ), wxITEM_CHECK );
+ item->Check( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_ZONE] );
+
+ item = AddMenuItem( prefsMenu, ID_MENU3D_COMMENTS_ONOFF,
+ _( "Show &Comments Layer" ), KiBitmap( edit_sheet_xpm ),
+ wxITEM_CHECK );
+ item->Check( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_COMMENTS] );
+
+ item = AddMenuItem( prefsMenu, ID_MENU3D_DRAWINGS_ONOFF,
+ _( "Show &Drawings Layer" ), KiBitmap( add_polygon_xpm ),
+ wxITEM_CHECK );
+ item->Check( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_DRAWINGS] );
+
+ item = AddMenuItem( prefsMenu, ID_MENU3D_ECO1_ONOFF,
+ _( "Show Eco&1 Layer" ), KiBitmap( tools_xpm ), wxITEM_CHECK );
+ item->Check( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_ECO1] );
+
+ item = AddMenuItem( prefsMenu, ID_MENU3D_ECO2_ONOFF,
+ _( "Show Eco&2 Layer" ), KiBitmap( tools_xpm ), wxITEM_CHECK );
+ item->Check( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_ECO2] );
}
SetMenuBar( menuBar );
diff -rup 3d-viewer.orig//3d_viewer.h 3d-viewer//3d_viewer.h
--- 3d-viewer.orig//3d_viewer.h 2012-06-03 22:21:14.096611489 +0200
+++ 3d-viewer//3d_viewer.h 2012-06-03 22:16:21.655545382 +0200
@@ -72,8 +72,7 @@ class ZONE_CONTAINER;
* id.h file. This will prevent the entire project from being rebuilt when
* adding new commands to the 3D viewer.
*/
-enum id_3dview_frm
-{
+enum id_3dview_frm {
ID_START_COMMAND_3D = ID_END_LIST,
ID_ROTATE3D_X_NEG,
ID_ROTATE3D_X_POS,
@@ -127,40 +126,38 @@ class S3D_Vertex;
class SEGVIA;
-#define m_ROTX m_Rot[0]
-#define m_ROTY m_Rot[1]
-#define m_ROTZ m_Rot[2]
+#define m_ROTX m_Rot[0]
+#define m_ROTY m_Rot[1]
+#define m_ROTZ m_Rot[2]
/* information needed to display 3D board */
class Info_3D_Visu
{
-
public:
enum {
- FL_AXIS=0, FL_MODULE, FL_ZONE,
- FL_COMMENTS, FL_DRAWINGS, FL_ECO1, FL_ECO2,
+ FL_AXIS=0, FL_MODULE, FL_ZONE,
+ FL_COMMENTS, FL_DRAWINGS, FL_ECO1, FL_ECO2,
FL_LAST
};
- double m_Beginx, m_Beginy; /* position of mouse */
- double m_Quat[4]; /* orientation of object */
- double m_Rot[4]; /* man rotation of object */
- double m_Zoom; /* field of view in degrees */
- S3D_Color m_BgColor;
- bool m_DrawFlags[FL_LAST]; /* show these special items */
- wxPoint m_BoardPos;
- wxSize m_BoardSize;
- int m_Layers;
-
- const BOARD_DESIGN_SETTINGS* m_BoardSettings; // Link to current board design settings
-
- double m_Epoxy_Width; // Epoxy thickness (normalized)
-
- double m_BoardScale; /* Normalization scale for coordinates:
- * when scaled between -1.0 and +1.0 */
- double m_LayerZcoord[32];
- double m_ActZpos;
-
+ double m_Beginx, m_Beginy; /* position of mouse */
+ double m_Quat[4]; /* orientation of object */
+ double m_Rot[4]; /* man rotation of object */
+ double m_Zoom; /* field of view in degrees */
+ S3D_Color m_BgColor;
+ bool m_DrawFlags[FL_LAST]; /* show these special items */
+ wxPoint m_BoardPos;
+ wxSize m_BoardSize;
+ int m_Layers;
+
+ const BOARD_DESIGN_SETTINGS* m_BoardSettings; // Link to current board design settings
+
+ double m_Epoxy_Width; // Epoxy thickness (normalized)
+
+ double m_BoardScale; /* Normalization scale for coordinates:
+ * when scaled between -1.0 and +1.0 */
+ double m_LayerZcoord[32];
+ double m_ActZpos;
public: Info_3D_Visu();
~Info_3D_Visu();
};
@@ -171,76 +168,76 @@ class EDA_3D_CANVAS : public wxGLCanvas
private:
bool m_init;
GLuint m_gllist;
- /// Tracks whether to use Orthographic or Perspective projection
- // TODO: Does this belong here, or in EDA_3D_FRAME ???
+ // / Tracks whether to use Orthographic or Perspective projection
+ // TODO: Does this belong here, or in EDA_3D_FRAME ???
bool m_ortho;
wxGLContext* m_glRC;
wxRealPoint m_draw3dOffset; // offset to draw the 3 mesh.
double m_ZBottom; // position of the back layer
double m_ZTop; // position of the front layer
-
-
public:
EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList = 0 );
~EDA_3D_CANVAS();
- EDA_3D_FRAME* Parent() { return (EDA_3D_FRAME*)GetParent(); }
+ EDA_3D_FRAME* Parent() { return (EDA_3D_FRAME*) GetParent(); }
- void ClearLists();
+ void ClearLists();
// Event functions:
- void OnPaint( wxPaintEvent& event );
- void OnEraseBackground( wxEraseEvent& event );
- void OnChar( wxKeyEvent& event );
- void OnMouseWheel( wxMouseEvent& event );
- void OnMouseMove( wxMouseEvent& event );
- void OnRightClick( wxMouseEvent& event );
- void OnPopUpMenu( wxCommandEvent& event );
- void TakeScreenshot( wxCommandEvent& event );
- void OnEnterWindow( wxMouseEvent& event );
+ void OnPaint( wxPaintEvent& event );
+ void OnEraseBackground( wxEraseEvent& event );
+ void OnChar( wxKeyEvent& event );
+ void OnMouseWheel( wxMouseEvent& event );
+ void OnMouseMove( wxMouseEvent& event );
+ void OnRightClick( wxMouseEvent& event );
+ void OnPopUpMenu( wxCommandEvent& event );
+ void TakeScreenshot( wxCommandEvent& event );
+ void OnEnterWindow( wxMouseEvent& event );
// Display functions
- GLuint DisplayCubeforTest(); // Just a test function
- void SetView3D( int keycode );
- void DisplayStatus();
- void Redraw( bool finish = false );
- void Render();
+ GLuint DisplayCubeforTest(); // Just a test function
+ void SetView3D( int keycode );
+ void DisplayStatus();
+ void Redraw( bool finish = false );
+ void Render();
/**
* Function CreateDrawGL_List
* creates the OpenGL draw list items.
*/
- GLuint CreateDrawGL_List();
- void InitGL();
- void SetLights();
- void SetOffset(double aPosX, double aPosY)
+ GLuint CreateDrawGL_List();
+ void InitGL();
+ void SetLights();
+
+ void SetOffset( double aPosX, double aPosY )
{
- m_draw3dOffset.x = aPosX;
- m_draw3dOffset.y = aPosY;
+ m_draw3dOffset.x = aPosX;
+ m_draw3dOffset.y = aPosY;
}
- void Draw3D_Track( TRACK* track );
+
+ void Draw3D_Track( TRACK* track );
/**
* Function Draw3D_SolidPolygonsInZones
* draw all solid polygons used as filled areas in a zone
* @param aZone = the zone to draw
- */
- void Draw3D_SolidPolygonsInZones( ZONE_CONTAINER* aZone );
+ */
+ void Draw3D_SolidPolygonsInZones( ZONE_CONTAINER* aZone );
/**
* Function Draw3D_Polygon
* draw one solid polygon
* @param aCornersList = a std::vector<wxPoint> list of corners, in physical coordinates
* @param aZpos = the z position in 3D units
- */
- void Draw3D_Polygon( std::vector<wxPoint>& aCornersList, double aZpos );
+ */
+ void Draw3D_Polygon( std::vector<wxPoint>& aCornersList, double aZpos );
/**
* Function Draw3D_Via
* draws 3D via as a cylinder and filled circles.
*/
- void Draw3D_Via( SEGVIA* via );
- void Draw3D_DrawSegment( DRAWSEGMENT* segment );
+ void Draw3D_Via( SEGVIA* via );
+ void Draw3D_DrawSegment( DRAWSEGMENT* segment );
/**
* Function Draw3D_DrawText
@@ -253,16 +250,23 @@ public:
* Using DrawGraphicText to draw all texts ensure texts have the same shape
* in all contexts
*/
- void Draw3D_DrawText( TEXTE_PCB* text );
+ void Draw3D_DrawText( TEXTE_PCB* text );
+ void Draw3D_DrawText( TEXTE_MODULE* text, double rot );
- /// Toggles orthographic projection on and off
- void ToggleOrtho(){ m_ortho = !m_ortho ; Refresh(true);};
+ // / Toggles orthographic projection on and off
+ void ToggleOrtho() { m_ortho = !m_ortho; Refresh( true ); };
- /// Returns the orthographic projection flag
- bool ModeIsOrtho() { return m_ortho ;};
+ // / Returns the orthographic projection flag
+ bool ModeIsOrtho() { return m_ortho; };
- //int Get3DLayerEnable(int act_layer);
+ // int Get3DLayerEnable(int act_layer);
+ // GLUtesselator* Get_mftess() { return mftess; };
+ // GLUtesselator* Get_mbtess() { return mbtess; };
+ // int Get_tmonly() { return tmonly; };
+ // void Set_mftess(GLUtesselator* tess) { mftess = tess; };
+ // void Set_mbtess(GLUtesselator* tess) { mbtess = tess; };
+ // void Set_tmonly(int i) { tmonly = i; };
DECLARE_EVENT_TABLE()
};
@@ -280,7 +284,6 @@ private:
wxSize m_FrameSize;
wxAuiManager m_auimgr;
bool m_reloadRequest;
-
public:
EDA_3D_FRAME( PCB_BASE_FRAME* parent, const wxString& title,
long style = KICAD_DEFAULT_3D_DRAWFRAME_STYLE );
@@ -289,15 +292,15 @@ public:
m_auimgr.UnInit();
};
- PCB_BASE_FRAME* Parent() { return (PCB_BASE_FRAME*)GetParent(); }
- void Exit3DFrame( wxCommandEvent& event );
- void OnCloseWindow( wxCloseEvent& Event );
- void ReCreateMenuBar();
- void ReCreateHToolbar();
- void ReCreateVToolbar();
- void SetToolbars();
- void GetSettings();
- void SaveSettings();
+ PCB_BASE_FRAME* Parent() { return (PCB_BASE_FRAME*) GetParent(); }
+ void Exit3DFrame( wxCommandEvent& event );
+ void OnCloseWindow( wxCloseEvent& Event );
+ void ReCreateMenuBar();
+ void ReCreateHToolbar();
+ void ReCreateVToolbar();
+ void SetToolbars();
+ void GetSettings();
+ void SaveSettings();
/**
* Function ReloadRequest
@@ -305,30 +308,30 @@ public:
* mainly after edition of the board or footprint being displayed.
* mainly for the module editor.
*/
- void ReloadRequest( )
+ void ReloadRequest()
{
m_reloadRequest = true;
}
- void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
- void OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
- void OnKeyEvent( wxKeyEvent& event );
- double BestZoom();
- void RedrawActiveWindow( wxDC* DC, bool EraseBg );
- void Process_Special_Functions( wxCommandEvent& event );
- void Process_Zoom( wxCommandEvent& event );
- void OnActivate( wxActivateEvent& event );
+ void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
+ void OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
+ void OnKeyEvent( wxKeyEvent& event );
+ double BestZoom();
+ void RedrawActiveWindow( wxDC* DC, bool EraseBg );
+ void Process_Special_Functions( wxCommandEvent& event );
+ void Process_Zoom( wxCommandEvent& event );
+ void OnActivate( wxActivateEvent& event );
- void NewDisplay();
- void Set3DBgColor();
+ void NewDisplay();
+ void Set3DBgColor();
DECLARE_EVENT_TABLE()
};
-void SetGLColor( int color );
-void Set_Object_Data( std::vector< S3D_Vertex >& aVertices );
+void SetGLColor( int color );
+void Set_Object_Data( std::vector<S3D_Vertex>& aVertices );
extern Info_3D_Visu g_Parm_3D_Visu;
extern double DataScale3D; // 3D scale units.
-#endif /* __3D_VIEWER_H__ */
+#endif /* __3D_VIEWER_H__ */
Only in 3d-viewer/: ORIG
diff -rup 3d-viewer.orig//trackball.cpp 3d-viewer//trackball.cpp
--- 3d-viewer.orig//trackball.cpp 2012-06-03 22:21:14.097611468 +0200
+++ 3d-viewer//trackball.cpp 2012-06-03 22:16:21.655545382 +0200
@@ -60,91 +60,92 @@
* simple example, though, so that is left as an Exercise for the
* Programmer.
*/
-#define TRACKBALLSIZE (0.8f)
+#define TRACKBALLSIZE (0.8f)
/*
* Local function prototypes (not defined in trackball.h)
*/
-static double tb_project_to_sphere(double, double, double);
-static void normalize_quat(double [4]);
+static double tb_project_to_sphere( double, double, double );
+static void normalize_quat( double[4] );
-void
-vzero(double *v)
+void vzero( double* v )
{
- v[0] = 0.0;
- v[1] = 0.0;
- v[2] = 0.0;
+ v[0] = 0.0;
+ v[1] = 0.0;
+ v[2] = 0.0;
}
-void
-vset(double *v, double x, double y, double z)
+
+void vset( double* v, double x, double y, double z )
{
- v[0] = x;
- v[1] = y;
- v[2] = z;
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
}
-void
-vsub(const double *src1, const double *src2, double *dst)
+
+void vsub( const double* src1, const double* src2, double* dst )
{
- dst[0] = src1[0] - src2[0];
- dst[1] = src1[1] - src2[1];
- dst[2] = src1[2] - src2[2];
+ dst[0] = src1[0] - src2[0];
+ dst[1] = src1[1] - src2[1];
+ dst[2] = src1[2] - src2[2];
}
-void
-vcopy(const double *v1, double *v2)
+
+void vcopy( const double* v1, double* v2 )
{
register int i;
- for (i = 0 ; i < 3 ; i++)
+
+ for( i = 0; i < 3; i++ )
v2[i] = v1[i];
}
-void
-vcross(const double *v1, const double *v2, double *cross)
+
+void vcross( const double* v1, const double* v2, double* cross )
{
double temp[3];
temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
- vcopy(temp, cross);
+ vcopy( temp, cross );
}
-double
-vlength(const double *v)
+
+double vlength( const double* v )
{
- return (double) sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+ return (double) sqrt( v[0] * v[0] + v[1] * v[1] + v[2] * v[2] );
}
-void
-vscale(double *v, double div)
+
+void vscale( double* v, double div )
{
- v[0] *= div;
- v[1] *= div;
- v[2] *= div;
+ v[0] *= div;
+ v[1] *= div;
+ v[2] *= div;
}
-void
-vnormal(double *v)
+
+void vnormal( double* v )
{
- vscale(v, 1.0f/vlength(v));
+ vscale( v, 1.0f / vlength( v ) );
}
-double
-vdot(const double *v1, const double *v2)
+
+double vdot( const double* v1, const double* v2 )
{
- return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
+ return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}
-void
-vadd(const double *src1, const double *src2, double *dst)
+
+void vadd( const double* src1, const double* src2, double* dst )
{
- dst[0] = src1[0] + src2[0];
- dst[1] = src1[1] + src2[1];
- dst[2] = src1[2] + src2[2];
+ dst[0] = src1[0] + src2[0];
+ dst[1] = src1[1] + src2[1];
+ dst[2] = src1[2] + src2[2];
}
+
/*
* Ok, simulate a track-ball. Project the points onto the virtual
* trackball, then figure out the axis of rotation, which is the cross
@@ -157,17 +158,17 @@ vadd(const double *src1, const double *s
* It is assumed that the arguments to this routine are in the range
* (-1.0 ... 1.0)
*/
-void
-trackball(double q[4], double p1x, double p1y, double p2x, double p2y)
+void trackball( double q[4], double p1x, double p1y, double p2x, double p2y )
{
- double a[3]; /* Axis of rotation */
- double phi; /* how much to rotate about axis */
- double p1[3], p2[3], d[3];
- double t;
+ double a[3]; /* Axis of rotation */
+ double phi; /* how much to rotate about axis */
+ double p1[3], p2[3], d[3];
+ double t;
- if (p1x == p2x && p1y == p2y) {
+ if( p1x == p2x && p1y == p2y )
+ {
/* Zero rotation */
- vzero(q);
+ vzero( q );
q[3] = 1.0;
return;
}
@@ -176,61 +177,71 @@ trackball(double q[4], double p1x, doubl
* First, figure out z-coordinates for projection of P1 and P2 to
* deformed sphere
*/
- vset(p1, p1x, p1y, tb_project_to_sphere(TRACKBALLSIZE, p1x, p1y));
- vset(p2, p2x, p2y, tb_project_to_sphere(TRACKBALLSIZE, p2x, p2y));
+ vset( p1, p1x, p1y, tb_project_to_sphere( TRACKBALLSIZE, p1x, p1y ) );
+ vset( p2, p2x, p2y, tb_project_to_sphere( TRACKBALLSIZE, p2x, p2y ) );
/*
* Now, we want the cross product of P1 and P2
*/
- vcross(p2,p1,a);
+ vcross( p2, p1, a );
/*
* Figure out how much to rotate around that axis.
*/
- vsub(p1, p2, d);
- t = vlength(d) / (2.0f*TRACKBALLSIZE);
+ vsub( p1, p2, d );
+ t = vlength( d ) / (2.0f * TRACKBALLSIZE);
/*
* Avoid problems with out-of-control values...
*/
- if (t > 1.0) t = 1.0;
- if (t < -1.0) t = -1.0;
- phi = 2.0f * (double) asin(t);
+ if( t > 1.0 )
+ t = 1.0;
+
+ if( t < -1.0 )
+ t = -1.0;
- axis_to_quat(a,phi,q);
+ phi = 2.0f * (double) asin( t );
+
+ axis_to_quat( a, phi, q );
}
+
/*
* Given an axis and angle, compute quaternion.
*/
-void
-axis_to_quat(double a[3], double phi, double q[4])
+void axis_to_quat( double a[3], double phi, double q[4] )
{
- vnormal(a);
- vcopy(a, q);
- vscale(q, (double) sin(phi/2.0));
- q[3] = (double) cos(phi/2.0);
+ vnormal( a );
+ vcopy( a, q );
+ vscale( q, (double) sin( phi / 2.0 ) );
+ q[3] = (double) cos( phi / 2.0 );
}
+
/*
* Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
* if we are away from the center of the sphere.
*/
-static double
-tb_project_to_sphere(double r, double x, double y)
+static double tb_project_to_sphere( double r, double x, double y )
{
double d, t, z;
- d = (double) sqrt(x*x + y*y);
- if (d < r * 0.70710678118654752440) { /* Inside sphere */
- z = (double) sqrt(r*r - d*d);
- } else { /* On hyperbola */
- t = r / 1.41421356237309504880f;
- z = t*t / d;
+ d = (double) sqrt( x * x + y * y );
+
+ if( d < r * 0.70710678118654752440 ) /* Inside sphere */
+ {
+ z = (double) sqrt( r * r - d * d );
+ }
+ else /* On hyperbola */
+ {
+ t = r / 1.41421356237309504880f;
+ z = t * t / d;
}
+
return z;
}
+
/*
* Given two rotations, e1 and e2, expressed as quaternion rotations,
* figure out the equivalent single rotation and stuff it into dest.
@@ -244,35 +255,36 @@ tb_project_to_sphere(double r, double x,
#define RENORMCOUNT 97
-void
-add_quats(double q1[4], double q2[4], double dest[4])
+void add_quats( double q1[4], double q2[4], double dest[4] )
{
- static int count=0;
- double t1[4], t2[4], t3[4];
- double tf[4];
-
- vcopy(q1,t1);
- vscale(t1,q2[3]);
-
- vcopy(q2,t2);
- vscale(t2,q1[3]);
-
- vcross(q2,q1,t3);
- vadd(t1,t2,tf);
- vadd(t3,tf,tf);
- tf[3] = q1[3] * q2[3] - vdot(q1,q2);
+ static int count = 0;
+ double t1[4], t2[4], t3[4];
+ double tf[4];
+
+ vcopy( q1, t1 );
+ vscale( t1, q2[3] );
+
+ vcopy( q2, t2 );
+ vscale( t2, q1[3] );
+
+ vcross( q2, q1, t3 );
+ vadd( t1, t2, tf );
+ vadd( t3, tf, tf );
+ tf[3] = q1[3] * q2[3] - vdot( q1, q2 );
dest[0] = tf[0];
dest[1] = tf[1];
dest[2] = tf[2];
dest[3] = tf[3];
- if (++count > RENORMCOUNT) {
+ if( ++count > RENORMCOUNT )
+ {
count = 0;
- normalize_quat(dest);
+ normalize_quat( dest );
}
}
+
/*
* Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0
* If they don't add up to 1.0, dividing by their magnitued will
@@ -285,20 +297,23 @@ add_quats(double q1[4], double q2[4], do
* - Pletinckx, D., Quaternion calculus as a basic tool in computer
* graphics, The Visual Computer 5, 2-13, 1989.
*/
-static void normalize_quat(double q[4])
+static void normalize_quat( double q[4] )
{
- int i;
- double mag;
+ int i;
+ double mag;
+
+ mag = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
- mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
- for (i = 0; i < 4; i++) q[i] /= mag;
+ for( i = 0; i < 4; i++ )
+ q[i] /= mag;
}
+
/*
* Build a rotation matrix, given a quaternion rotation.
*
*/
-void build_rotmatrix(GLfloat m[4][4], double q[4])
+void build_rotmatrix( GLfloat m[4][4], double q[4] )
{
m[0][0] = 1.0f - 2.0f * (q[1] * q[1] + q[2] * q[2]);
m[0][1] = 2.0f * (q[0] * q[1] - q[2] * q[3]);
@@ -306,7 +321,7 @@ void build_rotmatrix(GLfloat m[4][4], do
m[0][3] = 0.0f;
m[1][0] = 2.0f * (q[0] * q[1] + q[2] * q[3]);
- m[1][1]= 1.0f - 2.0f * (q[2] * q[2] + q[0] * q[0]);
+ m[1][1] = 1.0f - 2.0f * (q[2] * q[2] + q[0] * q[0]);
m[1][2] = 2.0f * (q[1] * q[2] - q[0] * q[3]);
m[1][3] = 0.0f;
@@ -320,4 +335,3 @@ void build_rotmatrix(GLfloat m[4][4], do
m[3][2] = 0.0f;
m[3][3] = 1.0f;
}
-
diff -rup 3d-viewer.orig//trackball.h 3d-viewer//trackball.h
--- 3d-viewer.orig//trackball.h 2012-06-03 22:21:14.097611468 +0200
+++ 3d-viewer//trackball.h 2012-06-03 22:16:21.655545382 +0200
@@ -47,7 +47,7 @@
* The resulting rotation is returned as a quaternion rotation in the
* first paramater.
*/
-void trackball(double q[4], double p1x, double p1y, double p2x, double p2y);
+void trackball( double q[4], double p1x, double p1y, double p2x, double p2y );
/*
* Given two quaternions, add them together to get a third quaternion.
@@ -57,18 +57,17 @@ void trackball(double q[4], double p1x,
* rotation, the second and third the total rotation (which will be
* over-written with the resulting new total rotation).
*/
-void add_quats(double *q1, double *q2, double *dest);
+void add_quats( double* q1, double* q2, double* dest );
/*
* A useful function, builds a rotation matrix in Matrix based on
* given quaternion.
*/
-void build_rotmatrix(GLfloat m[4][4], double q[4]);
+void build_rotmatrix( GLfloat m[4][4], double q[4] );
/*
* This function computes a quaternion based on an axis (defined by
* the given vector) and an angle about which to rotate. The angle is
* expressed in radians. The result is put into the third argument.
*/
-void axis_to_quat(double a[3], double phi, double q[4]);
-
+void axis_to_quat( double a[3], double phi, double q[4] );
Only in 3d-viewer/: xxxx
Follow ups