3D viewer: optimizations in code to build the 3D view.
Remove no more used code. Building the 3D view is now faster.
This commit is contained in:
parent
8b46c4eb8f
commit
7a51a502b4
|
@ -87,27 +87,34 @@ static void Draw3D_VerticalPolygonalCylinder( const SHAPE_POLY_SET& aPolysList,
|
|||
coords[3].z = coords[0].z;
|
||||
|
||||
// Draw the vertical polygonal side
|
||||
for( int ii = 0; ii < aPolysList.OutlineCount(); ii++ )
|
||||
for( int idx = 0; idx < aPolysList.OutlineCount(); idx++ )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN& path = aPolysList.COutline( ii );
|
||||
// Each polygon in aPolysList is a polygon with holes
|
||||
const SHAPE_POLY_SET::POLYGON& curr_polywithholes = aPolysList.CPolygon( idx );
|
||||
|
||||
for( int jj = 0; jj < path.PointCount(); jj++ )
|
||||
// Draw the outline of each simple polygon inside the polygon with holes:
|
||||
for( unsigned ipoly = 0; ipoly < curr_polywithholes.size(); ipoly++ )
|
||||
{
|
||||
const VECTOR2I& a = path.CPoint( jj );
|
||||
const VECTOR2I& b = path.CPoint( jj + 1 );
|
||||
const SHAPE_LINE_CHAIN& path = curr_polywithholes[ipoly]; // a simple polygon
|
||||
|
||||
// Build the 4 vertices of each GL_QUAD
|
||||
coords[0].x = a.x;
|
||||
coords[0].y = -a.y;
|
||||
coords[1].x = coords[0].x;
|
||||
coords[1].y = coords[0].y; // only z change
|
||||
coords[2].x = b.x;
|
||||
coords[2].y = -b.y;
|
||||
coords[3].x = coords[2].x;
|
||||
coords[3].y = coords[2].y; // only z change
|
||||
for( int jj = 0; jj < path.PointCount(); jj++ )
|
||||
{
|
||||
const VECTOR2I& a = path.CPoint( jj );
|
||||
const VECTOR2I& b = path.CPoint( jj + 1 );
|
||||
|
||||
// Creates the GL_QUAD
|
||||
TransfertToGLlist( coords, aBiuTo3DUnits );
|
||||
// Build the 4 vertices of each GL_QUAD
|
||||
coords[0].x = a.x;
|
||||
coords[0].y = -a.y;
|
||||
coords[1].x = coords[0].x;
|
||||
coords[1].y = coords[0].y; // only z change
|
||||
coords[2].x = b.x;
|
||||
coords[2].y = -b.y;
|
||||
coords[3].x = coords[2].x;
|
||||
coords[3].y = coords[2].y; // only z change
|
||||
|
||||
// Creates the GL_QUAD
|
||||
TransfertToGLlist( coords, aBiuTo3DUnits );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,46 +176,47 @@ void Draw3D_SolidHorizontalPolyPolygons( const SHAPE_POLY_SET& aPolysList,
|
|||
|
||||
// Set normal toward positive Z axis, for a solid object on the top side
|
||||
|
||||
//gluTessProperty( tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE );
|
||||
//gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD );
|
||||
//gluTessProperty( tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE );
|
||||
gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD );
|
||||
|
||||
glNormal3f( 0.0, 0.0, aNormal_Z_Orientation );
|
||||
|
||||
// Draw solid areas contained in this list
|
||||
SHAPE_POLY_SET polylist = aPolysList; // temporary copy for gluTessVertex
|
||||
|
||||
int startContour;
|
||||
|
||||
for( int side = 0; side < 2; side++ )
|
||||
{
|
||||
startContour = 1;
|
||||
|
||||
for ( SHAPE_POLY_SET::ITERATOR ii = polylist.Iterate(); ii; ++ii )
|
||||
for ( int idx = 0; idx < polylist.OutlineCount(); ++idx )
|
||||
{
|
||||
if( startContour == 1 )
|
||||
gluTessBeginPolygon( tess, NULL );
|
||||
|
||||
SHAPE_POLY_SET::POLYGON& curr_polywithholes = polylist.Polygon( idx ); // a polygon with holes
|
||||
|
||||
for( unsigned ipoly = 0; ipoly < curr_polywithholes.size(); ipoly++ )
|
||||
{
|
||||
gluTessBeginPolygon( tess, NULL );
|
||||
SHAPE_LINE_CHAIN& curr_poly = curr_polywithholes[ipoly]; // a simple polygon
|
||||
|
||||
gluTessBeginContour( tess );
|
||||
startContour = 0;
|
||||
}
|
||||
|
||||
v_data[0] = ii->x * aBiuTo3DUnits;
|
||||
v_data[1] = -ii->y * aBiuTo3DUnits;
|
||||
// gluTessVertex store pointers on data, not data, so do not store
|
||||
// different corners values in a temporary variable
|
||||
// but send pointer on each CPolyPt value in polylist
|
||||
// before calling gluDeleteTess
|
||||
gluTessVertex( tess, v_data, &ii.Get() );
|
||||
for( int ipt = 0; ipt < curr_poly.PointCount(); ipt++ )
|
||||
{
|
||||
v_data[0] = curr_poly.Point( ipt ).x * aBiuTo3DUnits;
|
||||
v_data[1] = -curr_poly.Point( ipt ).y * aBiuTo3DUnits;
|
||||
// gluTessVertex store pointers on data, not data, so do not store
|
||||
// different corners values in a temporary variable
|
||||
// but send pointer on each CPolyPt value in polylist
|
||||
// before calling gluDeleteTess
|
||||
gluTessVertex( tess, v_data, &curr_poly.Point( ipt ) );
|
||||
}
|
||||
|
||||
|
||||
if( ii.IsEndContour() )
|
||||
{
|
||||
gluTessEndContour( tess );
|
||||
gluTessEndPolygon( tess );
|
||||
startContour = 1;
|
||||
}
|
||||
|
||||
gluTessEndPolygon( tess );
|
||||
}
|
||||
|
||||
|
||||
if( aThickness == 0 )
|
||||
break;
|
||||
|
||||
|
@ -220,12 +228,6 @@ void Draw3D_SolidHorizontalPolyPolygons( const SHAPE_POLY_SET& aPolysList,
|
|||
glNormal3f( 0.0, 0.0, -aNormal_Z_Orientation );
|
||||
}
|
||||
|
||||
if( startContour == 0 )
|
||||
{
|
||||
gluTessEndContour( tess );
|
||||
gluTessEndPolygon( tess );
|
||||
}
|
||||
|
||||
gluDeleteTess( tess );
|
||||
|
||||
if( aThickness == 0 )
|
||||
|
@ -237,24 +239,6 @@ void Draw3D_SolidHorizontalPolyPolygons( const SHAPE_POLY_SET& aPolysList,
|
|||
}
|
||||
|
||||
|
||||
/* draw the solid polygon found in aPolysList
|
||||
* The first polygon is the main polygon, others are holes
|
||||
* See Draw3D_SolidHorizontalPolyPolygons for more info
|
||||
*/
|
||||
void Draw3D_SolidHorizontalPolygonWithHoles( const SHAPE_POLY_SET& aPolysList,
|
||||
int aZpos, int aThickness,
|
||||
double aBiuTo3DUnits, bool aUseTextures,
|
||||
float aNormal_Z_Orientation )
|
||||
{
|
||||
SHAPE_POLY_SET polygon( aPolysList );
|
||||
|
||||
polygon.Fracture();
|
||||
|
||||
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, aThickness, aBiuTo3DUnits, aUseTextures,
|
||||
aNormal_Z_Orientation );
|
||||
}
|
||||
|
||||
|
||||
/* draw a cylinder (a tube) using 3D primitives.
|
||||
* the cylinder axis is parallel to the Z axis
|
||||
* If aHeight = height of the cylinder is 0, only one ring will be drawn
|
||||
|
@ -274,6 +258,7 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
|
|||
coords.resize( 4 );
|
||||
|
||||
SHAPE_POLY_SET inner_cornerBuffer;
|
||||
|
||||
if( aThickness ) // build the the vertical inner polygon (hole)
|
||||
TransformCircleToPolygon( inner_cornerBuffer, aCenterPos,
|
||||
aRadius - (aThickness / 2), slice );
|
||||
|
@ -283,31 +268,28 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
|
|||
|
||||
// Draw the vertical outer side
|
||||
Draw3D_VerticalPolygonalCylinder( outer_cornerBuffer,
|
||||
aHeight, aZpos, false, aBiuTo3DUnits );
|
||||
aHeight, aZpos, false, aBiuTo3DUnits );
|
||||
|
||||
if( aThickness )
|
||||
// Draws the vertical inner side (hole)
|
||||
Draw3D_VerticalPolygonalCylinder( inner_cornerBuffer,
|
||||
aHeight, aZpos, true, aBiuTo3DUnits );
|
||||
aHeight, aZpos, true, aBiuTo3DUnits );
|
||||
}
|
||||
|
||||
if( aThickness )
|
||||
{
|
||||
// draw top (front) and bottom (back) horizontal sides (rings)
|
||||
outer_cornerBuffer.AddHole( inner_cornerBuffer.COutline( 0 ) );
|
||||
SHAPE_POLY_SET polygon = outer_cornerBuffer;
|
||||
|
||||
polygon.Fracture();
|
||||
|
||||
// draw top (front) horizontal ring
|
||||
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos + aHeight, 0, aBiuTo3DUnits, false,
|
||||
1.0f );
|
||||
Draw3D_SolidHorizontalPolyPolygons( outer_cornerBuffer, aZpos + aHeight,
|
||||
0, aBiuTo3DUnits, false, 1.0f );
|
||||
|
||||
if( aHeight )
|
||||
{
|
||||
// draw bottom (back) horizontal ring
|
||||
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, 0, aBiuTo3DUnits, false,
|
||||
-1.0f );
|
||||
Draw3D_SolidHorizontalPolyPolygons( outer_cornerBuffer, aZpos,
|
||||
0, aBiuTo3DUnits, false, -1.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -327,15 +309,15 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
|
|||
const int slice = SEGM_PER_CIRCLE;
|
||||
|
||||
// Build the points to approximate oblong cylinder by segments
|
||||
SHAPE_POLY_SET outer_cornerBuffer;
|
||||
SHAPE_POLY_SET cornerBuffer;
|
||||
|
||||
int segm_width = (aRadius * 2) + aThickness;
|
||||
TransformRoundedEndsSegmentToPolygon( outer_cornerBuffer, aAxis1Pos,
|
||||
TransformRoundedEndsSegmentToPolygon( cornerBuffer, aAxis1Pos,
|
||||
aAxis2Pos, slice, segm_width );
|
||||
|
||||
// Draw the oblong outer cylinder
|
||||
if( aHeight )
|
||||
Draw3D_VerticalPolygonalCylinder( outer_cornerBuffer, aHeight, aZpos,
|
||||
Draw3D_VerticalPolygonalCylinder( cornerBuffer, aHeight, aZpos,
|
||||
false, aBiuTo3DUnits );
|
||||
|
||||
if( aThickness )
|
||||
|
@ -352,19 +334,16 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
|
|||
|
||||
// Build the horizontal full polygon shape
|
||||
// (outer polygon shape - inner polygon shape)
|
||||
outer_cornerBuffer.AddHole( inner_cornerBuffer.COutline( 0 ) );
|
||||
|
||||
SHAPE_POLY_SET polygon( outer_cornerBuffer );
|
||||
polygon.Fracture();
|
||||
cornerBuffer.AddHole( inner_cornerBuffer.COutline( 0 ) );
|
||||
|
||||
// draw top (front) horizontal side (ring)
|
||||
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos + aHeight, 0, aBiuTo3DUnits, false,
|
||||
Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos + aHeight, 0, aBiuTo3DUnits, false,
|
||||
1.0f );
|
||||
|
||||
if( aHeight )
|
||||
{
|
||||
// draw bottom (back) horizontal side (ring)
|
||||
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, 0, aBiuTo3DUnits, false,
|
||||
Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos, 0, aBiuTo3DUnits, false,
|
||||
-1.0f );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,24 +48,6 @@ void Draw3D_SolidHorizontalPolyPolygons( const SHAPE_POLY_SET& aPolysList,
|
|||
bool aUseTextures,
|
||||
float aNormal_Z_Orientation );
|
||||
|
||||
/** draw the solid polygon found in aPolysList
|
||||
* The first polygonj is the main polygon, others are holes
|
||||
* @param aPolysList = the polygon with holes to draw
|
||||
* @param aZpos = z position in board internal units
|
||||
* @param aThickness = thickness in board internal units
|
||||
* @param aBiuTo3DUnits = board internal units to 3D units scaling value
|
||||
* @param aUseTextures = true to use textxures for the polygons
|
||||
* @param aNormal_Z_Orientation = the normal Z orientation to apply
|
||||
* If aThickness = 0, a polygon area is drawn in a XY plane at Z position = aZpos.
|
||||
* If aThickness > 0, a solid object is drawn.
|
||||
* The top side is located at aZpos + aThickness / 2
|
||||
* The bottom side is located at aZpos - aThickness / 2
|
||||
*/
|
||||
void Draw3D_SolidHorizontalPolygonWithHoles( const SHAPE_POLY_SET& aPolysList,
|
||||
int aZpos, int aThickness, double aBiuTo3DUnits,
|
||||
bool aUseTextures,
|
||||
float aNormal_Z_Orientation );
|
||||
|
||||
/** draw a thick segment using 3D primitives, in a XY plane
|
||||
* @param aStart = YX position of start point in board units
|
||||
* @param aEnd = YX position of end point in board units
|
||||
|
|
|
@ -85,11 +85,8 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
|
|||
bool useTextures = isRealisticMode() && isEnabled( FL_RENDER_TEXTURES );
|
||||
|
||||
// Number of segments to convert a circle to polygon
|
||||
// Boost polygon (at least v1.57 and previous) in very rare cases crashes
|
||||
// when using 16 segments to approximate a circle.
|
||||
// So using 18 segments is a workaround to try to avoid these crashes
|
||||
// ( We already used this trick in plot_board_layers.cpp,
|
||||
// see PlotSolderMaskLayer() )
|
||||
// We use 2 values: the first gives a good shape
|
||||
// the second is used to speed up calculations, when a poor approximation is acceptable (holes)
|
||||
const int segcountforcircle = 18;
|
||||
double correctionFactor = 1.0 / cos( M_PI / (segcountforcircle * 2.0) );
|
||||
const int segcountLowQuality = 12; // segments to draw a circle with low quality
|
||||
|
@ -119,22 +116,11 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
|
|||
}
|
||||
|
||||
bool throughHolesListBuilt = false; // flag to build the through hole polygon list only once
|
||||
|
||||
LSET cu_set = LSET::AllCuMask( GetPrm3DVisu().m_CopperLayersCount );
|
||||
|
||||
#if 1
|
||||
LAYER_ID cu_seq[MAX_CU_LAYERS]; // preferred sequence, could have called CuStack()
|
||||
// but I assume that's backwards
|
||||
|
||||
glNewList( aBoardList, GL_COMPILE );
|
||||
|
||||
for( unsigned i=0; i < DIM( cu_seq ); ++i )
|
||||
cu_seq[i] = ToLAYER_ID( B_Cu - i );
|
||||
|
||||
for( LSEQ cu = cu_set.Seq( cu_seq, DIM(cu_seq) ); cu; ++cu )
|
||||
#else
|
||||
for( LSEQ cu = cu_set.CuStack(); cu; ++cu )
|
||||
#endif
|
||||
{
|
||||
LAYER_ID layer = *cu;
|
||||
|
||||
|
@ -283,6 +269,9 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
|
|||
}
|
||||
}
|
||||
|
||||
if( !throughHolesListBuilt )
|
||||
allLayerHoles.Simplify();
|
||||
|
||||
// bufferPolys contains polygons to merge. Many overlaps .
|
||||
// Calculate merged polygons
|
||||
if( bufferPolys.IsEmpty() )
|
||||
|
@ -290,12 +279,10 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
|
|||
|
||||
// Use Clipper lib to subtract holes to copper areas
|
||||
|
||||
bufferPolys.Simplify();
|
||||
currLayerHoles.Append(allLayerHoles);
|
||||
currLayerHoles.Simplify();
|
||||
allLayerHoles.Simplify();
|
||||
|
||||
bufferPolys.BooleanSubtract( allLayerHoles );
|
||||
bufferPolys.Fracture();
|
||||
bufferPolys.BooleanSubtract( currLayerHoles );
|
||||
|
||||
int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer );
|
||||
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( layer );
|
||||
|
@ -339,7 +326,6 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
|
|||
if( aActivity )
|
||||
aActivity->Report( _( "Build board body" ) );
|
||||
|
||||
|
||||
// Draw plated vertical holes inside the board, but not always. They are drawn:
|
||||
// - if the board body is not shown, to show the holes.
|
||||
// - or if the copper thickness is shown
|
||||
|
@ -396,7 +382,6 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
|
|||
board_thickness -= copper_thickness + epsilon;
|
||||
|
||||
bufferPcbOutlines.BooleanSubtract( allLayerHoles );
|
||||
bufferPcbOutlines.Fracture();
|
||||
|
||||
if( !bufferPcbOutlines.IsEmpty() )
|
||||
{
|
||||
|
@ -469,6 +454,8 @@ void EDA_3D_CANVAS::buildTechLayers3DView( REPORTER* aErrorMessages, REPORTER* a
|
|||
segcountLowQuality );
|
||||
}
|
||||
|
||||
allLayerHoles.Simplify();
|
||||
|
||||
// draw graphic items, on technical layers
|
||||
|
||||
static const LAYER_ID teckLayerList[] = {
|
||||
|
@ -496,7 +483,6 @@ void EDA_3D_CANVAS::buildTechLayers3DView( REPORTER* aErrorMessages, REPORTER* a
|
|||
if( aActivity )
|
||||
aActivity->Report( wxString::Format( _( "Build layer %s" ), LSET::Name( layer ) ) );
|
||||
|
||||
|
||||
bufferPolys.RemoveAllContours();
|
||||
|
||||
for( BOARD_ITEM* item = pcb->m_Drawings; item; item = item->Next() )
|
||||
|
@ -565,8 +551,6 @@ void EDA_3D_CANVAS::buildTechLayers3DView( REPORTER* aErrorMessages, REPORTER* a
|
|||
if( bufferPolys.IsEmpty() )
|
||||
continue;
|
||||
|
||||
allLayerHoles.Simplify();
|
||||
|
||||
// Solder mask layers are "negative" layers.
|
||||
// Shapes should be removed from the full board area.
|
||||
if( layer == B_Mask || layer == F_Mask )
|
||||
|
@ -586,10 +570,6 @@ void EDA_3D_CANVAS::buildTechLayers3DView( REPORTER* aErrorMessages, REPORTER* a
|
|||
bufferPolys.BooleanSubtract( allLayerHoles );
|
||||
}
|
||||
|
||||
// Convert each polygon with holes to
|
||||
// a polygon with its holes linked to the main outline
|
||||
bufferPolys.Fracture();
|
||||
|
||||
int thickness = 0;
|
||||
|
||||
if( layer != B_Mask && layer != F_Mask )
|
||||
|
|
|
@ -644,7 +644,7 @@ void EDA_3D_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||
|
||||
case ID_MENU3D_SOLDER_PASTE_ONOFF:
|
||||
GetPrm3DVisu().SetFlag( FL_SOLDERPASTE, isChecked );
|
||||
NewDisplay();
|
||||
NewDisplay( GL_ID_TECH_LAYERS );
|
||||
return;
|
||||
|
||||
case ID_MENU3D_COMMENTS_ONOFF:
|
||||
|
|
|
@ -206,7 +206,8 @@ const SHAPE_LINE_CHAIN SHAPE_POLY_SET::convertFromClipper( const Path& aPath )
|
|||
return lc;
|
||||
}
|
||||
|
||||
|
||||
#include <common.h>
|
||||
#include <wx/wx.h>
|
||||
void SHAPE_POLY_SET::booleanOp( ClipType type, const SHAPE_POLY_SET& b )
|
||||
{
|
||||
Clipper c;
|
||||
|
@ -497,7 +498,7 @@ void SHAPE_POLY_SET::fractureSingle( POLYGON& paths )
|
|||
|
||||
void SHAPE_POLY_SET::Fracture()
|
||||
{
|
||||
Simplify(); // remove overlallping holes/degeneracy
|
||||
Simplify(); // remove overlapping holes/degeneracy
|
||||
|
||||
BOOST_FOREACH( POLYGON& paths, m_polys )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue