Pcbnew: fix issue when KICAD_NANOMETER is defined: when zones use htcth to show zones areas, hatch lines were incorrectly calculated (hunded of thousand lines created)
Eeschema: fix issue in search: search not made in reference strings. Minor fixes, code cleaning and comment enhancements.
This commit is contained in:
parent
54c20b57f2
commit
1c98200721
|
@ -31,7 +31,6 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "trigo.h"
|
#include "trigo.h"
|
||||||
#include "pcbstruct.h"
|
#include "pcbstruct.h"
|
||||||
#include "macros.h"
|
|
||||||
#include "drawtxt.h"
|
#include "drawtxt.h"
|
||||||
#include "confirm.h"
|
#include "confirm.h"
|
||||||
#include "layers_id_colors_and_visibility.h"
|
#include "layers_id_colors_and_visibility.h"
|
||||||
|
@ -171,7 +170,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List()
|
||||||
if( g_Parm_3D_Visu.m_Layers < 2 )
|
if( g_Parm_3D_Visu.m_Layers < 2 )
|
||||||
g_Parm_3D_Visu.m_Layers = 2;
|
g_Parm_3D_Visu.m_Layers = 2;
|
||||||
|
|
||||||
g_Parm_3D_Visu.m_BoardScale = 2.0 / MAX( g_Parm_3D_Visu.m_BoardSize.x,
|
g_Parm_3D_Visu.m_BoardScale = 2.0 / max( g_Parm_3D_Visu.m_BoardSize.x,
|
||||||
g_Parm_3D_Visu.m_BoardSize.y );
|
g_Parm_3D_Visu.m_BoardSize.y );
|
||||||
|
|
||||||
// @TODO: epoxy_width (board thickness) must be set by user,
|
// @TODO: epoxy_width (board thickness) must be set by user,
|
||||||
|
@ -911,7 +910,7 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas )
|
||||||
scale = g_Parm_3D_Visu.m_BoardScale;
|
scale = g_Parm_3D_Visu.m_BoardScale;
|
||||||
holeX = (double) m_Drill.x * scale / 2;
|
holeX = (double) m_Drill.x * scale / 2;
|
||||||
holeY = (double) m_Drill.y * scale / 2;
|
holeY = (double) m_Drill.y * scale / 2;
|
||||||
hole = MIN( holeX, holeY );
|
hole = fmin( holeX, holeY );
|
||||||
|
|
||||||
/* Calculate the center of the pad. */
|
/* Calculate the center of the pad. */
|
||||||
shape_pos = ReturnShapePos();
|
shape_pos = ReturnShapePos();
|
||||||
|
@ -1505,10 +1504,12 @@ void CALLBACK tesswxPoint2Vertex( const GLvoid* data )
|
||||||
|
|
||||||
void CALLBACK tessErrorCB( GLenum errorCode )
|
void CALLBACK tessErrorCB( GLenum errorCode )
|
||||||
{
|
{
|
||||||
|
#if defined(DEBUG)
|
||||||
const GLubyte* errorStr;
|
const GLubyte* errorStr;
|
||||||
|
|
||||||
errorStr = gluErrorString( errorCode );
|
errorStr = gluErrorString( errorCode );
|
||||||
|
|
||||||
// DEBUG //
|
// DEBUG //
|
||||||
D( printf( "Tess ERROR: %s\n", errorStr ); )
|
D( printf( "Tess ERROR: %s\n", errorStr ); )
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,11 +187,11 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType )
|
||||||
{
|
{
|
||||||
event.SetReplaceString( m_comboReplace->GetValue() );
|
event.SetReplaceString( m_comboReplace->GetValue() );
|
||||||
flags |= FR_SEARCH_REPLACE;
|
flags |= FR_SEARCH_REPLACE;
|
||||||
|
|
||||||
if( m_checkReplaceReferences->GetValue() )
|
|
||||||
flags |= FR_REPLACE_REFERENCES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_checkReplaceReferences->GetValue() )
|
||||||
|
flags |= FR_REPLACE_REFERENCES;
|
||||||
|
|
||||||
if( m_radioForward->GetValue() )
|
if( m_radioForward->GetValue() )
|
||||||
flags |= wxFR_DOWN;
|
flags |= wxFR_DOWN;
|
||||||
|
|
||||||
|
@ -232,6 +232,15 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType )
|
||||||
|
|
||||||
m_findReplaceData->SetFlags( event.GetFlags() );
|
m_findReplaceData->SetFlags( event.GetFlags() );
|
||||||
|
|
||||||
|
// when we are no using the find/replace (just find)
|
||||||
|
// FR_REPLACE_REFERENCES flag bit is always set to 1 in event flags
|
||||||
|
// but not set in m_findReplaceData
|
||||||
|
if ( ! HasFlag( wxFR_REPLACEDIALOG ) )
|
||||||
|
{
|
||||||
|
flags |= FR_REPLACE_REFERENCES;
|
||||||
|
event.SetFlags( flags );
|
||||||
|
}
|
||||||
|
|
||||||
if( !GetEventHandler()->ProcessEvent( event ) )
|
if( !GetEventHandler()->ProcessEvent( event ) )
|
||||||
{
|
{
|
||||||
GetParent()->GetEventHandler()->ProcessEvent( event );
|
GetParent()->GetEventHandler()->ProcessEvent( event );
|
||||||
|
|
|
@ -383,7 +383,7 @@ void GERBVIEW_FRAME::DrawItemsDCodeID( wxDC* aDC, int aDrawMode )
|
||||||
if( gerb_item->GetDcodeDescr() )
|
if( gerb_item->GetDcodeDescr() )
|
||||||
width = gerb_item->GetDcodeDescr()->GetShapeDim( gerb_item );
|
width = gerb_item->GetDcodeDescr()->GetShapeDim( gerb_item );
|
||||||
else
|
else
|
||||||
width = MIN( gerb_item->m_Size.x, gerb_item->m_Size.y );
|
width = min( gerb_item->m_Size.x, gerb_item->m_Size.y );
|
||||||
|
|
||||||
orient = TEXT_ORIENT_HORIZ;
|
orient = TEXT_ORIENT_HORIZ;
|
||||||
|
|
||||||
|
|
|
@ -278,7 +278,7 @@ void PCB_EDIT_FRAME::AutoMoveModulesOnPcb( bool PlaceModulesHorsPcb )
|
||||||
GetScreen()->SetCrossHairPosition( current + Module->m_Pos -
|
GetScreen()->SetCrossHairPosition( current + Module->m_Pos -
|
||||||
Module->m_BoundaryBox.GetPosition() );
|
Module->m_BoundaryBox.GetPosition() );
|
||||||
|
|
||||||
Ymax_size = MAX( Ymax_size, Module->m_BoundaryBox.GetHeight() );
|
Ymax_size = max( Ymax_size, Module->m_BoundaryBox.GetHeight() );
|
||||||
|
|
||||||
PlaceModule( Module, NULL, true );
|
PlaceModule( Module, NULL, true );
|
||||||
|
|
||||||
|
|
|
@ -235,7 +235,7 @@ double PCB_BASE_FRAME::BestZoom()
|
||||||
else
|
else
|
||||||
jj = 32.0;
|
jj = 32.0;
|
||||||
|
|
||||||
double bestzoom = MAX( ii, jj );
|
double bestzoom = max( ii, jj );
|
||||||
|
|
||||||
GetScreen()->SetScrollCenterPosition( bbbox.Centre() );
|
GetScreen()->SetScrollCenterPosition( bbbox.Centre() );
|
||||||
|
|
||||||
|
|
|
@ -532,27 +532,9 @@ void D_PAD:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCor
|
||||||
* and then moved and rotated acroding to the pad position and orientation
|
* and then moved and rotated acroding to the pad position and orientation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* WARNING:
|
/*
|
||||||
* When Kbool calculates the filled areas :
|
|
||||||
* i.e when substracting holes (thermal shapes) to the full zone area
|
|
||||||
* under certains circumstances kboll drop some holes.
|
|
||||||
* These circumstances are:
|
|
||||||
* some identical holes (same thermal shape and size) are *exactly* on the same vertical line
|
|
||||||
* And
|
|
||||||
* nothing else between holes
|
|
||||||
* And
|
|
||||||
* angles less than 90 deg between 2 consecutive lines in hole outline (sometime occurs without
|
|
||||||
* this condition)
|
|
||||||
* And
|
|
||||||
* a hole above the identical holes
|
|
||||||
*
|
|
||||||
* In fact, it is easy to find these conditions in pad arrays.
|
|
||||||
* So to avoid this, the workaround is do not use holes outlines that include
|
|
||||||
* angles less than 90 deg between 2 consecutive lines
|
|
||||||
* this is made in round and oblong thermal reliefs
|
|
||||||
*
|
|
||||||
* Note 1: polygons are drawm using outlines witk a thickness = aMinThicknessValue
|
* Note 1: polygons are drawm using outlines witk a thickness = aMinThicknessValue
|
||||||
* so shapes must keep in account this outline thickness
|
* so shapes must take in account this outline thickness
|
||||||
*
|
*
|
||||||
* Note 2:
|
* Note 2:
|
||||||
* Trapezoidal pads are not considered here because they are very special case
|
* Trapezoidal pads are not considered here because they are very special case
|
||||||
|
|
|
@ -611,7 +611,7 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wxPoint&
|
||||||
BOARD * brd = GetBoard( );
|
BOARD * brd = GetBoard( );
|
||||||
color = brd->GetLayerColor(m_Layer);
|
color = brd->GetLayerColor(m_Layer);
|
||||||
|
|
||||||
if( brd->IsLayerVisible( m_Layer ) == false && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG )
|
if( brd->IsLayerVisible( m_Layer ) == false && !( draw_mode & GR_HIGHLIGHT ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( DisplayOpt.ContrastModeDisplay )
|
if( DisplayOpt.ContrastModeDisplay )
|
||||||
|
|
|
@ -195,7 +195,7 @@ void DIALOG_GENDRILL::InitDisplayParams( void )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( MIN( pad->m_Drill.x, pad->m_Drill.y ) != 0 )
|
if( min( pad->m_Drill.x, pad->m_Drill.y ) != 0 )
|
||||||
{
|
{
|
||||||
if( pad->m_Attribut == PAD_HOLE_NOT_PLATED )
|
if( pad->m_Attribut == PAD_HOLE_NOT_PLATED )
|
||||||
m_notplatedPadsHoleCount++;
|
m_notplatedPadsHoleCount++;
|
||||||
|
|
|
@ -319,11 +319,11 @@ bool PCB_EDIT_FRAME::Add45DegreeSegment( wxDC* aDC )
|
||||||
dx1 = curTrack->m_End.x - curTrack->m_Start.x;
|
dx1 = curTrack->m_End.x - curTrack->m_Start.x;
|
||||||
dy1 = curTrack->m_End.y - curTrack->m_Start.y;
|
dy1 = curTrack->m_End.y - curTrack->m_Start.y;
|
||||||
|
|
||||||
// Segments must be of sufficient length.
|
// Segments should have a min length.
|
||||||
if( MAX( abs( dx0 ), abs( dy0 ) ) < ( segm_step_45 * 2 ) )
|
if( max( abs( dx0 ), abs( dy0 ) ) < ( segm_step_45 * 2 ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( MAX( abs( dx1 ), abs( dy1 ) ) < ( segm_step_45 * 2 ) )
|
if( max( abs( dx1 ), abs( dy1 ) ) < ( segm_step_45 * 2 ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Create a new segment and connect it with the previous 2 segments. */
|
/* Create a new segment and connect it with the previous 2 segments. */
|
||||||
|
@ -851,7 +851,7 @@ void CalculateSegmentEndPoint( const wxPoint& aPosition, int ox, int oy, int* fx
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 45:
|
case 45:
|
||||||
deltax = MIN( deltax, deltay );
|
deltax = min( deltax, deltay );
|
||||||
deltay = deltax;
|
deltay = deltax;
|
||||||
|
|
||||||
/* Recalculate the signs for deltax and deltaY. */
|
/* Recalculate the signs for deltax and deltaY. */
|
||||||
|
@ -946,7 +946,7 @@ void ComputeBreakPoint( TRACK* track, int SegmentCount, wxPoint end )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 45:
|
case 45:
|
||||||
iDx = MIN( iDx, iDy );
|
iDx = min( iDx, iDy );
|
||||||
iDy = iDx;
|
iDy = iDx;
|
||||||
|
|
||||||
/* Recalculate the signs for deltax and deltaY. */
|
/* Recalculate the signs for deltax and deltaY. */
|
||||||
|
|
|
@ -317,7 +317,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
|
||||||
if( GetBoard()->GetCopperLayerCount() < 2 ) // Single layer
|
if( GetBoard()->GetCopperLayerCount() < 2 ) // Single layer
|
||||||
ll = LAYER_N_BACK;
|
ll = LAYER_N_BACK;
|
||||||
else if( ll == LAYER_N_FRONT )
|
else if( ll == LAYER_N_FRONT )
|
||||||
ll = MAX( LAYER_N_BACK, GetBoard()->GetCopperLayerCount() - 2 );
|
ll = max( LAYER_N_BACK, GetBoard()->GetCopperLayerCount() - 2 );
|
||||||
else
|
else
|
||||||
ll--;
|
ll--;
|
||||||
|
|
||||||
|
|
|
@ -354,8 +354,8 @@ static void Print_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, MODULE* aModule,
|
||||||
pt_pad->m_Drill = wxSize(0,0);
|
pt_pad->m_Drill = wxSize(0,0);
|
||||||
break;
|
break;
|
||||||
case PRINT_PARAMETERS::SMALL_DRILL_SHAPE:
|
case PRINT_PARAMETERS::SMALL_DRILL_SHAPE:
|
||||||
pt_pad->m_Drill.x = MIN(SMALL_DRILL,pt_pad->m_Drill.x);
|
pt_pad->m_Drill.x = min(SMALL_DRILL,pt_pad->m_Drill.x);
|
||||||
pt_pad->m_Drill.y = MIN(SMALL_DRILL,pt_pad->m_Drill.y);
|
pt_pad->m_Drill.y = min(SMALL_DRILL,pt_pad->m_Drill.y);
|
||||||
break;
|
break;
|
||||||
case PRINT_PARAMETERS::FULL_DRILL_SHAPE:
|
case PRINT_PARAMETERS::FULL_DRILL_SHAPE:
|
||||||
// Do nothing
|
// Do nothing
|
||||||
|
|
|
@ -40,11 +40,12 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb )
|
||||||
* this zone
|
* this zone
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( GetNumCorners() <= 2 ) // malformed zone. Kbool does not like it ...
|
if( GetNumCorners() <= 2 ) // malformed zone. polygon calculations do not like it ...
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Make a smoothed polygon out of the user-drawn polygon if required
|
// Make a smoothed polygon out of the user-drawn polygon if required
|
||||||
if( smoothedPoly ) {
|
if( smoothedPoly )
|
||||||
|
{
|
||||||
delete smoothedPoly;
|
delete smoothedPoly;
|
||||||
smoothedPoly = NULL;
|
smoothedPoly = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
EDA_RECT item_boundingbox;
|
EDA_RECT item_boundingbox;
|
||||||
EDA_RECT zone_boundingbox = GetBoundingBox();
|
EDA_RECT zone_boundingbox = GetBoundingBox();
|
||||||
int biggest_clearance = aPcb->GetBiggestClearanceValue();
|
int biggest_clearance = aPcb->GetBiggestClearanceValue();
|
||||||
biggest_clearance = MAX( biggest_clearance, zone_clearance );
|
biggest_clearance = max( biggest_clearance, zone_clearance );
|
||||||
zone_boundingbox.Inflate( biggest_clearance );
|
zone_boundingbox.Inflate( biggest_clearance );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -220,7 +220,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
|
|
||||||
if( item_boundingbox.Intersects( zone_boundingbox ) )
|
if( item_boundingbox.Intersects( zone_boundingbox ) )
|
||||||
{
|
{
|
||||||
int clearance = MAX( zone_clearance, item_clearance );
|
int clearance = max( zone_clearance, item_clearance );
|
||||||
pad->TransformShapeWithClearanceToPolygon( cornerBufferPolysToSubstract,
|
pad->TransformShapeWithClearanceToPolygon( cornerBufferPolysToSubstract,
|
||||||
clearance,
|
clearance,
|
||||||
s_CircleToSegmentsCount,
|
s_CircleToSegmentsCount,
|
||||||
|
@ -267,7 +267,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
|
|
||||||
if( item_boundingbox.Intersects( zone_boundingbox ) )
|
if( item_boundingbox.Intersects( zone_boundingbox ) )
|
||||||
{
|
{
|
||||||
int clearance = MAX( zone_clearance, item_clearance );
|
int clearance = max( zone_clearance, item_clearance );
|
||||||
track->TransformShapeWithClearanceToPolygon( cornerBufferPolysToSubstract,
|
track->TransformShapeWithClearanceToPolygon( cornerBufferPolysToSubstract,
|
||||||
clearance,
|
clearance,
|
||||||
s_CircleToSegmentsCount,
|
s_CircleToSegmentsCount,
|
||||||
|
|
|
@ -42,7 +42,7 @@ void BuildUnconnectedThermalStubsPolygonList( std::vector<CPolyPt>& aCornerBuffe
|
||||||
EDA_RECT item_boundingbox;
|
EDA_RECT item_boundingbox;
|
||||||
EDA_RECT zone_boundingbox = aZone->GetBoundingBox();
|
EDA_RECT zone_boundingbox = aZone->GetBoundingBox();
|
||||||
int biggest_clearance = aPcb->GetBiggestClearanceValue();
|
int biggest_clearance = aPcb->GetBiggestClearanceValue();
|
||||||
biggest_clearance = MAX( biggest_clearance, zone_clearance );
|
biggest_clearance = max( biggest_clearance, zone_clearance );
|
||||||
zone_boundingbox.Inflate( biggest_clearance );
|
zone_boundingbox.Inflate( biggest_clearance );
|
||||||
|
|
||||||
// half size of the pen used to draw/plot zones outlines
|
// half size of the pen used to draw/plot zones outlines
|
||||||
|
|
|
@ -336,7 +336,7 @@ int BOARD::ClipAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList,
|
||||||
wxPoint(0, 0), CPolyLine::NO_HATCH );
|
wxPoint(0, 0), CPolyLine::NO_HATCH );
|
||||||
|
|
||||||
// remove the poly that was automatically created for the new area
|
// remove the poly that was automatically created for the new area
|
||||||
// and replace it with a poly from NormalizeWithKbool
|
// and replace it with a poly from NormalizeAreaOutlines
|
||||||
delete NewArea->m_Poly;
|
delete NewArea->m_Poly;
|
||||||
NewArea->m_Poly = new_p;
|
NewArea->m_Poly = new_p;
|
||||||
NewArea->m_Poly->Draw();
|
NewArea->m_Poly->Draw();
|
||||||
|
|
|
@ -7,14 +7,27 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "fctsys.h"
|
#include "fctsys.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include "PolyLine.h"
|
#include "PolyLine.h"
|
||||||
#include "gr_basic.h"
|
#include "gr_basic.h"
|
||||||
#include "bezier_curves.h"
|
#include "bezier_curves.h"
|
||||||
#include "polygon_test_point_inside.h"
|
#include "polygon_test_point_inside.h"
|
||||||
|
|
||||||
using namespace std;
|
#if defined(KICAD_NANOMETRE)
|
||||||
|
#define PCBU_PER_MIL (1000.0*25.4)
|
||||||
|
#else
|
||||||
|
#define PCBU_PER_MIL 10
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define to_int( x ) wxRound( (x) )
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN( x1, x2 ) ( (x1) > (x2) ? (x2) : (x1) )
|
||||||
|
#endif
|
||||||
|
#ifndef MAX
|
||||||
|
#define MAX( x1, x2 ) ( (x1) > (x2) ? (x1) : (x2) )
|
||||||
|
#endif
|
||||||
|
|
||||||
#define pi M_PI
|
#define pi M_PI
|
||||||
|
|
||||||
|
@ -1386,21 +1399,13 @@ int CPolyLine::GetClosed()
|
||||||
void CPolyLine::Hatch()
|
void CPolyLine::Hatch()
|
||||||
{
|
{
|
||||||
m_HatchLines.clear();
|
m_HatchLines.clear();
|
||||||
if( m_HatchStyle == NO_HATCH )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int layer = GetLayer();
|
if( m_HatchStyle == NO_HATCH )
|
||||||
|
return;
|
||||||
|
|
||||||
if( !GetClosed() ) // If not closed, the poly is beeing created and not finalised. Not not hatch
|
if( !GetClosed() ) // If not closed, the poly is beeing created and not finalised. Not not hatch
|
||||||
return;
|
return;
|
||||||
|
|
||||||
enum {
|
|
||||||
MAXPTS = 100
|
|
||||||
};
|
|
||||||
int xx[MAXPTS], yy[MAXPTS];
|
|
||||||
|
|
||||||
// define range for hatch lines
|
// define range for hatch lines
|
||||||
int min_x = corner[0].x;
|
int min_x = corner[0].x;
|
||||||
int max_x = corner[0].x;
|
int max_x = corner[0].x;
|
||||||
|
@ -1418,13 +1423,19 @@ void CPolyLine::Hatch()
|
||||||
max_y = corner[ic].y;
|
max_y = corner[ic].y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1
|
// Calculate spacing betwwen 2 hatch lines
|
||||||
double slope = 0.707106 * slope_flag;
|
|
||||||
int spacing;
|
int spacing;
|
||||||
if( m_HatchStyle == DIAGONAL_EDGE )
|
if( m_HatchStyle == DIAGONAL_EDGE )
|
||||||
spacing = 10 * PCBU_PER_MIL;
|
spacing = 20 * PCBU_PER_MIL;
|
||||||
else
|
else
|
||||||
spacing = 50 * PCBU_PER_MIL;
|
spacing = 50 * PCBU_PER_MIL;
|
||||||
|
// set the "lenght" of hatch lines (the lenght on horizontal axis)
|
||||||
|
double hatch_line_len = 20 * PCBU_PER_MIL;
|
||||||
|
|
||||||
|
// To have a better look, give a slope depending on the layer
|
||||||
|
int layer = GetLayer();
|
||||||
|
int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1
|
||||||
|
double slope = 0.707106 * slope_flag; // 45 degrees slope
|
||||||
int max_a, min_a;
|
int max_a, min_a;
|
||||||
if( slope_flag == 1 )
|
if( slope_flag == 1 )
|
||||||
{
|
{
|
||||||
|
@ -1438,7 +1449,8 @@ void CPolyLine::Hatch()
|
||||||
}
|
}
|
||||||
min_a = (min_a / spacing) * spacing;
|
min_a = (min_a / spacing) * spacing;
|
||||||
|
|
||||||
// calculate an offset depending on layer number, for a better display of hatches on a multilayer board
|
// calculate an offset depending on layer number,
|
||||||
|
// for a better look of hatches on a multilayer board
|
||||||
int offset = (layer * 7) / 8;
|
int offset = (layer * 7) / 8;
|
||||||
min_a += offset;
|
min_a += offset;
|
||||||
|
|
||||||
|
@ -1446,112 +1458,119 @@ void CPolyLine::Hatch()
|
||||||
int nc = corner.size();
|
int nc = corner.size();
|
||||||
|
|
||||||
// loop through hatch lines
|
// loop through hatch lines
|
||||||
for( int a = min_a; a<max_a; a += spacing )
|
#define MAXPTS 200 // Usually we store only few values
|
||||||
|
// depending on the compexity of the zone outline
|
||||||
|
static std::vector <CPoint> pointbuffer;
|
||||||
|
pointbuffer.clear();
|
||||||
|
pointbuffer.reserve(MAXPTS+2);
|
||||||
|
for( int a = min_a; a < max_a; a += spacing )
|
||||||
{
|
{
|
||||||
// get intersection points for this hatch line
|
// get intersection points for this hatch line
|
||||||
int nloops = 0;
|
|
||||||
int npts;
|
|
||||||
|
|
||||||
// make this a loop in case my homebrew hatching algorithm screws up
|
// Note: because we should have an even number of intersections with the
|
||||||
do
|
// current hatch line and the zone outline, if we have an odd count if found
|
||||||
|
// we skip this line (should not occur)
|
||||||
|
pointbuffer.clear();
|
||||||
|
int i_start_contour = 0;
|
||||||
|
for( int ic = 0; ic<nc; ic++ )
|
||||||
{
|
{
|
||||||
npts = 0;
|
double x, y, x2, y2;
|
||||||
int i_start_contour = 0;
|
int ok;
|
||||||
for( int ic = 0; ic<nc; ic++ )
|
if( corner[ic].end_contour || ( ic == (int) (corner.size() - 1) ) )
|
||||||
{
|
{
|
||||||
double x, y, x2, y2;
|
ok = FindLineSegmentIntersection( a, slope,
|
||||||
int ok;
|
corner[ic].x, corner[ic].y,
|
||||||
if( corner[ic].end_contour || ( ic == (int) (corner.size() - 1) ) )
|
corner[i_start_contour].x,
|
||||||
{
|
corner[i_start_contour].y,
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
side_style[ic],
|
||||||
corner[ic].x, corner[ic].y,
|
&x, &y, &x2, &y2 );
|
||||||
corner[i_start_contour].x,
|
i_start_contour = ic + 1;
|
||||||
corner[i_start_contour].y,
|
|
||||||
side_style[ic],
|
|
||||||
&x, &y, &x2, &y2 );
|
|
||||||
i_start_contour = ic + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
|
||||||
corner[ic].x, corner[ic].y,
|
|
||||||
corner[ic + 1].x, corner[ic + 1].y,
|
|
||||||
side_style[ic],
|
|
||||||
&x, &y, &x2, &y2 );
|
|
||||||
}
|
|
||||||
if( ok )
|
|
||||||
{
|
|
||||||
xx[npts] = (int) x;
|
|
||||||
yy[npts] = (int) y;
|
|
||||||
npts++;
|
|
||||||
wxASSERT( npts<MAXPTS ); // overflow
|
|
||||||
}
|
|
||||||
if( ok == 2 )
|
|
||||||
{
|
|
||||||
xx[npts] = (int) x2;
|
|
||||||
yy[npts] = (int) y2;
|
|
||||||
npts++;
|
|
||||||
wxASSERT( npts<MAXPTS ); // overflow
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok = FindLineSegmentIntersection( a, slope,
|
||||||
|
corner[ic].x, corner[ic].y,
|
||||||
|
corner[ic + 1].x, corner[ic + 1].y,
|
||||||
|
side_style[ic],
|
||||||
|
&x, &y, &x2, &y2 );
|
||||||
|
}
|
||||||
|
if( ok )
|
||||||
|
{
|
||||||
|
CPoint point( (int) x, (int) y);
|
||||||
|
pointbuffer.push_back( point );
|
||||||
|
}
|
||||||
|
if( ok == 2 )
|
||||||
|
{
|
||||||
|
CPoint point( (int) x2, (int) y2);
|
||||||
|
pointbuffer.push_back( point );
|
||||||
|
}
|
||||||
|
if( pointbuffer.size() >= MAXPTS ) // overflow
|
||||||
|
{
|
||||||
|
wxASSERT( 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nloops++;
|
// ensure we have found an even intersection points count
|
||||||
a += PCBU_PER_MIL / 100;
|
// because a segment has 2 points.
|
||||||
} while( npts % 2 != 0 && nloops < 3 );
|
// if not, this is a strange case (a bug ?) so skip this hatch
|
||||||
|
if( pointbuffer.size() % 2 != 0 )
|
||||||
/* DICK 1/22/08: this was firing repeatedly on me, needed to comment out to get
|
continue;
|
||||||
* my work done:
|
|
||||||
* wxASSERT( npts%2==0 ); // odd number of intersection points, error
|
|
||||||
*/
|
|
||||||
|
|
||||||
// sort points in order of descending x (if more than 2)
|
// sort points in order of descending x (if more than 2)
|
||||||
if( npts>2 )
|
if( pointbuffer.size() > 2 )
|
||||||
{
|
{
|
||||||
for( int istart = 0; istart<(npts - 1); istart++ )
|
for( unsigned istart = 0; istart < (pointbuffer.size() - 1); istart++ )
|
||||||
{
|
{
|
||||||
int max_x = INT_MIN;
|
int max_x = INT_MIN;
|
||||||
int imax = INT_MIN;
|
int imax = INT_MIN;
|
||||||
for( int i = istart; i<npts; i++ )
|
for( unsigned i = istart; i < pointbuffer.size(); i++ )
|
||||||
{
|
{
|
||||||
if( xx[i] > max_x )
|
if( pointbuffer[i].x > max_x )
|
||||||
{
|
{
|
||||||
max_x = xx[i];
|
max_x = pointbuffer[i].x;
|
||||||
imax = i;
|
imax = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int temp = xx[istart];
|
CPoint temp = pointbuffer[istart];
|
||||||
xx[istart] = xx[imax];
|
pointbuffer[istart] = pointbuffer[imax];
|
||||||
xx[imax] = temp;
|
pointbuffer[imax] = temp;
|
||||||
temp = yy[istart];
|
|
||||||
yy[istart] = yy[imax];
|
|
||||||
yy[imax] = temp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw lines
|
// creates lines
|
||||||
for( int ip = 0; ip<npts; ip += 2 )
|
for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 )
|
||||||
{
|
{
|
||||||
double dx = xx[ip + 1] - xx[ip];
|
double dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
|
||||||
if( m_HatchStyle == DIAGONAL_FULL || fabs( dx ) < 40 * NM_PER_MIL )
|
// Push only one line for diagonal hatch,
|
||||||
|
// or for small lines < twice the line len
|
||||||
|
// else push 2 small lines
|
||||||
|
if( m_HatchStyle == DIAGONAL_FULL || fabs( dx ) < 2 * hatch_line_len )
|
||||||
{
|
{
|
||||||
m_HatchLines.push_back( CSegment( xx[ip], yy[ip], xx[ip + 1], yy[ip + 1] ) );
|
m_HatchLines.push_back( CSegment( pointbuffer[ip].x,
|
||||||
|
pointbuffer[ip].y,
|
||||||
|
pointbuffer[ip + 1].x,
|
||||||
|
pointbuffer[ip + 1].y ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double dy = yy[ip + 1] - yy[ip];
|
double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y;
|
||||||
double slope = dy / dx;
|
double slope = dy / dx;
|
||||||
if( dx > 0 )
|
if( dx > 0 )
|
||||||
dx = 20 * NM_PER_MIL;
|
dx = hatch_line_len;
|
||||||
else
|
else
|
||||||
dx = -20 * NM_PER_MIL;
|
dx = -hatch_line_len;
|
||||||
double x1 = xx[ip] + dx;
|
double x1 = pointbuffer[ip].x + dx;
|
||||||
double x2 = xx[ip + 1] - dx;
|
double x2 = pointbuffer[ip + 1].x - dx;
|
||||||
double y1 = yy[ip] + dx * slope;
|
double y1 = pointbuffer[ip].y + dx * slope;
|
||||||
double y2 = yy[ip + 1] - dx * slope;
|
double y2 = pointbuffer[ip + 1].y - dx * slope;
|
||||||
m_HatchLines.push_back( CSegment( xx[ip], yy[ip], to_int( x1 ), to_int( y1 ) ) );
|
m_HatchLines.push_back( CSegment( pointbuffer[ip].x,
|
||||||
m_HatchLines.push_back( CSegment( xx[ip + 1], yy[ip + 1], to_int( x2 ),
|
pointbuffer[ip].y,
|
||||||
to_int( y2 ) ) );
|
to_int( x1 ), to_int( y1 ) ) );
|
||||||
|
m_HatchLines.push_back( CSegment( pointbuffer[ip + 1].x,
|
||||||
|
pointbuffer[ip + 1].y,
|
||||||
|
to_int( x2 ), to_int( y2 ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,18 +42,6 @@ enum
|
||||||
*/
|
*/
|
||||||
void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false );
|
void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false );
|
||||||
|
|
||||||
|
|
||||||
#define PCBU_PER_MIL 10
|
|
||||||
#define NM_PER_MIL 10 // 25400
|
|
||||||
|
|
||||||
#define to_int( x ) wxRound( (x) )
|
|
||||||
#ifndef MIN
|
|
||||||
#define MIN( x1, x2 ) ( (x1) > (x2) ? (x2) : (x1) )
|
|
||||||
#endif
|
|
||||||
#ifndef MAX
|
|
||||||
#define MAX( x1, x2 ) ( (x1) > (x2) ? (x1) : (x2) )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class CRect
|
class CRect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include "PolyLine.h"
|
#include "PolyLine.h"
|
||||||
|
|
||||||
using namespace std;
|
#define NM_PER_MIL 25400
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -732,7 +732,6 @@ bool FindLineEllipseIntersections( double a, double b, double c, double d, doubl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Get clearance between 2 segments
|
// Get clearance between 2 segments
|
||||||
// Returns point in segment closest to other segment in x, y
|
// Returns point in segment closest to other segment in x, y
|
||||||
// in clearance > max_cl, just returns max_cl and doesn't return x,y
|
// in clearance > max_cl, just returns max_cl and doesn't return x,y
|
||||||
|
@ -916,7 +915,6 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Get min. distance from (x,y) to line y = a + bx
|
// Get min. distance from (x,y) to line y = a + bx
|
||||||
// if b > DBL_MAX/10, assume vertical line at x = a
|
// if b > DBL_MAX/10, assume vertical line at x = a
|
||||||
// returns closest point on line in xp, yp
|
// returns closest point on line in xp, yp
|
||||||
|
@ -1056,7 +1054,7 @@ int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||||
double yr = el2->yrad*yscale;
|
double yr = el2->yrad*yscale;
|
||||||
// now test NSTEPS positions in arc, moving clockwise (ie. decreasing theta)
|
// now test NSTEPS positions in arc, moving clockwise (ie. decreasing theta)
|
||||||
double step = M_PI/((NSTEPS-1)*2.0);
|
double step = M_PI/((NSTEPS-1)*2.0);
|
||||||
double d_prev=0, th_prev;
|
double d_prev=0;
|
||||||
double th_interp;
|
double th_interp;
|
||||||
double th1;
|
double th1;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
@ -1101,7 +1099,6 @@ int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d_prev = d;
|
d_prev = d;
|
||||||
th_prev = theta;
|
|
||||||
}
|
}
|
||||||
if( x1 )
|
if( x1 )
|
||||||
*x1 = xret[0];
|
*x1 = xret[0];
|
||||||
|
@ -1196,4 +1193,3 @@ double GetArcClearance( EllipseKH * el1, EllipseKH * el2,
|
||||||
*y1 = ymin;
|
*y1 = ymin;
|
||||||
return dmin;
|
return dmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue