pcbnew: Allow curves in custom pads
Updates custom pad functions to permit adding arbitrary curves to the primitives
This commit is contained in:
parent
b56ca3f09c
commit
f7c042a357
|
@ -259,10 +259,26 @@ void UNIT_BINDER::Enable( bool aEnable )
|
|||
}
|
||||
|
||||
|
||||
void UNIT_BINDER::Show( bool aShow )
|
||||
void UNIT_BINDER::Show( bool aShow, bool aResize )
|
||||
{
|
||||
m_label->Show( aShow );
|
||||
m_value->Show( aShow );
|
||||
m_unitLabel->Show( aShow );
|
||||
|
||||
if( aResize )
|
||||
{
|
||||
if( aShow )
|
||||
{
|
||||
m_label->SetSize( -1, -1 );
|
||||
m_value->SetSize( -1, -1 );
|
||||
m_unitLabel->SetSize( -1, -1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_label->SetSize( 0, 0 );
|
||||
m_value->SetSize( 0, 0 );
|
||||
m_unitLabel->SetSize( 0, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,8 +115,11 @@ public:
|
|||
/**
|
||||
* Function Show
|
||||
* Shows/hides the label, widget and units label.
|
||||
*
|
||||
* @param aShow called for the Show() routine in wx
|
||||
* @param aResize if true, the element will be sized to 0 on hide and -1 on show
|
||||
*/
|
||||
void Show( bool aShow );
|
||||
void Show( bool aShow, bool aResize = false );
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -64,11 +64,13 @@ DRAWSEGMENT::~DRAWSEGMENT()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
void DRAWSEGMENT::SetPosition( const wxPoint& aPos )
|
||||
{
|
||||
m_Start = aPos;
|
||||
}
|
||||
|
||||
|
||||
const wxPoint DRAWSEGMENT::GetPosition() const
|
||||
{
|
||||
if( m_Shape == S_POLYGON )
|
||||
|
@ -77,6 +79,28 @@ const wxPoint DRAWSEGMENT::GetPosition() const
|
|||
return m_Start;
|
||||
}
|
||||
|
||||
|
||||
double DRAWSEGMENT::GetLength() const
|
||||
{
|
||||
double length = 0.0;
|
||||
|
||||
switch( m_Shape )
|
||||
{
|
||||
case S_CURVE:
|
||||
for( size_t ii = 1; ii < m_BezierPoints.size(); ++ii )
|
||||
length += GetLineLength( m_BezierPoints[ii - 1], m_BezierPoints[ii] );
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
length = GetLineLength( GetStart(), GetEnd() );
|
||||
break;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
void DRAWSEGMENT::Move( const wxPoint& aMoveVector )
|
||||
{
|
||||
m_Start += aMoveVector;
|
||||
|
@ -148,6 +172,7 @@ void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, double aAngle )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void DRAWSEGMENT::Flip( const wxPoint& aCentre )
|
||||
{
|
||||
m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
|
||||
|
@ -234,6 +259,7 @@ const wxPoint DRAWSEGMENT::GetCenter() const
|
|||
return c;
|
||||
}
|
||||
|
||||
|
||||
const wxPoint DRAWSEGMENT::GetArcEnd() const
|
||||
{
|
||||
wxPoint endPoint( m_End ); // start of arc
|
||||
|
@ -255,6 +281,7 @@ const wxPoint DRAWSEGMENT::GetArcEnd() const
|
|||
return endPoint; // after rotation, the end of the arc.
|
||||
}
|
||||
|
||||
|
||||
const wxPoint DRAWSEGMENT::GetArcMid() const
|
||||
{
|
||||
wxPoint endPoint( m_End );
|
||||
|
@ -276,6 +303,7 @@ const wxPoint DRAWSEGMENT::GetArcMid() const
|
|||
return endPoint; // after rotation, the end of the arc.
|
||||
}
|
||||
|
||||
|
||||
double DRAWSEGMENT::GetArcAngleStart() const
|
||||
{
|
||||
// due to the Y axis orient atan2 needs - y value
|
||||
|
@ -454,6 +482,7 @@ void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void DRAWSEGMENT::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList )
|
||||
{
|
||||
wxString msg;
|
||||
|
@ -484,6 +513,9 @@ void DRAWSEGMENT::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_IT
|
|||
|
||||
case S_CURVE:
|
||||
aList.push_back( MSG_PANEL_ITEM( shape, _( "Curve" ), RED ) );
|
||||
|
||||
msg = MessageTextFromValue( aUnits, GetLength() );
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Length" ), msg, DARKGREEN ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -931,6 +963,7 @@ void DRAWSEGMENT::computeArcBBox( EDA_RECT& aBBox ) const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void DRAWSEGMENT::SetPolyPoints( const std::vector<wxPoint>& aPoints )
|
||||
{
|
||||
m_Poly.RemoveAllContours();
|
||||
|
|
|
@ -231,10 +231,7 @@ public:
|
|||
* returns the length of the track using the hypotenuse calculation.
|
||||
* @return double - the length of the track
|
||||
*/
|
||||
double GetLength() const
|
||||
{
|
||||
return GetLineLength( GetStart(), GetEnd() );
|
||||
}
|
||||
double GetLength() const;
|
||||
|
||||
virtual void Move( const wxPoint& aMoveVector ) override;
|
||||
|
||||
|
|
|
@ -99,6 +99,8 @@ public:
|
|||
double m_ArcAngle; /// angle of an arc, from its starting point, in 0.1 deg
|
||||
wxPoint m_Start; /// is also the center of the circle and arc
|
||||
wxPoint m_End; /// is also the start point of the arc
|
||||
wxPoint m_Ctrl1; /// Bezier Control point 1
|
||||
wxPoint m_Ctrl2; /// Bezier Control point 2
|
||||
std::vector<wxPoint> m_Poly;
|
||||
|
||||
PAD_CS_PRIMITIVE( STROKE_T aShape ):
|
||||
|
@ -285,6 +287,7 @@ public:
|
|||
* a thick segment
|
||||
* a filled circle or ring ( if thickness == 0, this is a filled circle, else a ring)
|
||||
* a arc
|
||||
* a curve
|
||||
*/
|
||||
void AddPrimitive( const SHAPE_POLY_SET& aPoly, int aThickness ); ///< add a polygonal basic shape
|
||||
void AddPrimitive( const std::vector<wxPoint>& aPoly, int aThickness ); ///< add a polygonal basic shape
|
||||
|
@ -292,6 +295,8 @@ public:
|
|||
void AddPrimitive( wxPoint aCenter, int aRadius, int aThickness ); ///< ring or circle basic shape
|
||||
void AddPrimitive( wxPoint aCenter, wxPoint aStart,
|
||||
int aArcAngle, int aThickness ); ///< arc basic shape
|
||||
void AddPrimitive( wxPoint aStart, wxPoint aEnd, wxPoint aCtrl1,
|
||||
wxPoint aCtrl2, int aThickness ); ///< curve basic shape
|
||||
|
||||
|
||||
bool GetBestAnchorPosition( VECTOR2I& aPos );
|
||||
|
|
|
@ -51,6 +51,10 @@ DIALOG_PAD_PRIMITIVES_PROPERTIES::DIALOG_PAD_PRIMITIVES_PROPERTIES( wxWindow* aP
|
|||
m_shape( aShape ),
|
||||
m_startX( aFrame, m_startXLabel, m_startXCtrl, m_startXUnits, true ),
|
||||
m_startY( aFrame, m_startYLabel, m_startYCtrl, m_startYUnits, true ),
|
||||
m_ctrl1X( aFrame, m_ctrl1XLabel, m_ctrl1XCtrl, m_ctrl1XUnits, true ),
|
||||
m_ctrl1Y( aFrame, m_ctrl1YLabel, m_ctrl1YCtrl, m_ctrl1YUnits, true ),
|
||||
m_ctrl2X( aFrame, m_ctrl2XLabel, m_ctrl2XCtrl, m_ctrl2XUnits, true ),
|
||||
m_ctrl2Y( aFrame, m_ctrl2YLabel, m_ctrl2YCtrl, m_ctrl2YUnits, true ),
|
||||
m_endX( aFrame, m_endXLabel, m_endXCtrl, m_endXUnits, true ),
|
||||
m_endY( aFrame, m_endYLabel, m_endYCtrl, m_endYUnits, true ),
|
||||
m_radius( aFrame, m_radiusLabel, m_radiusCtrl, m_radiusUnits, true ),
|
||||
|
@ -58,6 +62,8 @@ DIALOG_PAD_PRIMITIVES_PROPERTIES::DIALOG_PAD_PRIMITIVES_PROPERTIES( wxWindow* aP
|
|||
{
|
||||
SetInitialFocus( m_startXCtrl );
|
||||
|
||||
TransferDataToWindow();
|
||||
|
||||
m_sdbSizerOK->SetDefault();
|
||||
|
||||
FinishDialogSettings();
|
||||
|
@ -82,6 +88,27 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow()
|
|||
m_startY.SetValue( m_shape->m_Start.y );
|
||||
m_endX.SetValue( m_shape->m_End.x );
|
||||
m_endY.SetValue( m_shape->m_End.y );
|
||||
m_ctrl1X.Show( false, true );
|
||||
m_ctrl1Y.Show( false, true );
|
||||
m_ctrl2X.Show( false, true );
|
||||
m_ctrl2Y.Show( false, true );
|
||||
m_staticTextPosCtrl1->Show( false );
|
||||
m_staticTextPosCtrl1->SetSize( 0, 0 );
|
||||
m_staticTextPosCtrl2->Show( false );
|
||||
m_staticTextPosCtrl2->SetSize( 0, 0 );
|
||||
m_radius.Show( false );
|
||||
break;
|
||||
|
||||
case S_CURVE: // Bezier line
|
||||
SetTitle( _( "Bezier" ) );
|
||||
m_startX.SetValue( m_shape->m_Start.x );
|
||||
m_startY.SetValue( m_shape->m_Start.y );
|
||||
m_endX.SetValue( m_shape->m_End.x );
|
||||
m_endY.SetValue( m_shape->m_End.y );
|
||||
m_ctrl1X.SetValue( m_shape->m_Ctrl1.x );
|
||||
m_ctrl1Y.SetValue( m_shape->m_Ctrl1.y );
|
||||
m_ctrl2X.SetValue( m_shape->m_Ctrl2.x );
|
||||
m_ctrl2Y.SetValue( m_shape->m_Ctrl2.y );
|
||||
m_radius.Show( false );
|
||||
break;
|
||||
|
||||
|
@ -95,6 +122,14 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow()
|
|||
m_radiusLabel->SetLabel( _( "Angle:" ) );
|
||||
m_radius.SetUnits( DEGREES );
|
||||
m_radius.SetValue( m_shape->m_ArcAngle );
|
||||
m_ctrl1X.Show( false, true );
|
||||
m_ctrl1Y.Show( false, true );
|
||||
m_ctrl2X.Show( false, true );
|
||||
m_ctrl2Y.Show( false, true );
|
||||
m_staticTextPosCtrl1->Show( false );
|
||||
m_staticTextPosCtrl1->SetSize( 0, 0 );
|
||||
m_staticTextPosCtrl2->Show( false );
|
||||
m_staticTextPosCtrl2->SetSize( 0, 0 );
|
||||
break;
|
||||
|
||||
case S_CIRCLE: // ring or circle
|
||||
|
@ -113,6 +148,14 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow()
|
|||
m_startX.SetValue( m_shape->m_Start.x );
|
||||
m_startY.SetValue( m_shape->m_Start.y );
|
||||
m_radius.SetValue( m_shape->m_Radius );
|
||||
m_ctrl1X.Show( false, true );
|
||||
m_ctrl1Y.Show( false, true );
|
||||
m_ctrl2X.Show( false, true );
|
||||
m_ctrl2Y.Show( false, true );
|
||||
m_staticTextPosCtrl1->Show( false );
|
||||
m_staticTextPosCtrl1->SetSize( 0, 0 );
|
||||
m_staticTextPosCtrl2->Show( false );
|
||||
m_staticTextPosCtrl2->SetSize( 0, 0 );
|
||||
break;
|
||||
|
||||
case S_POLYGON: // polygon
|
||||
|
@ -141,6 +184,17 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataFromWindow()
|
|||
m_shape->m_End.y = m_endY.GetValue();
|
||||
break;
|
||||
|
||||
case S_CURVE: // Segment with rounded ends
|
||||
m_shape->m_Start.x = m_startX.GetValue();
|
||||
m_shape->m_Start.y = m_startY.GetValue();
|
||||
m_shape->m_End.x = m_endX.GetValue();
|
||||
m_shape->m_End.y = m_endY.GetValue();
|
||||
m_shape->m_Ctrl1.x = m_ctrl1X.GetValue();
|
||||
m_shape->m_Ctrl1.y = m_ctrl1Y.GetValue();
|
||||
m_shape->m_Ctrl2.x = m_ctrl2X.GetValue();
|
||||
m_shape->m_Ctrl2.y = m_ctrl2Y.GetValue();
|
||||
break;
|
||||
|
||||
case S_ARC: // Arc with rounded ends
|
||||
// Start point of arc
|
||||
m_shape->m_Start.x = m_startX.GetValue();
|
||||
|
@ -194,6 +248,9 @@ DIALOG_PAD_PRIMITIVE_POLY_PROPS::DIALOG_PAD_PRIMITIVE_POLY_PROPS( wxWindow* aPar
|
|||
|
||||
// TODO: move wxEVT_GRID_CELL_CHANGING in wxFormbuilder, when it support it
|
||||
m_gridCornersList->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ), NULL, this );
|
||||
|
||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||
FinishDialogSettings();
|
||||
}
|
||||
|
||||
|
||||
|
@ -535,7 +592,7 @@ inline void geom_transf( wxPoint& aCoord, wxPoint& aMove, double aScale, double
|
|||
void DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform( std::vector<PAD_CS_PRIMITIVE>* aList, int aDuplicateCount )
|
||||
{
|
||||
wxPoint move_vect( m_vectorX.GetValue(), m_vectorY.GetValue() );
|
||||
double rotation = m_rotation.GetValue() / 10.0;
|
||||
double rotation = m_rotation.GetValue();
|
||||
double scale = DoubleValueFromString( UNSCALED_UNITS, m_scaleCtrl->GetValue() );
|
||||
|
||||
// Avoid too small / too large scale, which could create issues:
|
||||
|
@ -581,6 +638,11 @@ void DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform( std::vector<PAD_CS_PRIMITIVE>*
|
|||
case S_ARC: // Arc with rounded ends
|
||||
break;
|
||||
|
||||
case S_CURVE: // Bezier with rounded ends
|
||||
geom_transf( shape->m_Ctrl1, currMoveVect, scale, curr_rotation );
|
||||
geom_transf( shape->m_Ctrl2, currMoveVect, scale, curr_rotation );
|
||||
break;
|
||||
|
||||
case S_CIRCLE: // ring or circle
|
||||
shape->m_Radius = KiROUND( shape->m_Radius * scale );
|
||||
break;
|
||||
|
|
|
@ -843,6 +843,12 @@ void DIALOG_PAD_PROPERTIES::displayPrimitivesList()
|
|||
bs_info[2] = _( "to " ) + formatCoord( m_units, primitive.m_End );
|
||||
break;
|
||||
|
||||
case S_CURVE: // Bezier segment
|
||||
bs_info[0] = _( "Bezier" );
|
||||
bs_info[1] = _( "from " ) + formatCoord( m_units, primitive.m_Start );
|
||||
bs_info[2] = _( "to " ) + formatCoord( m_units, primitive.m_End );
|
||||
break;
|
||||
|
||||
case S_ARC: // Arc with rounded ends
|
||||
bs_info[0] = _( "Arc" );
|
||||
bs_info[1] = _( "center " ) + formatCoord( m_units, primitive.m_Start );// Center
|
||||
|
@ -1355,11 +1361,12 @@ void DIALOG_PAD_PROPERTIES::redraw()
|
|||
dummySegment->Rotate( wxPoint( 0, 0), m_dummyPad->GetOrientation() );
|
||||
dummySegment->Move( m_dummyPad->GetPosition() );
|
||||
|
||||
// Update selected primitive (highligth selected)
|
||||
// Update selected primitive (highlight selected)
|
||||
switch( primitive.m_Shape )
|
||||
{
|
||||
case S_SEGMENT:
|
||||
case S_ARC:
|
||||
case S_CURVE:
|
||||
break;
|
||||
|
||||
case S_CIRCLE: // ring or circle
|
||||
|
@ -1368,7 +1375,7 @@ void DIALOG_PAD_PROPERTIES::redraw()
|
|||
// but it is easy to create it with a circle having the
|
||||
// right radius and outline width
|
||||
wxPoint end = dummySegment->GetCenter();
|
||||
end.x += primitive.m_Radius/2;
|
||||
end.x += primitive.m_Radius / 2;
|
||||
dummySegment->SetEnd( end );
|
||||
dummySegment->SetWidth( primitive.m_Radius );
|
||||
}
|
||||
|
@ -1399,7 +1406,7 @@ void DIALOG_PAD_PROPERTIES::redraw()
|
|||
// gives a size to the full drawable area
|
||||
BOX2I drawbox;
|
||||
drawbox.Move( m_dummyPad->GetPosition() );
|
||||
drawbox.Inflate( bbox.GetSize().x*2, bbox.GetSize().y*2 );
|
||||
drawbox.Inflate( bbox.GetSize().x * 2, bbox.GetSize().y * 2 );
|
||||
|
||||
view->SetBoundary( drawbox );
|
||||
|
||||
|
@ -1987,14 +1994,20 @@ void DIALOG_PAD_PROPERTIES::onDeletePrimitive( wxCommandEvent& event )
|
|||
void DIALOG_PAD_PROPERTIES::onAddPrimitive( wxCommandEvent& event )
|
||||
{
|
||||
// Ask user for shape type
|
||||
wxString shapelist[] = { _( "Segment" ), _( "Arc" ), _( "Ring/Circle" ), _( "Polygon" ) };
|
||||
wxString shapelist[] = { _( "Segment" ), _( "Arc" ), _( "Bezier" ),
|
||||
_( "Ring/Circle" ), _( "Polygon" ) };
|
||||
|
||||
int type = wxGetSingleChoiceIndex( _( "Shape type:" ), _( "Add Primitive" ),
|
||||
arrayDim( shapelist ), shapelist, 0, this );
|
||||
|
||||
STROKE_T listtype[] = { S_SEGMENT, S_ARC, S_CIRCLE, S_POLYGON };
|
||||
// User pressed cancel
|
||||
if( type == -1 )
|
||||
return;
|
||||
|
||||
STROKE_T listtype[] = { S_SEGMENT, S_ARC, S_CURVE, S_CIRCLE, S_POLYGON };
|
||||
|
||||
PAD_CS_PRIMITIVE primitive( listtype[type] );
|
||||
primitive.m_Thickness = m_board->GetDesignSettings().GetLineThickness( F_Cu );
|
||||
|
||||
if( listtype[type] == S_POLYGON )
|
||||
{
|
||||
|
|
|
@ -191,6 +191,10 @@ private:
|
|||
|
||||
UNIT_BINDER m_startX;
|
||||
UNIT_BINDER m_startY;
|
||||
UNIT_BINDER m_ctrl1X;
|
||||
UNIT_BINDER m_ctrl1Y;
|
||||
UNIT_BINDER m_ctrl2X;
|
||||
UNIT_BINDER m_ctrl2Y;
|
||||
UNIT_BINDER m_endX;
|
||||
UNIT_BINDER m_endY;
|
||||
UNIT_BINDER m_radius;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Dec 1 2018)
|
||||
// C++ code generated with wxFormBuilder (version Jan 17 2019)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -890,6 +890,58 @@ DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE::DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE( wx
|
|||
m_startYUnits->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_startYUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
|
||||
|
||||
m_staticTextPosCtrl1 = new wxStaticText( this, wxID_ANY, _("Control Point 1"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextPosCtrl1->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_staticTextPosCtrl1, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_ctrl1XLabel = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ctrl1XLabel->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_ctrl1XLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT, 5 );
|
||||
|
||||
m_ctrl1XCtrl = new TEXT_CTRL_EVAL( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerShapeProperties->Add( m_ctrl1XCtrl, 0, wxALL, 5 );
|
||||
|
||||
m_ctrl1XUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ctrl1XUnits->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_ctrl1XUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
|
||||
|
||||
m_ctrl1YLabel = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ctrl1YLabel->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_ctrl1YLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT, 5 );
|
||||
|
||||
m_ctrl1YCtrl = new TEXT_CTRL_EVAL( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerShapeProperties->Add( m_ctrl1YCtrl, 0, wxALL, 5 );
|
||||
|
||||
m_ctrl1YUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ctrl1YUnits->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_ctrl1YUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
|
||||
|
||||
m_staticTextPosCtrl2 = new wxStaticText( this, wxID_ANY, _("Control Point 2"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextPosCtrl2->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_staticTextPosCtrl2, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_ctrl2XLabel = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ctrl2XLabel->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_ctrl2XLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT, 5 );
|
||||
|
||||
m_ctrl2XCtrl = new TEXT_CTRL_EVAL( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerShapeProperties->Add( m_ctrl2XCtrl, 0, wxALL, 5 );
|
||||
|
||||
m_ctrl2XUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ctrl2XUnits->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_ctrl2XUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
|
||||
|
||||
m_ctrl2YLabel = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ctrl2YLabel->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_ctrl2YLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT, 5 );
|
||||
|
||||
m_ctrl2YCtrl = new TEXT_CTRL_EVAL( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerShapeProperties->Add( m_ctrl2YCtrl, 0, wxALL, 5 );
|
||||
|
||||
m_ctrl2YUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ctrl2YUnits->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_ctrl2YUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
|
||||
|
||||
m_staticTextPosEnd = new wxStaticText( this, wxID_ANY, _("End point"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextPosEnd->Wrap( -1 );
|
||||
fgSizerShapeProperties->Add( m_staticTextPosEnd, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Dec 1 2018)
|
||||
// C++ code generated with wxFormBuilder (version Jan 17 2019)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -239,6 +239,20 @@ class DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE : public DIALOG_SHIM
|
|||
wxStaticText* m_startYLabel;
|
||||
TEXT_CTRL_EVAL* m_startYCtrl;
|
||||
wxStaticText* m_startYUnits;
|
||||
wxStaticText* m_staticTextPosCtrl1;
|
||||
wxStaticText* m_ctrl1XLabel;
|
||||
TEXT_CTRL_EVAL* m_ctrl1XCtrl;
|
||||
wxStaticText* m_ctrl1XUnits;
|
||||
wxStaticText* m_ctrl1YLabel;
|
||||
TEXT_CTRL_EVAL* m_ctrl1YCtrl;
|
||||
wxStaticText* m_ctrl1YUnits;
|
||||
wxStaticText* m_staticTextPosCtrl2;
|
||||
wxStaticText* m_ctrl2XLabel;
|
||||
TEXT_CTRL_EVAL* m_ctrl2XCtrl;
|
||||
wxStaticText* m_ctrl2XUnits;
|
||||
wxStaticText* m_ctrl2YLabel;
|
||||
TEXT_CTRL_EVAL* m_ctrl2YCtrl;
|
||||
wxStaticText* m_ctrl2YUnits;
|
||||
wxStaticText* m_staticTextPosEnd;
|
||||
wxStaticText* m_endXLabel;
|
||||
TEXT_CTRL_EVAL* m_endXCtrl;
|
||||
|
|
|
@ -1441,6 +1441,15 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
|
|||
FormatInternalUnits( primitive.m_Thickness ).c_str() );
|
||||
break;
|
||||
|
||||
case S_CURVE: // Bezier Curve
|
||||
m_out->Print( aNestLevel, "(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s)) (width %s))",
|
||||
FormatInternalUnits( primitive.m_Start ).c_str(),
|
||||
FormatInternalUnits( primitive.m_Ctrl1 ).c_str(),
|
||||
FormatInternalUnits( primitive.m_Ctrl2 ).c_str(),
|
||||
FormatInternalUnits( primitive.m_End ).c_str(),
|
||||
FormatInternalUnits( primitive.m_Thickness ).c_str() );
|
||||
break;
|
||||
|
||||
case S_POLYGON: // polygon
|
||||
if( primitive.m_Poly.size() < 2 )
|
||||
break; // Malformed polygon.
|
||||
|
|
|
@ -48,7 +48,8 @@ class NETINFO_MAPPING;
|
|||
//#define SEXPR_BOARD_FILE_VERSION 20171114 // Save 3D model offset in mm, instead of inches
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20171125 // Locked/unlocked TEXTE_MODULE
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20171130 // 3D model offset written using "offset" parameter
|
||||
#define SEXPR_BOARD_FILE_VERSION 20190331 // hatched zones and chamfered round rect pads
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20190331 // hatched zones and chamfered round rect pads
|
||||
#define SEXPR_BOARD_FILE_VERSION 20190421 // curves in custom pads
|
||||
|
||||
#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)
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include <convert_basic_shapes_to_polygon.h>
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <geometry/convex_hull.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <bezier_curves.h>
|
||||
|
||||
|
||||
void PAD_CS_PRIMITIVE::ExportTo( DRAWSEGMENT* aTarget )
|
||||
|
@ -46,6 +48,8 @@ void PAD_CS_PRIMITIVE::ExportTo( DRAWSEGMENT* aTarget )
|
|||
aTarget->SetWidth( m_Thickness );
|
||||
aTarget->SetStart( m_Start );
|
||||
aTarget->SetEnd( m_End );
|
||||
aTarget->SetBezControl1( m_Ctrl1 );
|
||||
aTarget->SetBezControl2( m_Ctrl2 );
|
||||
|
||||
// in a DRAWSEGMENT the radius of a circle is calculated from the
|
||||
// center and one point on the circle outline (stored in m_End)
|
||||
|
@ -73,6 +77,8 @@ void PAD_CS_PRIMITIVE::Move( wxPoint aMoveVector )
|
|||
{
|
||||
m_Start += aMoveVector;
|
||||
m_End += aMoveVector;
|
||||
m_Ctrl1 += aMoveVector;
|
||||
m_Ctrl2 += aMoveVector;
|
||||
|
||||
for( auto& corner : m_Poly )
|
||||
{
|
||||
|
@ -138,6 +144,20 @@ void D_PAD::AddPrimitive( wxPoint aCenter, wxPoint aStart, int aArcAngle, int aT
|
|||
}
|
||||
|
||||
|
||||
void D_PAD::AddPrimitive( wxPoint aStart, wxPoint aEnd, wxPoint aCtrl1, wxPoint aCtrl2, int aThickness )
|
||||
{
|
||||
PAD_CS_PRIMITIVE shape( S_CURVE );
|
||||
shape.m_Start = aStart;
|
||||
shape.m_End = aEnd;
|
||||
shape.m_Ctrl1 = aCtrl1;
|
||||
shape.m_Ctrl2 = aCtrl2;
|
||||
shape.m_Thickness = aThickness;
|
||||
m_basicShapes.push_back( shape );
|
||||
|
||||
MergePrimitivesAsPolygon();
|
||||
}
|
||||
|
||||
|
||||
void D_PAD::AddPrimitive( wxPoint aCenter, int aRadius, int aThickness )
|
||||
{
|
||||
PAD_CS_PRIMITIVE shape( S_CIRCLE );
|
||||
|
@ -192,6 +212,21 @@ bool D_PAD::buildCustomPadPolygon( SHAPE_POLY_SET* aMergedPolygon,
|
|||
|
||||
switch( bshape.m_Shape )
|
||||
{
|
||||
case S_CURVE:
|
||||
{
|
||||
std::vector<wxPoint> ctrlPoints = { bshape.m_Start, bshape.m_Ctrl1, bshape.m_Ctrl2, bshape.m_End };
|
||||
BEZIER_POLY converter( ctrlPoints );
|
||||
std::vector< wxPoint> poly;
|
||||
converter.GetPoly( poly, bshape.m_Thickness );
|
||||
|
||||
for( unsigned ii = 1; ii < poly.size(); ii++ )
|
||||
{
|
||||
TransformRoundedEndsSegmentToPolygon( aux_polyset,
|
||||
poly[ii-1], poly[ii], aCircleToSegmentsCount, bshape.m_Thickness );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case S_SEGMENT: // usual segment : line with rounded ends
|
||||
TransformRoundedEndsSegmentToPolygon( aux_polyset,
|
||||
bshape.m_Start, bshape.m_End, aCircleToSegmentsCount, bshape.m_Thickness );
|
||||
|
|
|
@ -2792,8 +2792,15 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent )
|
|||
pad->AddPrimitive( dummysegm->BuildPolyPointsList(), dummysegm->GetWidth() );
|
||||
break;
|
||||
|
||||
case T_gr_curve:
|
||||
dummysegm = parseDRAWSEGMENT();
|
||||
pad->AddPrimitive( dummysegm->GetStart(), dummysegm->GetEnd(),
|
||||
dummysegm->GetBezControl1(), dummysegm->GetBezControl2(),
|
||||
dummysegm->GetWidth() );
|
||||
break;
|
||||
|
||||
default:
|
||||
Expecting( "gr_line, gr_arc, gr_circle or gr_poly" );
|
||||
Expecting( "gr_line, gr_arc, gr_circle, gr_curve or gr_poly" );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -410,19 +410,14 @@ int MODULE_EDITOR_TOOLS::CreatePadFromShapes( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
auto em = static_cast<EDGE_MODULE*> ( item );
|
||||
|
||||
// Currently, S_CURVE shape is not supported. so warn the user
|
||||
if( em->GetShape() == S_CURVE )
|
||||
{
|
||||
illegalItemsFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
PAD_CS_PRIMITIVE shape( em->GetShape() );
|
||||
shape.m_Start = em->GetStart();
|
||||
shape.m_End = em->GetEnd();
|
||||
shape.m_Radius = em->GetRadius();
|
||||
shape.m_Thickness = em->GetWidth();
|
||||
shape.m_ArcAngle = em->GetAngle();
|
||||
shape.m_Ctrl1 = em->GetBezControl1();
|
||||
shape.m_Ctrl2 = em->GetBezControl2();
|
||||
shape.m_Poly = em->BuildPolyPointsList();
|
||||
|
||||
shapes.push_back(shape);
|
||||
|
|
Loading…
Reference in New Issue