Finish implementation of DRAWSEGMENT::C_RECT.
It's currently only supported in the Footprint Editor. It could be easily added to the board editor (all the code is there), but the board editor is a little short on room in the drawing tools toolbar.
This commit is contained in:
parent
4480759599
commit
aeed8e6e2c
|
@ -781,6 +781,31 @@ void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const DRAWSEGMENT* aDrawSe
|
|||
}
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
aDrawSegment->GetRectCorners( &pts );
|
||||
|
||||
const SFVEC2F topLeft3DU( pts[0].x * m_biuTo3Dunits, -pts[0].y * m_biuTo3Dunits );
|
||||
const SFVEC2F topRight3DU( pts[1].x * m_biuTo3Dunits, -pts[1].y * m_biuTo3Dunits );
|
||||
const SFVEC2F botRight3DU( pts[2].x * m_biuTo3Dunits, -pts[2].y * m_biuTo3Dunits );
|
||||
const SFVEC2F botLeft3DU( pts[3].x * m_biuTo3Dunits, -pts[3].y * m_biuTo3Dunits );
|
||||
|
||||
aDstContainer->Add( new CROUNDSEGMENT2D( topLeft3DU, topRight3DU,
|
||||
linewidth * m_biuTo3Dunits,
|
||||
*aDrawSegment ) );
|
||||
aDstContainer->Add( new CROUNDSEGMENT2D( topRight3DU, botRight3DU,
|
||||
linewidth * m_biuTo3Dunits,
|
||||
*aDrawSegment ) );
|
||||
aDstContainer->Add( new CROUNDSEGMENT2D( botRight3DU, botLeft3DU,
|
||||
linewidth * m_biuTo3Dunits,
|
||||
*aDrawSegment ) );
|
||||
aDstContainer->Add( new CROUNDSEGMENT2D( botLeft3DU, topLeft3DU,
|
||||
linewidth * m_biuTo3Dunits,
|
||||
*aDrawSegment ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
{
|
||||
const unsigned int nr_segments =
|
||||
|
@ -812,8 +837,7 @@ void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const DRAWSEGMENT* aDrawSe
|
|||
}
|
||||
else
|
||||
{
|
||||
aDstContainer->Add( new CROUNDSEGMENT2D( start3DU,
|
||||
end3DU,
|
||||
aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU,
|
||||
linewidth * m_biuTo3Dunits,
|
||||
*aDrawSegment ) );
|
||||
}
|
||||
|
@ -832,8 +856,8 @@ void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const DRAWSEGMENT* aDrawSe
|
|||
if( polyList.IsEmpty() ) // Just for caution
|
||||
break;
|
||||
|
||||
Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer,
|
||||
m_biuTo3Dunits, *aDrawSegment );
|
||||
Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits,
|
||||
*aDrawSegment );
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -656,6 +656,7 @@ void EDA_RECT::Merge( const wxPoint& aPoint )
|
|||
{
|
||||
m_Pos = aPoint;
|
||||
m_Size = wxSize( 0, 0 );
|
||||
m_init = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ fp_circle
|
|||
fp_curve
|
||||
fp_line
|
||||
fp_poly
|
||||
fp_rect
|
||||
fp_text
|
||||
full
|
||||
general
|
||||
|
@ -115,6 +116,7 @@ gr_circle
|
|||
gr_curve
|
||||
gr_line
|
||||
gr_poly
|
||||
gr_rect
|
||||
gr_text
|
||||
hatch
|
||||
hatch_thickness
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <pcbnew.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <gr_basic.h>
|
||||
#include <macros.h>
|
||||
#include <msgpanel.h>
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
|
@ -43,7 +42,6 @@
|
|||
#include <widgets/progress_reporter.h>
|
||||
|
||||
#include "ar_autoplacer.h"
|
||||
#include "ar_cell.h"
|
||||
#include "ar_matrix.h"
|
||||
#include <memory>
|
||||
|
||||
|
@ -53,6 +51,15 @@
|
|||
|
||||
#define STEP_AR_MM 1.0
|
||||
|
||||
/* Bits characterizing cell */
|
||||
#define CELL_IS_EMPTY 0x00
|
||||
#define CELL_IS_HOLE 0x01 /* a conducting hole or obstacle */
|
||||
#define CELL_IS_MODULE 0x02 /* auto placement occupied by a module */
|
||||
#define CELL_IS_EDGE 0x20 /* Area and auto-placement: limiting cell contour (Board, Zone) */
|
||||
#define CELL_IS_FRIEND 0x40 /* Area and auto-placement: cell part of the net */
|
||||
#define CELL_IS_ZONE 0x80 /* Area and auto-placement: cell available */
|
||||
|
||||
|
||||
/* Penalty (cost) for CntRot90 and CntRot180:
|
||||
* CntRot90 and CntRot180 are from 0 (rotation allowed) to 10 (rotation not allowed)
|
||||
*/
|
||||
|
@ -265,7 +272,6 @@ bool AR_AUTOPLACER::fillMatrix()
|
|||
}
|
||||
|
||||
|
||||
|
||||
void AR_AUTOPLACER::rotateModule( MODULE* module, double angle, bool incremental )
|
||||
{
|
||||
if( module == NULL )
|
||||
|
@ -485,22 +491,6 @@ int AR_AUTOPLACER::testRectangle( const EDA_RECT& aRect, int side )
|
|||
return AR_FREE_CELL;
|
||||
}
|
||||
|
||||
int AR_AUTOPLACER::testModuleByPolygon( MODULE* aModule, int aSide, const wxPoint& aOffset )
|
||||
{
|
||||
// Test for footprint out of board:
|
||||
// If a footprint is not fully inside the board, substract board polygon
|
||||
// to the footprint polygon gives a non null area.
|
||||
SHAPE_POLY_SET fp_area = m_fpAreaTop;
|
||||
fp_area.Move( -aOffset );
|
||||
SHAPE_POLY_SET out_of_board_area;
|
||||
out_of_board_area.BooleanSubtract( fp_area, m_topFreeArea, SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
if( out_of_board_area.OutlineCount() )
|
||||
return AR_OCCUIPED_BY_MODULE;
|
||||
|
||||
return AR_FREE_CELL;
|
||||
}
|
||||
|
||||
|
||||
/* Calculates and returns the clearance area of the rectangular surface
|
||||
* aRect):
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#ifndef __AR_AUTOPLACER_H
|
||||
#define __AR_AUTOPLACER_H
|
||||
|
||||
#include "ar_cell.h"
|
||||
#include "ar_matrix.h"
|
||||
|
||||
#include <class_board.h>
|
||||
|
@ -63,13 +62,6 @@ public:
|
|||
AR_RESULT AutoplaceModules( std::vector<MODULE*> aModules, BOARD_COMMIT* aCommit,
|
||||
bool aPlaceOffboardModules = false );
|
||||
|
||||
const std::vector<MODULE*> QueryOffboardModules();
|
||||
|
||||
void SetPlacementGrid( int aGrid )
|
||||
{
|
||||
m_gridSize = aGrid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a VIEW overlay to draw items during a autoplace session.
|
||||
*/
|
||||
|
@ -104,7 +96,6 @@ private:
|
|||
void genModuleOnRoutingMatrix( MODULE* Module );
|
||||
|
||||
int testRectangle( const EDA_RECT& aRect, int side );
|
||||
int testModuleByPolygon( MODULE* aModule,int aSide, const wxPoint& aOffset );
|
||||
unsigned int calculateKeepOutArea( const EDA_RECT& aRect, int side );
|
||||
int testModuleOnBoard( MODULE* aModule, bool TstOtherSide, const wxPoint& aOffset );
|
||||
int getOptimalModulePlacement( MODULE* aModule );
|
||||
|
@ -140,7 +131,6 @@ private:
|
|||
BOARD* m_board;
|
||||
|
||||
wxPoint m_curPosition;
|
||||
wxPoint m_moduleOffset;
|
||||
double m_minCost;
|
||||
int m_gridSize;
|
||||
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
*
|
||||
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* First copyright (C) Randy Nevin, 1989 (see PCBCA package)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _AR_CELL_H_
|
||||
#define _AR_CELL_H_
|
||||
|
||||
/* Bits characterizing cell */
|
||||
#define CELL_IS_EMPTY 0x00
|
||||
#define CELL_IS_HOLE 0x01 /* a conducting hole or obstacle */
|
||||
#define CELL_IS_MODULE 0x02 /* auto placement occupied by a module */
|
||||
#define CELL_IS_EDGE 0x20 /* Area and auto-placement: limiting cell contour (Board, Zone) */
|
||||
#define CELL_IS_FRIEND 0x40 /* Area and auto-placement: cell part of the net */
|
||||
#define CELL_IS_ZONE 0x80 /* Area and auto-placement: cell available */
|
||||
|
||||
/* Bit masks for presence of obstacles to autorouting */
|
||||
#define OCCUPE 1 /* Autorouting: obstacle tracks and vias. */
|
||||
#define VIA_IMPOSSIBLE 2 /* Autorouting: obstacle for vias. */
|
||||
#define CURRENT_PAD 4
|
||||
|
||||
|
||||
/* traces radiating outward from a hole to a side or corner */
|
||||
#define HOLE_NORTH 0x00000002L /* upward */
|
||||
#define HOLE_NORTHEAST 0x00000004L /* upward and right */
|
||||
#define HOLE_EAST 0x00000008L /* to the right */
|
||||
#define HOLE_SOUTHEAST 0x00000010L /* downward and right */
|
||||
#define HOLE_SOUTH 0x00000020L /* downward */
|
||||
#define HOLE_SOUTHWEST 0x00000040L /* downward and left */
|
||||
#define HOLE_WEST 0x00000080L /* to the left */
|
||||
#define HOLE_NORTHWEST 0x00000100L /* upward and left */
|
||||
|
||||
/* straight lines through the center */
|
||||
#define LINE_HORIZONTAL 0x00000002L /* left-to-right line */
|
||||
#define LINE_VERTICAL 0x00000004L /* top-to-bottom line */
|
||||
|
||||
/* lines cutting across a corner, connecting adjacent sides */
|
||||
#define CORNER_NORTHEAST 0x00000008L /* upper right corner */
|
||||
#define CORNER_SOUTHEAST 0x00000010L /* lower right corner */
|
||||
#define CORNER_SOUTHWEST 0x00000020L /* lower left corner */
|
||||
#define CORNER_NORTHWEST 0x00000040L /* upper left corner */
|
||||
|
||||
/* diagonal lines through the center */
|
||||
#define DIAG_NEtoSW 0x00000080L /* northeast to southwest */
|
||||
#define DIAG_SEtoNW 0x00000100L /* southeast to northwest */
|
||||
|
||||
/* 135 degree angle side-to-far-corner lines */
|
||||
#define BENT_NtoSE 0x00000200L /* north to southeast */
|
||||
#define BENT_NtoSW 0x00000400L /* north to southwest */
|
||||
#define BENT_EtoSW 0x00000800L /* east to southwest */
|
||||
#define BENT_EtoNW 0x00001000L /* east to northwest */
|
||||
#define BENT_StoNW 0x00002000L /* south to northwest */
|
||||
#define BENT_StoNE 0x00004000L /* south to northeast */
|
||||
#define BENT_WtoNE 0x00008000L /* west to northeast */
|
||||
#define BENT_WtoSE 0x00010000L /* west to southeast */
|
||||
|
||||
/* 90 degree corner-to-adjacent-corner lines */
|
||||
#define ANGLE_NEtoSE 0x00020000L /* northeast to southeast */
|
||||
#define ANGLE_SEtoSW 0x00040000L /* southeast to southwest */
|
||||
#define ANGLE_SWtoNW 0x00080000L /* southwest to northwest */
|
||||
#define ANGLE_NWtoNE 0x00100000L /* northwest to northeast */
|
||||
|
||||
/* 45 degree angle side-to-near-corner lines */
|
||||
#define SHARP_NtoNE 0x00200000L /* north to northeast */
|
||||
#define SHARP_EtoNE 0x00400000L /* east to northeast */
|
||||
#define SHARP_EtoSE 0x00800000L /* east to southeast */
|
||||
#define SHARP_StoSE 0x01000000L /* south to southeast */
|
||||
#define SHARP_StoSW 0x02000000L /* south to southwest */
|
||||
#define SHARP_WtoSW 0x04000000L /* west to southwest */
|
||||
#define SHARP_WtoNW 0x08000000L /* west to northwest */
|
||||
#define SHARP_NtoNW 0x10000000L /* north to northwest */
|
||||
|
||||
/* directions the cell can be reached from (point to previous cell) */
|
||||
#define FROM_NOWHERE 0
|
||||
#define FROM_NORTH 1
|
||||
#define FROM_NORTHEAST 2
|
||||
#define FROM_EAST 3
|
||||
#define FROM_SOUTHEAST 4
|
||||
#define FROM_SOUTH 5
|
||||
#define FROM_SOUTHWEST 6
|
||||
#define FROM_WEST 7
|
||||
#define FROM_NORTHWEST 8
|
||||
#define FROM_OTHERSIDE 9
|
||||
|
||||
|
||||
#endif // __AR_CELL_H
|
|
@ -26,16 +26,12 @@
|
|||
*/
|
||||
|
||||
#include "ar_matrix.h"
|
||||
#include "ar_cell.h"
|
||||
|
||||
#include <common.h>
|
||||
#include <math/util.h> // for KiROUND
|
||||
#include <math_for_graphics.h>
|
||||
#include <trigo.h>
|
||||
|
||||
#include <class_drawsegment.h>
|
||||
#include <class_pad.h>
|
||||
#include <class_track.h>
|
||||
|
||||
AR_MATRIX::AR_MATRIX()
|
||||
{
|
||||
|
@ -46,7 +42,6 @@ AR_MATRIX::AR_MATRIX()
|
|||
m_DirSide[0] = nullptr;
|
||||
m_DirSide[1] = nullptr;
|
||||
m_opWriteCell = nullptr;
|
||||
m_InitMatrixDone = false;
|
||||
m_Nrows = 0;
|
||||
m_Ncols = 0;
|
||||
m_MemSize = 0;
|
||||
|
@ -100,8 +95,6 @@ int AR_MATRIX::InitRoutingMatrix()
|
|||
if( m_Nrows <= 0 || m_Ncols <= 0 )
|
||||
return 0;
|
||||
|
||||
m_InitMatrixDone = true; // we have been called
|
||||
|
||||
// give a small margin for memory allocation:
|
||||
int ii = ( m_Nrows + 1 ) * ( m_Ncols + 1 );
|
||||
|
||||
|
@ -147,8 +140,6 @@ void AR_MATRIX::UnInitRoutingMatrix()
|
|||
{
|
||||
int ii;
|
||||
|
||||
m_InitMatrixDone = false;
|
||||
|
||||
for( ii = 0; ii < AR_MAX_ROUTING_LAYERS_COUNT; ii++ )
|
||||
{
|
||||
// de-allocate Dir matrix
|
||||
|
@ -183,13 +174,9 @@ void AR_MATRIX::SetCellOperation( AR_MATRIX::CELL_OP aLogicOp )
|
|||
{
|
||||
default:
|
||||
case WRITE_CELL: m_opWriteCell = &AR_MATRIX::SetCell; break;
|
||||
|
||||
case WRITE_OR_CELL: m_opWriteCell = &AR_MATRIX::OrCell; break;
|
||||
|
||||
case WRITE_XOR_CELL: m_opWriteCell = &AR_MATRIX::XorCell; break;
|
||||
|
||||
case WRITE_AND_CELL: m_opWriteCell = &AR_MATRIX::AndCell; break;
|
||||
|
||||
case WRITE_ADD_CELL: m_opWriteCell = &AR_MATRIX::AddCell; break;
|
||||
}
|
||||
}
|
||||
|
@ -281,116 +268,6 @@ void AR_MATRIX::SetDist( int aRow, int aCol, int aSide, DIST_CELL x )
|
|||
}
|
||||
|
||||
|
||||
// fetch direction cell
|
||||
int AR_MATRIX::GetDir( int aRow, int aCol, int aSide )
|
||||
{
|
||||
DIR_CELL* p;
|
||||
|
||||
p = m_DirSide[aSide];
|
||||
return (int) ( p[aRow * m_Ncols + aCol] );
|
||||
}
|
||||
|
||||
|
||||
// store direction cell
|
||||
void AR_MATRIX::SetDir( int aRow, int aCol, int aSide, int x )
|
||||
{
|
||||
DIR_CELL* p;
|
||||
|
||||
p = m_DirSide[aSide];
|
||||
p[aRow * m_Ncols + aCol] = (char) x;
|
||||
}
|
||||
|
||||
/* The tables of distances and keep out areas are established on the basis of a
|
||||
* 50 units grid size (the pitch between the cells is 50 units).
|
||||
* The actual distance could be computed by a scaling factor, but this is
|
||||
* not needed, we can use only reduced values
|
||||
*/
|
||||
|
||||
/* calculate approximate distance (manhattan distance)
|
||||
*/
|
||||
int AR_MATRIX::GetApxDist( int r1, int c1, int r2, int c2 )
|
||||
{
|
||||
int d1, d2; /* row and column deltas */
|
||||
|
||||
if( ( d1 = r1 - r2 ) < 0 ) /* get absolute row delta */
|
||||
d1 = -d1;
|
||||
|
||||
if( ( d2 = c1 - c2 ) < 0 ) /* get absolute column delta */
|
||||
d2 = -d2;
|
||||
|
||||
return ( d1 + d2 ) * 50;
|
||||
}
|
||||
|
||||
|
||||
/* distance to go thru a cell (en mils) */
|
||||
static const int dist[10][10] = { /* OT=Otherside, OR=Origin (source) cell */
|
||||
/*..........N, NE, E, SE, S, SW, W, NW, OT, OR */
|
||||
/* N */ { 50, 60, 35, 60, 99, 60, 35, 60, 12, 12 },
|
||||
/* NE */ { 60, 71, 60, 71, 60, 99, 60, 71, 23, 23 },
|
||||
/* E */ { 35, 60, 50, 60, 35, 60, 99, 60, 12, 12 },
|
||||
/* SE */ { 60, 71, 60, 71, 60, 71, 60, 99, 23, 23 },
|
||||
/* S */ { 99, 60, 35, 60, 50, 60, 35, 60, 12, 12 },
|
||||
/* SW */ { 60, 99, 60, 71, 60, 71, 60, 71, 23, 23 },
|
||||
/* W */ { 35, 60, 99, 60, 35, 60, 50, 60, 12, 12 },
|
||||
/* NW */ { 60, 71, 60, 99, 60, 71, 60, 71, 23, 23 },
|
||||
|
||||
/* OT */ { 12, 23, 12, 23, 12, 23, 12, 23, 99, 99 },
|
||||
/* OR */ { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }
|
||||
};
|
||||
|
||||
|
||||
/* penalty for extraneous holes and corners, scaled by sharpness of turn */
|
||||
static const int penalty[10][10] = { /* OT=Otherside, OR=Origin (source) cell */
|
||||
/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
|
||||
/* N */ { 0, 5, 10, 15, 20, 15, 10, 5, 50, 0 },
|
||||
/* NE */ { 5, 0, 5, 10, 15, 20, 15, 10, 50, 0 },
|
||||
/* E */ { 10, 5, 0, 5, 10, 15, 20, 15, 50, 0 },
|
||||
/* SE */ { 15, 10, 5, 0, 5, 10, 15, 20, 50, 0 },
|
||||
/* S */ { 20, 15, 10, 5, 0, 5, 10, 15, 50, 0 },
|
||||
/* SW */ { 15, 20, 15, 10, 5, 0, 5, 10, 50, 0 },
|
||||
/* W */ { 10, 15, 20, 15, 10, 5, 0, 5, 50, 0 },
|
||||
/* NW */ { 5, 10, 15, 20, 15, 10, 5, 0, 50, 0 },
|
||||
|
||||
/* OT */ { 50, 50, 50, 50, 50, 50, 50, 50, 100, 0 },
|
||||
/* OR */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
/* penalty pour directions preferencielles */
|
||||
#define PN 20
|
||||
static const int dir_penalty_TOP[10][10] = {
|
||||
/* OT=Otherside, OR=Origin (source) cell */
|
||||
/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
|
||||
/* N */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
|
||||
/* NE */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
|
||||
/* E */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
|
||||
/* SE */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
|
||||
/* S */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
|
||||
/* SW */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
|
||||
/* W */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
|
||||
/* NW */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
|
||||
|
||||
/* OT */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
|
||||
/* OR */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static int dir_penalty_BOTTOM[10][10] = {
|
||||
/* OT=Otherside, OR=Origin (source) cell */
|
||||
/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
|
||||
/* N */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
|
||||
/* NE */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
|
||||
/* E */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
|
||||
/* SE */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
|
||||
/* S */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
|
||||
/* SW */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
|
||||
/* W */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
|
||||
/* NW */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
|
||||
|
||||
/* OT */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
|
||||
/* OR */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
** x is the direction to enter the cell of interest.
|
||||
** y is the direction to exit the cell of interest.
|
||||
|
@ -401,44 +278,6 @@ static int dir_penalty_BOTTOM[10][10] = {
|
|||
*/
|
||||
|
||||
|
||||
/* calculate distance (with penalty) of a trace through a cell
|
||||
*/
|
||||
int AR_MATRIX::CalcDist( int x, int y, int z, int side )
|
||||
{
|
||||
int adjust, ldist;
|
||||
|
||||
adjust = 0; /* set if hole is encountered */
|
||||
|
||||
if( x == CELL_IS_EMPTY )
|
||||
x = 10;
|
||||
|
||||
if( y == CELL_IS_EMPTY )
|
||||
{
|
||||
y = 10;
|
||||
}
|
||||
else if( y == FROM_OTHERSIDE )
|
||||
{
|
||||
if( z == CELL_IS_EMPTY )
|
||||
z = 10;
|
||||
|
||||
adjust = penalty[x - 1][z - 1];
|
||||
}
|
||||
|
||||
ldist = dist[x - 1][y - 1] + penalty[x - 1][y - 1] + adjust;
|
||||
|
||||
if( m_RouteCount > 1 )
|
||||
{
|
||||
if( side == AR_SIDE_BOTTOM )
|
||||
ldist += dir_penalty_TOP[x - 1][y - 1];
|
||||
|
||||
if( side == AR_SIDE_TOP )
|
||||
ldist += dir_penalty_BOTTOM[x - 1][y - 1];
|
||||
}
|
||||
|
||||
return ldist * 10;
|
||||
}
|
||||
|
||||
|
||||
#define OP_CELL( layer, dy, dx ) \
|
||||
{ \
|
||||
if( layer == UNDEFINED_LAYER ) \
|
||||
|
@ -947,147 +786,6 @@ void AR_MATRIX::TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1, LSET a
|
|||
}
|
||||
|
||||
|
||||
/* Draws a line, if layer = -1 on all layers
|
||||
*/
|
||||
void AR_MATRIX::tracePcbLine(
|
||||
int x0, int y0, int x1, int y1, LAYER_NUM layer, int color, AR_MATRIX::CELL_OP op_logic )
|
||||
{
|
||||
int dx, dy, lim;
|
||||
int cumul, inc, il, delta;
|
||||
|
||||
SetCellOperation( op_logic );
|
||||
|
||||
if( x0 == x1 ) // Vertical.
|
||||
{
|
||||
if( y1 < y0 )
|
||||
std::swap( y0, y1 );
|
||||
|
||||
dy = y0 / m_GridRouting;
|
||||
lim = y1 / m_GridRouting;
|
||||
dx = x0 / m_GridRouting;
|
||||
|
||||
// Clipping limits of board.
|
||||
if( ( dx < 0 ) || ( dx >= m_Ncols ) )
|
||||
return;
|
||||
|
||||
if( dy < 0 )
|
||||
dy = 0;
|
||||
|
||||
if( lim >= m_Nrows )
|
||||
lim = m_Nrows - 1;
|
||||
|
||||
for( ; dy <= lim; dy++ )
|
||||
{
|
||||
OP_CELL( layer, dy, dx );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if( y0 == y1 ) // Horizontal
|
||||
{
|
||||
if( x1 < x0 )
|
||||
std::swap( x0, x1 );
|
||||
|
||||
dx = x0 / m_GridRouting;
|
||||
lim = x1 / m_GridRouting;
|
||||
dy = y0 / m_GridRouting;
|
||||
|
||||
// Clipping limits of board.
|
||||
if( ( dy < 0 ) || ( dy >= m_Nrows ) )
|
||||
return;
|
||||
|
||||
if( dx < 0 )
|
||||
dx = 0;
|
||||
|
||||
if( lim >= m_Ncols )
|
||||
lim = m_Ncols - 1;
|
||||
|
||||
for( ; dx <= lim; dx++ )
|
||||
{
|
||||
OP_CELL( layer, dy, dx );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Here is some perspective: using the algorithm LUCAS.
|
||||
if( abs( x1 - x0 ) >= abs( y1 - y0 ) ) // segment slightly inclined/
|
||||
{
|
||||
if( x1 < x0 )
|
||||
{
|
||||
std::swap( x1, x0 );
|
||||
std::swap( y1, y0 );
|
||||
}
|
||||
|
||||
dx = x0 / m_GridRouting;
|
||||
lim = x1 / m_GridRouting;
|
||||
dy = y0 / m_GridRouting;
|
||||
inc = 1;
|
||||
|
||||
if( y1 < y0 )
|
||||
inc = -1;
|
||||
|
||||
il = lim - dx;
|
||||
cumul = il / 2;
|
||||
delta = abs( y1 - y0 ) / m_GridRouting;
|
||||
|
||||
for( ; dx <= lim; )
|
||||
{
|
||||
if( ( dx >= 0 ) && ( dy >= 0 ) && ( dx < m_Ncols ) && ( dy < m_Nrows ) )
|
||||
{
|
||||
OP_CELL( layer, dy, dx );
|
||||
}
|
||||
|
||||
dx++;
|
||||
cumul += delta;
|
||||
|
||||
if( cumul > il )
|
||||
{
|
||||
cumul -= il;
|
||||
dy += inc;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( y1 < y0 )
|
||||
{
|
||||
std::swap( x1, x0 );
|
||||
std::swap( y1, y0 );
|
||||
}
|
||||
|
||||
dy = y0 / m_GridRouting;
|
||||
lim = y1 / m_GridRouting;
|
||||
dx = x0 / m_GridRouting;
|
||||
inc = 1;
|
||||
|
||||
if( x1 < x0 )
|
||||
inc = -1;
|
||||
|
||||
il = lim - dy;
|
||||
cumul = il / 2;
|
||||
delta = abs( x1 - x0 ) / m_GridRouting;
|
||||
|
||||
for( ; dy <= lim; )
|
||||
{
|
||||
if( ( dx >= 0 ) && ( dy >= 0 ) && ( dx < m_Ncols ) && ( dy < m_Nrows ) )
|
||||
{
|
||||
OP_CELL( layer, dy, dx );
|
||||
}
|
||||
|
||||
dy++;
|
||||
cumul += delta;
|
||||
|
||||
if( cumul > il )
|
||||
{
|
||||
cumul -= il;
|
||||
dx += inc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AR_MATRIX::TraceSegmentPcb(
|
||||
DRAWSEGMENT* pt_segm, int color, int marge, AR_MATRIX::CELL_OP op_logic )
|
||||
{
|
||||
|
@ -1101,69 +799,24 @@ void AR_MATRIX::TraceSegmentPcb(
|
|||
|
||||
//printf("traceSegm %d %d %d %d\n", ux0, uy0, ux1, uy1);
|
||||
|
||||
LAYER_NUM layer = pt_segm->GetLayer();
|
||||
|
||||
//if( color == VIA_IMPOSSIBLE )
|
||||
layer = UNDEFINED_LAYER;
|
||||
|
||||
LAYER_NUM layer = UNDEFINED_LAYER; // Draw on all layers
|
||||
|
||||
switch( pt_segm->GetShape() )
|
||||
{
|
||||
// The segment is here a straight line or a circle or an arc.:
|
||||
case S_CIRCLE: traceCircle( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); break;
|
||||
case S_CIRCLE:
|
||||
traceCircle( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
traceArc( ux0, uy0, ux1, uy1, pt_segm->GetAngle(), half_width, layer, color, op_logic );
|
||||
break;
|
||||
|
||||
// The segment is here a line segment.
|
||||
default: drawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AR_MATRIX::TraceSegmentPcb( TRACK* aTrack, int color, int marge, AR_MATRIX::CELL_OP op_logic )
|
||||
{
|
||||
int half_width = ( aTrack->GetWidth() / 2 ) + marge;
|
||||
|
||||
// Test if VIA (filled circle need to be drawn)
|
||||
if( aTrack->Type() == PCB_VIA_T )
|
||||
{
|
||||
LSET layer_mask;
|
||||
|
||||
if( aTrack->IsOnLayer( m_routeLayerBottom ) )
|
||||
layer_mask.set( m_routeLayerBottom );
|
||||
|
||||
if( aTrack->IsOnLayer( m_routeLayerTop ) )
|
||||
{
|
||||
if( !layer_mask.any() )
|
||||
layer_mask = LSET( m_routeLayerTop );
|
||||
else
|
||||
layer_mask.set();
|
||||
}
|
||||
|
||||
if( color == VIA_IMPOSSIBLE )
|
||||
layer_mask.set();
|
||||
|
||||
if( layer_mask.any() )
|
||||
traceFilledCircle( aTrack->GetStart().x, aTrack->GetStart().y, half_width, layer_mask,
|
||||
color, op_logic );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the bounding rectangle of the segment
|
||||
int ux0 = aTrack->GetStart().x - GetBrdCoordOrigin().x;
|
||||
int uy0 = aTrack->GetStart().y - GetBrdCoordOrigin().y;
|
||||
int ux1 = aTrack->GetEnd().x - GetBrdCoordOrigin().x;
|
||||
int uy1 = aTrack->GetEnd().y - GetBrdCoordOrigin().y;
|
||||
|
||||
// Ordinary track
|
||||
PCB_LAYER_ID layer = aTrack->GetLayer();
|
||||
|
||||
if( color == VIA_IMPOSSIBLE )
|
||||
layer = UNDEFINED_LAYER;
|
||||
|
||||
case S_SEGMENT:
|
||||
drawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@ public:
|
|||
// distance to cells
|
||||
DIR_CELL* m_DirSide[AR_MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
|
||||
// pointers back to source
|
||||
bool m_InitMatrixDone;
|
||||
int m_RoutingLayersCount; // Number of layers for autorouting (0 or 1)
|
||||
int m_GridRouting; // Size of grid for autoplace/autoroute
|
||||
EDA_RECT m_BrdBox; // Actual board bounding box
|
||||
|
@ -133,18 +132,8 @@ public:
|
|||
void AddCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell );
|
||||
DIST_CELL GetDist( int aRow, int aCol, int aSide );
|
||||
void SetDist( int aRow, int aCol, int aSide, DIST_CELL );
|
||||
int GetDir( int aRow, int aCol, int aSide );
|
||||
void SetDir( int aRow, int aCol, int aSide, int aDir );
|
||||
|
||||
// calculate distance (with penalty) of a trace through a cell
|
||||
int CalcDist( int x, int y, int z, int side );
|
||||
|
||||
// calculate approximate distance (manhattan distance)
|
||||
int GetApxDist( int r1, int c1, int r2, int c2 );
|
||||
|
||||
|
||||
void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int color, int marge, AR_MATRIX::CELL_OP op_logic );
|
||||
void TraceSegmentPcb( TRACK* aTrack, int color, int marge, AR_MATRIX::CELL_OP op_logic );
|
||||
void CreateKeepOutRectangle(
|
||||
int ux0, int uy0, int ux1, int uy1, int marge, int aKeepOut, LSET aLayerMask );
|
||||
void PlacePad( D_PAD* aPad, int color, int marge, AR_MATRIX::CELL_OP op_logic );
|
||||
|
@ -154,7 +143,6 @@ public:
|
|||
AR_MATRIX::CELL_OP op_logic );
|
||||
|
||||
private:
|
||||
|
||||
void drawSegmentQcq( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer, int color,
|
||||
CELL_OP op_logic );
|
||||
|
||||
|
@ -164,8 +152,6 @@ private:
|
|||
int cx, int cy, int radius, LSET aLayerMask, int color, AR_MATRIX::CELL_OP op_logic );
|
||||
void traceArc( int ux0, int uy0, int ux1, int uy1, double ArcAngle, int lg, LAYER_NUM layer,
|
||||
int color, AR_MATRIX::CELL_OP op_logic );
|
||||
void tracePcbLine( int x0, int y0, int x1, int y1, LAYER_NUM layer, int color,
|
||||
AR_MATRIX::CELL_OP op_logic );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -368,6 +368,18 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB
|
|||
TransformRingToPolygon( aCornerBuffer, GetCenter(), GetRadius(), aError, width );
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
GetRectCorners( &pts );
|
||||
|
||||
aCornerBuffer.NewOutline();
|
||||
|
||||
for( const wxPoint& pt : pts )
|
||||
aCornerBuffer.Append( pt );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
TransformArcToPolygon( aCornerBuffer, GetCenter(), GetArcStart(), m_Angle, aError, width );
|
||||
break;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <macros.h>
|
||||
#include <gr_basic.h>
|
||||
#include <bezier_curves.h>
|
||||
#include <pcb_screen.h>
|
||||
|
@ -87,9 +86,14 @@ double DRAWSEGMENT::GetLength() const
|
|||
|
||||
break;
|
||||
|
||||
default:
|
||||
case S_SEGMENT:
|
||||
length = GetLineLength( GetStart(), GetEnd() );
|
||||
break;
|
||||
|
||||
default:
|
||||
wxASSERT_MSG( false, "DRAWSEGMENT::GetLength not implemented for shape"
|
||||
+ ShowShape( GetShape() ) );
|
||||
break;
|
||||
}
|
||||
|
||||
return length;
|
||||
|
@ -116,10 +120,8 @@ void DRAWSEGMENT::Move( const wxPoint& aMoveVector )
|
|||
m_BezierC1 += aMoveVector;
|
||||
m_BezierC2 += aMoveVector;
|
||||
|
||||
for( unsigned int ii = 0; ii < m_BezierPoints.size(); ii++ )
|
||||
{
|
||||
m_BezierPoints[ii] += aMoveVector;
|
||||
}
|
||||
for( wxPoint& pt : m_BezierPoints)
|
||||
pt += aMoveVector;
|
||||
|
||||
break;
|
||||
|
||||
|
@ -136,6 +138,7 @@ void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, double aAngle )
|
|||
case S_ARC:
|
||||
case S_SEGMENT:
|
||||
case S_CIRCLE:
|
||||
case S_RECT:
|
||||
// these can all be done by just rotating the start and end points
|
||||
RotatePoint( &m_Start, aRotCentre, aAngle);
|
||||
RotatePoint( &m_End, aRotCentre, aAngle);
|
||||
|
@ -151,13 +154,11 @@ void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, double aAngle )
|
|||
RotatePoint( &m_BezierC1, aRotCentre, aAngle);
|
||||
RotatePoint( &m_BezierC2, aRotCentre, aAngle);
|
||||
|
||||
for( unsigned int ii = 0; ii < m_BezierPoints.size(); ii++ )
|
||||
{
|
||||
RotatePoint( &m_BezierPoints[ii], aRotCentre, aAngle);
|
||||
}
|
||||
for( wxPoint& pt : m_BezierPoints )
|
||||
RotatePoint( &pt, aRotCentre, aAngle);
|
||||
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
default:
|
||||
// un-handled edge transform
|
||||
wxASSERT_MSG( false, wxT( "DRAWSEGMENT::Rotate not implemented for "
|
||||
|
@ -385,7 +386,17 @@ void DRAWSEGMENT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL
|
|||
aList.emplace_back( _( "Points" ), msg, DARKGREEN );
|
||||
break;
|
||||
|
||||
default:
|
||||
case S_RECT:
|
||||
aList.emplace_back( shape, _( "Rectangle" ), RED );
|
||||
|
||||
msg = MessageTextFromValue( units, std::abs( m_End.x - m_Start.x ) );
|
||||
aList.emplace_back( _( "Width" ), msg, DARKGREEN );
|
||||
|
||||
msg = MessageTextFromValue( units, std::abs( m_End.y - m_Start.y ) );
|
||||
aList.emplace_back( _( "Height" ), msg, DARKGREEN );
|
||||
break;
|
||||
|
||||
case S_SEGMENT:
|
||||
{
|
||||
aList.emplace_back( shape, _( "Segment" ), RED );
|
||||
|
||||
|
@ -398,6 +409,11 @@ void DRAWSEGMENT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL
|
|||
msg.Printf( wxT( "%.1f" ), deg );
|
||||
aList.emplace_back( _( "Angle" ), msg, DARKGREEN );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
aList.emplace_back( shape, _( "Unrecognized" ), RED );
|
||||
break;
|
||||
}
|
||||
|
||||
if( m_Shape == S_POLYGON )
|
||||
|
@ -436,6 +452,18 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const
|
|||
|
||||
switch( m_Shape )
|
||||
{
|
||||
case S_RECT:
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
GetRectCorners( &pts );
|
||||
|
||||
bbox = EDA_RECT(); // re-init for merging
|
||||
|
||||
for( wxPoint& pt : pts )
|
||||
bbox.Merge( pt );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_SEGMENT:
|
||||
bbox.SetEnd( m_End );
|
||||
break;
|
||||
|
@ -452,9 +480,8 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const
|
|||
if( m_Poly.IsEmpty() )
|
||||
break;
|
||||
{
|
||||
wxPoint p_end;
|
||||
MODULE* module = GetParentModule();
|
||||
bool first = true;
|
||||
bbox = EDA_RECT(); // re-init for merging
|
||||
|
||||
for( auto iter = m_Poly.CIterate(); iter; iter++ )
|
||||
{
|
||||
|
@ -466,31 +493,12 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const
|
|||
pt += module->GetPosition();
|
||||
}
|
||||
|
||||
|
||||
if( first )
|
||||
{
|
||||
p_end = pt;
|
||||
bbox.SetX( pt.x );
|
||||
bbox.SetY( pt.y );
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
bbox.SetX( std::min( bbox.GetX(), pt.x ) );
|
||||
bbox.SetY( std::min( bbox.GetY(), pt.y ) );
|
||||
|
||||
p_end.x = std::max( p_end.x, pt.x );
|
||||
p_end.y = std::max( p_end.y, pt.y );
|
||||
bbox.Merge( pt );
|
||||
}
|
||||
}
|
||||
|
||||
bbox.SetEnd( p_end );
|
||||
break;
|
||||
}
|
||||
|
||||
case S_CURVE:
|
||||
|
||||
bbox.Merge( m_BezierC1 );
|
||||
bbox.Merge( m_BezierC2 );
|
||||
bbox.Merge( m_End );
|
||||
|
@ -572,6 +580,21 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
|
|||
return true;
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
GetRectCorners( &pts );
|
||||
|
||||
if( TestSegmentHit( aPosition, pts[0], pts[1], maxdist )
|
||||
|| TestSegmentHit( aPosition, pts[1], pts[2], maxdist )
|
||||
|| TestSegmentHit( aPosition, pts[2], pts[3], maxdist )
|
||||
|| TestSegmentHit( aPosition, pts[3], pts[0], maxdist ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
{
|
||||
if( !IsPolygonFilled() )
|
||||
|
@ -644,6 +667,26 @@ bool DRAWSEGMENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy
|
|||
}
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
if( aContained )
|
||||
{
|
||||
return arect.Contains( bb );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
GetRectCorners( &pts );
|
||||
|
||||
// Account for the width of the lines
|
||||
arect.Inflate( GetWidth() / 2 );
|
||||
return ( arect.Intersects( pts[0], pts[1] )
|
||||
|| arect.Intersects( pts[1], pts[2] )
|
||||
|| arect.Intersects( pts[2], pts[3] )
|
||||
|| arect.Intersects( pts[3], pts[0] ) );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case S_SEGMENT:
|
||||
if( aContained )
|
||||
{
|
||||
|
@ -734,9 +777,8 @@ bool DRAWSEGMENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy
|
|||
|
||||
wxString DRAWSEGMENT::GetSelectMenuText( EDA_UNITS aUnits ) const
|
||||
{
|
||||
return wxString::Format( _( "Pcb Graphic %s, length %s on %s" ),
|
||||
return wxString::Format( _( "Pcb Graphic %s on %s" ),
|
||||
ShowShape( m_Shape ),
|
||||
MessageTextFromValue( aUnits, GetLength() ),
|
||||
GetLayerName() );
|
||||
}
|
||||
|
||||
|
@ -769,6 +811,40 @@ const BOX2I DRAWSEGMENT::ViewBBox() const
|
|||
}
|
||||
|
||||
|
||||
void DRAWSEGMENT::GetRectCorners( std::vector<wxPoint>* pts ) const
|
||||
{
|
||||
MODULE* module = GetParentModule();
|
||||
wxPoint topLeft = GetStart();
|
||||
wxPoint botRight = GetEnd();
|
||||
|
||||
// Un-rotate rect topLeft and botRight
|
||||
if( module && KiROUND( module->GetOrientation() ) % 900 != 0 )
|
||||
{
|
||||
topLeft -= module->GetPosition();
|
||||
RotatePoint( &topLeft, -module->GetOrientation() );
|
||||
|
||||
botRight -= module->GetPosition();
|
||||
RotatePoint( &botRight, -module->GetOrientation() );
|
||||
}
|
||||
|
||||
// Set up the un-rotated 4 corners
|
||||
pts->emplace_back( topLeft );
|
||||
pts->emplace_back( botRight.x, topLeft.y );
|
||||
pts->emplace_back( botRight );
|
||||
pts->emplace_back( topLeft.x, botRight.y );
|
||||
|
||||
// Now re-rotate the 4 corners to get a diamond
|
||||
if( module && KiROUND( module->GetOrientation() ) % 900 != 0 )
|
||||
{
|
||||
for( wxPoint& pt : *pts )
|
||||
{
|
||||
RotatePoint( &pt,module->GetOrientation() );
|
||||
pt += module->GetPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DRAWSEGMENT::computeArcBBox( EDA_RECT& aBBox ) const
|
||||
{
|
||||
// Do not include the center, which is not necessarily
|
||||
|
@ -816,21 +892,10 @@ void DRAWSEGMENT::computeArcBBox( EDA_RECT& aBBox ) const
|
|||
{
|
||||
switch( quarter )
|
||||
{
|
||||
case 0:
|
||||
aBBox.Merge( wxPoint( m_Start.x, m_Start.y + radius ) ); // down
|
||||
break;
|
||||
|
||||
case 1:
|
||||
aBBox.Merge( wxPoint( m_Start.x - radius, m_Start.y ) ); // left
|
||||
break;
|
||||
|
||||
case 2:
|
||||
aBBox.Merge( wxPoint( m_Start.x, m_Start.y - radius ) ); // up
|
||||
break;
|
||||
|
||||
case 3:
|
||||
aBBox.Merge( wxPoint( m_Start.x + radius, m_Start.y ) ); // right
|
||||
break;
|
||||
case 0: aBBox.Merge( wxPoint( m_Start.x, m_Start.y + radius ) ); break; // down
|
||||
case 1: aBBox.Merge( wxPoint( m_Start.x - radius, m_Start.y ) ); break; // left
|
||||
case 2: aBBox.Merge( wxPoint( m_Start.x, m_Start.y - radius ) ); break; // up
|
||||
case 3: aBBox.Merge( wxPoint( m_Start.x + radius, m_Start.y ) ); break; // right
|
||||
}
|
||||
|
||||
if( directionCW )
|
||||
|
@ -849,11 +914,9 @@ void DRAWSEGMENT::SetPolyPoints( const std::vector<wxPoint>& aPoints )
|
|||
m_Poly.RemoveAllContours();
|
||||
m_Poly.NewOutline();
|
||||
|
||||
for ( auto p : aPoints )
|
||||
{
|
||||
for ( const wxPoint& p : aPoints )
|
||||
m_Poly.Append( p.x, p.y );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const std::vector<wxPoint> DRAWSEGMENT::BuildPolyPointsList() const
|
||||
|
@ -865,11 +928,9 @@ const std::vector<wxPoint> DRAWSEGMENT::BuildPolyPointsList() const
|
|||
if( m_Poly.COutline( 0 ).PointCount() )
|
||||
{
|
||||
for ( auto iter = m_Poly.CIterate(); iter; iter++ )
|
||||
{
|
||||
rv.emplace_back( iter->x, iter->y );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -150,6 +150,7 @@ public:
|
|||
const wxPoint& GetArcStart() const { return m_End; }
|
||||
const wxPoint GetArcEnd() const;
|
||||
const wxPoint GetArcMid() const;
|
||||
void GetRectCorners( std::vector<wxPoint>* pts ) const;
|
||||
|
||||
/**
|
||||
* function GetArcAngleStart()
|
||||
|
@ -181,6 +182,11 @@ public:
|
|||
*/
|
||||
void SetCenter( const wxPoint& aCenterPoint ) { m_Start = aCenterPoint; }
|
||||
|
||||
const wxPoint GetFocusPosition() const override
|
||||
{
|
||||
return GetCenter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetParentModule
|
||||
* returns a pointer to the parent module, or NULL if DRAWSEGMENT does not
|
||||
|
|
|
@ -30,14 +30,10 @@
|
|||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <gr_basic.h>
|
||||
#include <trigo.h>
|
||||
#include <pcb_screen.h>
|
||||
#include <confirm.h>
|
||||
#include <kicad_string.h>
|
||||
#include <richio.h>
|
||||
#include <macros.h>
|
||||
#include <math_for_graphics.h>
|
||||
#include <pcb_base_frame.h>
|
||||
#include <msgpanel.h>
|
||||
#include <base_units.h>
|
||||
|
@ -46,15 +42,12 @@
|
|||
#include <pgm_base.h>
|
||||
#include <settings/color_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
#include <class_edge_mod.h>
|
||||
|
||||
#include <view/view.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
EDGE_MODULE::EDGE_MODULE( MODULE* parent, STROKE_T aShape ) :
|
||||
DRAWSEGMENT( parent, PCB_MODULE_EDGE_T )
|
||||
|
|
|
@ -207,6 +207,7 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
|
||||
switch( graphic->GetShape() )
|
||||
{
|
||||
case S_RECT:
|
||||
case S_SEGMENT:
|
||||
{
|
||||
if( graphic->GetStart().x < xmin.x )
|
||||
|
@ -326,6 +327,16 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
{
|
||||
TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(), aTolerance );
|
||||
}
|
||||
else if( graphic->GetShape() == S_RECT )
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
graphic->GetRectCorners( &pts );
|
||||
|
||||
aPolygons.NewOutline();
|
||||
|
||||
for( const wxPoint& pt : pts )
|
||||
aPolygons.Append( pt );
|
||||
}
|
||||
else if( graphic->GetShape() == S_POLYGON )
|
||||
{
|
||||
MODULE* module = graphic->GetParentModule(); // NULL for items not in footprints
|
||||
|
@ -542,6 +553,14 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
aPolygons.Append( nextPt, -1, hole );
|
||||
}
|
||||
}
|
||||
else if( graphic->GetShape() == S_RECT )
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
graphic->GetRectCorners( &pts );
|
||||
|
||||
for( const wxPoint& pt : pts )
|
||||
aPolygons.Append( pt, -1, hole );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Polygon start point. Arbitrarily chosen end of the
|
||||
|
|
|
@ -180,6 +180,10 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataToWindow()
|
|||
m_sizerLeft->Show( false );
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
SetTitle( _( "Rectangle Properties" ) );
|
||||
break;
|
||||
|
||||
case S_SEGMENT:
|
||||
if( m_item->GetStart().x == m_item->GetEnd().x )
|
||||
m_flipStartEnd = m_item->GetStart().y > m_item->GetEnd().y;
|
||||
|
|
|
@ -941,6 +941,18 @@ void DRC::testCopperDrawItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem )
|
|||
itemShape.emplace_back( SEG( drawItem->GetStart(), drawItem->GetEnd() ) );
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
drawItem->GetRectCorners( &pts );
|
||||
|
||||
itemShape.emplace_back( SEG( pts[0], pts[1] ) );
|
||||
itemShape.emplace_back( SEG( pts[1], pts[2] ) );
|
||||
itemShape.emplace_back( SEG( pts[2], pts[3] ) );
|
||||
itemShape.emplace_back( SEG( pts[3], pts[0] ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CIRCLE:
|
||||
{
|
||||
// SHAPE_CIRCLE has no ConvertToPolyline() method, so use a 360.0 SHAPE_ARC
|
||||
|
|
|
@ -1259,6 +1259,31 @@ static void FootprintWriteShape( FILE* aFile, MODULE* module, const wxString& aS
|
|||
-PtEdge->m_End0.y / SCALE_FACTOR );
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
{
|
||||
fprintf( aFile, "LINE %g %g %g %g\n",
|
||||
PtEdge->m_Start0.x / SCALE_FACTOR,
|
||||
-PtEdge->m_Start0.y / SCALE_FACTOR,
|
||||
PtEdge->m_End0.x / SCALE_FACTOR,
|
||||
-PtEdge->m_Start0.y / SCALE_FACTOR );
|
||||
fprintf( aFile, "LINE %g %g %g %g\n",
|
||||
PtEdge->m_End0.x / SCALE_FACTOR,
|
||||
-PtEdge->m_Start0.y / SCALE_FACTOR,
|
||||
PtEdge->m_End0.x / SCALE_FACTOR,
|
||||
-PtEdge->m_End0.y / SCALE_FACTOR );
|
||||
fprintf( aFile, "LINE %g %g %g %g\n",
|
||||
PtEdge->m_End0.x / SCALE_FACTOR,
|
||||
-PtEdge->m_End0.y / SCALE_FACTOR,
|
||||
PtEdge->m_Start0.x / SCALE_FACTOR,
|
||||
-PtEdge->m_End0.y / SCALE_FACTOR );
|
||||
fprintf( aFile, "LINE %g %g %g %g\n",
|
||||
PtEdge->m_Start0.x / SCALE_FACTOR,
|
||||
-PtEdge->m_End0.y / SCALE_FACTOR,
|
||||
PtEdge->m_Start0.x / SCALE_FACTOR,
|
||||
-PtEdge->m_Start0.y / SCALE_FACTOR );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CIRCLE:
|
||||
{
|
||||
int radius = KiROUND( GetLineLength( PtEdge->m_End0,
|
||||
|
|
|
@ -102,6 +102,30 @@ static void idf_export_outline( BOARD* aPcb, IDF3_BOARD& aIDFBoard )
|
|||
}
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
{
|
||||
if( ( graphic->GetStart().x == graphic->GetEnd().x )
|
||||
&& ( graphic->GetStart().y == graphic->GetEnd().y ) )
|
||||
break;
|
||||
|
||||
double top = graphic->GetStart().y * scale + offY;
|
||||
double left = graphic->GetStart().x * scale + offX;
|
||||
double bottom = graphic->GetEnd().y * scale + offY;
|
||||
double right = graphic->GetEnd().x * scale + offX;
|
||||
|
||||
IDF_POINT corners[4];
|
||||
corners[0] = IDF_POINT( left, top );
|
||||
corners[1] = IDF_POINT( right, top );
|
||||
corners[2] = IDF_POINT( right, bottom );
|
||||
corners[3] = IDF_POINT( left, bottom );
|
||||
|
||||
lines.push_back( new IDF_SEGMENT( corners[0], corners[1] ) );
|
||||
lines.push_back( new IDF_SEGMENT( corners[1], corners[2] ) );
|
||||
lines.push_back( new IDF_SEGMENT( corners[2], corners[3] ) );
|
||||
lines.push_back( new IDF_SEGMENT( corners[3], corners[0] ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
{
|
||||
if( ( graphic->GetCenter().x == graphic->GetArcStart().x )
|
||||
|
|
|
@ -750,9 +750,19 @@ static void export_vrml_drawsegment( MODEL_VRML& aModel, DRAWSEGMENT* drawseg )
|
|||
export_vrml_polygon( aModel, layer, drawseg, 0.0, wxPoint( 0, 0 ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
case S_SEGMENT:
|
||||
export_vrml_line( aModel, layer, x, y, xf, yf, w );
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
export_vrml_line( aModel, layer, x, y, xf, y, w );
|
||||
export_vrml_line( aModel, layer, xf, y, xf, yf, w );
|
||||
export_vrml_line( aModel, layer, xf, yf, x, yf, w );
|
||||
export_vrml_line( aModel, layer, x, yf, x, y, w );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <kicad_string.h>
|
||||
#include <common.h>
|
||||
#include <build_version.h> // LEGACY_BOARD_FILE_VERSION
|
||||
#include <macros.h>
|
||||
|
@ -39,7 +38,6 @@
|
|||
#include <class_drawsegment.h>
|
||||
#include <class_pcb_target.h>
|
||||
#include <class_edge_mod.h>
|
||||
#include <pcb_plot_params.h>
|
||||
#include <zones.h>
|
||||
#include <kicad_plugin.h>
|
||||
#include <pcb_parser.h>
|
||||
|
@ -888,6 +886,12 @@ void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const
|
|||
|
||||
break;
|
||||
|
||||
case S_RECT: // Rectangle
|
||||
m_out->Print( aNestLevel, "(gr_rect (start %s) (end %s)",
|
||||
FormatInternalUnits( aSegment->GetStart() ).c_str(),
|
||||
FormatInternalUnits( aSegment->GetEnd() ).c_str() );
|
||||
break;
|
||||
|
||||
case S_CIRCLE: // Circle
|
||||
m_out->Print( aNestLevel, "(gr_circle (center %s) (end %s)",
|
||||
FormatInternalUnits( aSegment->GetStart() ).c_str(),
|
||||
|
@ -961,6 +965,12 @@ void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const
|
|||
FormatInternalUnits( aModuleDrawing->GetEnd0() ).c_str() );
|
||||
break;
|
||||
|
||||
case S_RECT: // Rectangle
|
||||
m_out->Print( aNestLevel, "(fp_rect (start %s) (end %s)",
|
||||
FormatInternalUnits( aModuleDrawing->GetStart0() ).c_str(),
|
||||
FormatInternalUnits( aModuleDrawing->GetEnd0() ).c_str() );
|
||||
break;
|
||||
|
||||
case S_CIRCLE: // Circle
|
||||
m_out->Print( aNestLevel, "(fp_circle (center %s) (end %s)",
|
||||
FormatInternalUnits( aModuleDrawing->GetStart0() ).c_str(),
|
||||
|
|
|
@ -68,7 +68,8 @@ class TEXTE_PCB;
|
|||
//#define SEXPR_BOARD_FILE_VERSION 20200104 // pad property for fabrication
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20200119 // arcs in tracks
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20200512 // page -> paper
|
||||
#define SEXPR_BOARD_FILE_VERSION 20200518 // save hole_to_hole_min
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20200518 // save hole_to_hole_min
|
||||
#define SEXPR_BOARD_FILE_VERSION 20200614 // Add support for fp_rects and gr_rects
|
||||
|
||||
#define CTL_STD_LAYER_NAMES (1 << 0) ///< Use English Standard layer names
|
||||
#define CTL_OMIT_NETS (1 << 1) ///< Omit pads net names (useless in library)
|
||||
|
|
|
@ -915,8 +915,15 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
|
|||
break;
|
||||
|
||||
case S_RECT:
|
||||
wxASSERT_MSG( false, "Not tested yet" );
|
||||
m_gal->DrawRectangle( start, end );
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
aSegment->GetRectCorners( &pts );
|
||||
|
||||
m_gal->DrawSegment( pts[0], pts[1], thickness );
|
||||
m_gal->DrawSegment( pts[1], pts[2], thickness );
|
||||
m_gal->DrawSegment( pts[2], pts[3], thickness );
|
||||
m_gal->DrawSegment( pts[3], pts[0], thickness );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
|
|
|
@ -582,6 +582,7 @@ BOARD* PCB_PARSER::parseBOARD_unchecked()
|
|||
case T_gr_arc:
|
||||
case T_gr_circle:
|
||||
case T_gr_curve:
|
||||
case T_gr_rect:
|
||||
case T_gr_line:
|
||||
case T_gr_poly:
|
||||
m_board->Add( parseDRAWSEGMENT(), ADD_MODE::APPEND );
|
||||
|
@ -1942,7 +1943,7 @@ void PCB_PARSER::parseNETCLASS()
|
|||
DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT( bool aAllowCirclesZeroWidth )
|
||||
{
|
||||
wxCHECK_MSG( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
|
||||
CurTok() == T_gr_line || CurTok() == T_gr_poly, NULL,
|
||||
CurTok() == T_gr_rect || CurTok() == T_gr_line || CurTok() == T_gr_poly, NULL,
|
||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DRAWSEGMENT." ) );
|
||||
|
||||
T token;
|
||||
|
@ -2017,6 +2018,30 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT( bool aAllowCirclesZeroWidth )
|
|||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_gr_rect:
|
||||
segment->SetShape( S_RECT );
|
||||
NeedLEFT();
|
||||
token = NextTok();
|
||||
|
||||
if( token != T_start )
|
||||
Expecting( T_start );
|
||||
|
||||
pt.x = parseBoardUnits( "X coordinate" );
|
||||
pt.y = parseBoardUnits( "Y coordinate" );
|
||||
segment->SetStart( pt );
|
||||
NeedRIGHT();
|
||||
NeedLEFT();
|
||||
token = NextTok();
|
||||
|
||||
if( token != T_end )
|
||||
Expecting( T_end );
|
||||
|
||||
pt.x = parseBoardUnits( "X coordinate" );
|
||||
pt.y = parseBoardUnits( "Y coordinate" );
|
||||
segment->SetEnd( pt );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_gr_line:
|
||||
// Default DRAWSEGMENT type is S_SEGMENT.
|
||||
NeedLEFT();
|
||||
|
@ -2061,7 +2086,7 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT( bool aAllowCirclesZeroWidth )
|
|||
break;
|
||||
|
||||
default:
|
||||
Expecting( "gr_arc, gr_circle, gr_curve, gr_line, or gr_poly" );
|
||||
Expecting( "gr_arc, gr_circle, gr_curve, gr_line, gr_poly, or gp_rect" );
|
||||
}
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
|
@ -2107,7 +2132,9 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT( bool aAllowCirclesZeroWidth )
|
|||
// However in custom pad shapes, zero-line width is allowed for filled circles
|
||||
if( segment->GetShape() != S_POLYGON && segment->GetWidth() == 0 &&
|
||||
!( segment->GetShape() == S_CIRCLE && aAllowCirclesZeroWidth ) )
|
||||
{
|
||||
segment->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
|
||||
}
|
||||
|
||||
return segment.release();
|
||||
}
|
||||
|
@ -2588,6 +2615,7 @@ MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments )
|
|||
|
||||
case T_fp_circle:
|
||||
case T_fp_curve:
|
||||
case T_fp_rect:
|
||||
case T_fp_line:
|
||||
case T_fp_poly:
|
||||
{
|
||||
|
@ -2628,7 +2656,7 @@ MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments )
|
|||
"autoplace_cost90, autoplace_cost180, solder_mask_margin, "
|
||||
"solder_paste_margin, solder_paste_ratio, clearance, "
|
||||
"zone_connect, thermal_width, thermal_gap, attr, fp_text, "
|
||||
"fp_arc, fp_circle, fp_curve, fp_line, fp_poly, pad, "
|
||||
"fp_arc, fp_circle, fp_curve, fp_line, fp_poly, fp_rect, pad, "
|
||||
"zone, or model" );
|
||||
}
|
||||
}
|
||||
|
@ -2738,7 +2766,7 @@ TEXTE_MODULE* PCB_PARSER::parseTEXTE_MODULE()
|
|||
EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE()
|
||||
{
|
||||
wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
|
||||
CurTok() == T_fp_line || CurTok() == T_fp_poly, NULL,
|
||||
CurTok() == T_fp_rect || CurTok() == T_fp_line || CurTok() == T_fp_poly, NULL,
|
||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDGE_MODULE." ) );
|
||||
|
||||
wxPoint pt;
|
||||
|
@ -2821,6 +2849,31 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE()
|
|||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_fp_rect:
|
||||
segment->SetShape( S_RECT );
|
||||
NeedLEFT();
|
||||
token = NextTok();
|
||||
|
||||
if( token != T_start )
|
||||
Expecting( T_start );
|
||||
|
||||
pt.x = parseBoardUnits( "X coordinate" );
|
||||
pt.y = parseBoardUnits( "Y coordinate" );
|
||||
segment->SetStart0( pt );
|
||||
|
||||
NeedRIGHT();
|
||||
NeedLEFT();
|
||||
token = NextTok();
|
||||
|
||||
if( token != T_end )
|
||||
Expecting( T_end );
|
||||
|
||||
pt.x = parseBoardUnits( "X coordinate" );
|
||||
pt.y = parseBoardUnits( "Y coordinate" );
|
||||
segment->SetEnd0( pt );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_fp_line:
|
||||
// Default DRAWSEGMENT type is S_SEGMENT.
|
||||
NeedLEFT();
|
||||
|
@ -2865,7 +2918,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE()
|
|||
break;
|
||||
|
||||
default:
|
||||
Expecting( "fp_arc, fp_circle, fp_curve, fp_line, or fp_poly" );
|
||||
Expecting( "fp_arc, fp_circle, fp_curve, fp_line, fp_poly, or fp_rect" );
|
||||
}
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
|
|
|
@ -529,6 +529,18 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( EDGE_MODULE* aEdge )
|
|||
m_plotter->ThickSegment( pos, end, thickness, GetPlotMode(), &gbr_metadata );
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
aEdge->GetRectCorners( &pts );
|
||||
|
||||
m_plotter->ThickSegment( pts[0], pts[1], thickness, GetPlotMode(), &gbr_metadata );
|
||||
m_plotter->ThickSegment( pts[1], pts[2], thickness, GetPlotMode(), &gbr_metadata );
|
||||
m_plotter->ThickSegment( pts[2], pts[3], thickness, GetPlotMode(), &gbr_metadata );
|
||||
m_plotter->ThickSegment( pts[3], pts[0], thickness, GetPlotMode(), &gbr_metadata );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CIRCLE:
|
||||
radius = KiROUND( GetLineLength( end, pos ) );
|
||||
m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
|
||||
|
|
|
@ -985,6 +985,18 @@ bool PNS_KICAD_IFACE_BASE::syncGraphicalItem( PNS::NODE* aWorld, DRAWSEGMENT* aI
|
|||
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
{
|
||||
std::vector<wxPoint> pts;
|
||||
aItem->GetRectCorners( &pts );
|
||||
|
||||
segs.push_back( new SHAPE_SEGMENT( pts[0], pts[1], aItem->GetWidth() ) );
|
||||
segs.push_back( new SHAPE_SEGMENT( pts[1], pts[2], aItem->GetWidth() ) );
|
||||
segs.push_back( new SHAPE_SEGMENT( pts[2], pts[3], aItem->GetWidth() ) );
|
||||
segs.push_back( new SHAPE_SEGMENT( pts[3], pts[0], aItem->GetWidth() ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CIRCLE:
|
||||
{
|
||||
// SHAPE_CIRCLE has no ConvertToPolyline() method, so use a 360.0 SHAPE_ARC
|
||||
|
|
|
@ -150,6 +150,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateVToolbar()
|
|||
KiScaledSeparator( m_drawToolBar, this );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::placePad, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawLine, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawRectangle, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawArc, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE );
|
||||
|
@ -252,6 +253,7 @@ void FOOTPRINT_EDIT_FRAME::SyncToolbars()
|
|||
// If there is no footprint loaded, disable the editing tools
|
||||
m_drawToolBar->Toggle( PCB_ACTIONS::placePad, false, false );
|
||||
m_drawToolBar->Toggle( PCB_ACTIONS::drawLine, false, false );
|
||||
m_drawToolBar->Toggle( PCB_ACTIONS::drawRectangle, false, false );
|
||||
m_drawToolBar->Toggle( PCB_ACTIONS::drawCircle, false, false );
|
||||
m_drawToolBar->Toggle( PCB_ACTIONS::drawArc, false, false );
|
||||
m_drawToolBar->Toggle( PCB_ACTIONS::drawPolygon, false, false );
|
||||
|
@ -266,6 +268,7 @@ void FOOTPRINT_EDIT_FRAME::SyncToolbars()
|
|||
{
|
||||
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::placePad );
|
||||
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawLine );
|
||||
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawRectangle );
|
||||
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawCircle );
|
||||
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawArc );
|
||||
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawPolygon );
|
||||
|
|
|
@ -183,6 +183,48 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( m_editModules && !m_frame->GetModel() )
|
||||
return 0;
|
||||
|
||||
MODULE* module = dynamic_cast<MODULE*>( m_frame->GetModel() );
|
||||
DRAWSEGMENT* rect = m_editModules ? new EDGE_MODULE( module ) : new DRAWSEGMENT;
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::RECT );
|
||||
OPT<VECTOR2D> startingPoint = boost::make_optional<VECTOR2D>( false, VECTOR2D( 0, 0 ) );
|
||||
|
||||
rect->SetFlags(IS_NEW );
|
||||
|
||||
if( aEvent.HasPosition() )
|
||||
startingPoint = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) );
|
||||
|
||||
std::string tool = aEvent.GetCommandStr().get();
|
||||
m_frame->PushTool( tool );
|
||||
Activate();
|
||||
|
||||
while( drawSegment( tool, S_RECT, rect, startingPoint ) )
|
||||
{
|
||||
if( rect )
|
||||
{
|
||||
if( m_editModules )
|
||||
static_cast<EDGE_MODULE*>( rect )->SetLocalCoord();
|
||||
|
||||
commit.Add( rect );
|
||||
commit.Push( _( "Draw a rectangle" ) );
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, rect );
|
||||
}
|
||||
|
||||
rect = m_editModules ? new EDGE_MODULE( module ) : new DRAWSEGMENT;
|
||||
rect->SetFlags(IS_NEW );
|
||||
startingPoint = NULLOPT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( m_editModules && !m_frame->GetModel() )
|
||||
|
@ -918,8 +960,8 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
|
|||
bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMENT*& aGraphic,
|
||||
OPT<VECTOR2D> aStartingPoint )
|
||||
{
|
||||
// Only two shapes are currently supported
|
||||
assert( aShape == S_SEGMENT || aShape == S_CIRCLE );
|
||||
// Only three shapes are currently supported
|
||||
assert( aShape == S_SEGMENT || aShape == S_CIRCLE || aShape == S_RECT );
|
||||
GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() );
|
||||
POINT_EDITOR* pointEditor = m_toolMgr->GetTool<POINT_EDITOR>();
|
||||
|
||||
|
@ -1938,6 +1980,7 @@ void DRAWING_TOOL::setTransitions()
|
|||
{
|
||||
Go( &DRAWING_TOOL::DrawLine, PCB_ACTIONS::drawLine.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawPolygon.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawRectangle, PCB_ACTIONS::drawRectangle.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawCircle, PCB_ACTIONS::drawCircle.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawArc, PCB_ACTIONS::drawArc.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawDimension, PCB_ACTIONS::drawDimension.MakeEvent() );
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
{
|
||||
NONE,
|
||||
LINE,
|
||||
RECT,
|
||||
CIRCLE,
|
||||
ARC,
|
||||
TEXT,
|
||||
|
@ -91,6 +92,14 @@ public:
|
|||
*/
|
||||
int DrawLine( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function DrawRectangle()
|
||||
* Starts interactively drawing a rectangle. After invoking the function it expects the user
|
||||
* to first click on a point that is going to be used as the top-left of the rectangle. The
|
||||
* second click determines the bottom-right.
|
||||
*/
|
||||
int DrawRectangle( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function DrawCircle()
|
||||
* Starts interactively drawing a circle. After invoking the function it expects the user
|
||||
|
|
|
@ -66,6 +66,11 @@ TOOL_ACTION PCB_ACTIONS::drawPolygon( "pcbnew.InteractiveDrawing.graphicPolygon"
|
|||
_( "Draw Graphic Polygon" ), _( "Draw a graphic polygon" ),
|
||||
add_graphical_polygon_xpm, AF_ACTIVATE, (void*) ZONE_MODE::GRAPHIC_POLYGON );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::drawRectangle( "pcbnew.InteractiveDrawing.rectangle",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Draw Rectangle" ), _( "Draw a rectangle" ),
|
||||
add_rectangle_xpm, AF_ACTIVATE );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::drawCircle( "pcbnew.InteractiveDrawing.circle",
|
||||
AS_GLOBAL,
|
||||
MD_SHIFT + MD_CTRL + 'C', LEGACY_HK_NAME( "Draw Circle" ),
|
||||
|
|
|
@ -136,6 +136,7 @@ public:
|
|||
// Drawing Tool Activations
|
||||
static TOOL_ACTION drawLine;
|
||||
static TOOL_ACTION drawPolygon;
|
||||
static TOOL_ACTION drawRectangle;
|
||||
static TOOL_ACTION drawCircle;
|
||||
static TOOL_ACTION drawArc;
|
||||
static TOOL_ACTION placeText;
|
||||
|
|
|
@ -50,6 +50,11 @@ enum SEG_POINTS
|
|||
SEG_START, SEG_END
|
||||
};
|
||||
|
||||
enum RECT_POINTS
|
||||
{
|
||||
RECT_TOP_LEFT, RECT_TOP_RIGHT, RECT_BOT_RIGHT, RECT_BOT_LEFT
|
||||
};
|
||||
|
||||
enum ARC_POINTS
|
||||
{
|
||||
ARC_CENTER, ARC_START, ARC_MID, ARC_END
|
||||
|
@ -144,6 +149,13 @@ public:
|
|||
points->AddPoint( segment->GetEnd() );
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
points->AddPoint( segment->GetStart() );
|
||||
points->AddPoint( wxPoint( segment->GetEnd().x, segment->GetStart().y ) );
|
||||
points->AddPoint( segment->GetEnd() );
|
||||
points->AddPoint( wxPoint( segment->GetStart().x, segment->GetEnd().y ) );
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
points->AddPoint( segment->GetCenter() );
|
||||
points->AddPoint( segment->GetArcStart() );
|
||||
|
@ -163,7 +175,6 @@ public:
|
|||
case S_CIRCLE:
|
||||
points->AddPoint( segment->GetCenter() );
|
||||
points->AddPoint( segment->GetEnd() );
|
||||
|
||||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
|
@ -441,6 +452,29 @@ void POINT_EDITOR::updateItem() const
|
|||
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
{
|
||||
if( isModified( m_editPoints->Point( RECT_TOP_LEFT ) ) )
|
||||
{
|
||||
segment->SetStart( (wxPoint) m_editPoints->Point( RECT_TOP_LEFT ).GetPosition() );
|
||||
}
|
||||
else if( isModified( m_editPoints->Point( RECT_TOP_RIGHT ) ) )
|
||||
{
|
||||
segment->SetStartY( m_editPoints->Point( RECT_TOP_RIGHT ).GetPosition().y );
|
||||
segment->SetEndX( m_editPoints->Point( RECT_TOP_RIGHT ).GetPosition().x );
|
||||
}
|
||||
else if( isModified( m_editPoints->Point( RECT_BOT_RIGHT ) ) )
|
||||
{
|
||||
segment->SetEnd( (wxPoint) m_editPoints->Point( RECT_BOT_RIGHT ).GetPosition() );
|
||||
}
|
||||
else if( isModified( m_editPoints->Point( RECT_BOT_LEFT ) ) )
|
||||
{
|
||||
segment->SetStartX( m_editPoints->Point( RECT_BOT_LEFT ).GetPosition().x );
|
||||
segment->SetEndY( m_editPoints->Point( RECT_BOT_LEFT ).GetPosition().y );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
{
|
||||
VECTOR2I center = m_editPoints->Point( ARC_CENTER ).GetPosition();
|
||||
|
@ -482,9 +516,8 @@ void POINT_EDITOR::updateItem() const
|
|||
|
||||
segment->SetAngle( newAngle );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CIRCLE:
|
||||
{
|
||||
|
@ -500,9 +533,8 @@ void POINT_EDITOR::updateItem() const
|
|||
{
|
||||
segment->SetEnd( wxPoint( end.x, end.y ) );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
{
|
||||
|
@ -512,8 +544,8 @@ void POINT_EDITOR::updateItem() const
|
|||
outline.SetVertex( i, m_editPoints->Point( i ).GetPosition() );
|
||||
|
||||
validatePolygon( outline );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CURVE:
|
||||
if( isModified( m_editPoints->Point( BEZIER_CURVE_START ) ) )
|
||||
|
@ -685,6 +717,15 @@ void POINT_EDITOR::updatePoints()
|
|||
m_editPoints->Point( SEG_END ).SetPosition( segment->GetEnd() );
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
m_editPoints->Point( RECT_TOP_LEFT ).SetPosition( segment->GetStart() );
|
||||
m_editPoints->Point( RECT_TOP_RIGHT ).SetPosition( segment->GetEnd().x,
|
||||
segment->GetStart().y );
|
||||
m_editPoints->Point( RECT_BOT_RIGHT ).SetPosition( segment->GetEnd() );
|
||||
m_editPoints->Point( RECT_BOT_LEFT ).SetPosition( segment->GetStart().x,
|
||||
segment->GetEnd().y );
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
m_editPoints->Point( ARC_CENTER ).SetPosition( segment->GetCenter() );
|
||||
m_editPoints->Point( ARC_START ).SetPosition( segment->GetArcStart() );
|
||||
|
|
|
@ -480,6 +480,12 @@ public:
|
|||
y = 0.0;
|
||||
}
|
||||
|
||||
IDF_POINT( double aX, double aY )
|
||||
{
|
||||
x = aX;
|
||||
y = aY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Matches()
|
||||
* returns true if the given coordinate point is within the given radius
|
||||
|
|
Loading…
Reference in New Issue