Commit 4e114e1a authored by Mikhail Karpenko's avatar Mikhail Karpenko

WIP: add teardrops to selected tracks

Teardrops are added to selection in accordance with user settings
collected from teardrops dialog window.
parent f2446132
......@@ -279,6 +279,7 @@ set( PCB_COMMON_SRCS
../pcbnew/class_zone.cpp
../pcbnew/class_zone_settings.cpp
../pcbnew/class_teardrop.cpp
../pcbnew/edit_teardrops.cpp
../pcbnew/classpcb.cpp
../pcbnew/ratsnest_data.cpp
../pcbnew/ratsnest_viewitem.cpp
......
......@@ -3,16 +3,13 @@
#include "class_board_item.h"
#include "class_undoredo_container.h"
TEARDROP::TEARDROP(BOARD_ITEM *aParent) :
TRACK(aParent, PCB_TRACE_T)
TEARDROP::TEARDROP()
{
m_type = TEARDROP_NONE;
}
bool TEARDROP::Create(TRACK &aTrack, ENDPOINT_T endPoint, TEARDROP_TYPE type = TEARDROP_STRAIGHT)
{
std::vector<VECTOR2I> upperSegment;
std::vector<VECTOR2I> lowerSegment;
bool result = false;
VIA *aVia = GetViaOnEnd(aTrack, endPoint);
......@@ -21,19 +18,21 @@ bool TEARDROP::Create(TRACK &aTrack, ENDPOINT_T endPoint, TEARDROP_TYPE type = T
}
if (type == TEARDROP_STRAIGHT) {
result = StraightSegments(aTrack, *aVia, upperSegment, lowerSegment, 100);
result = StraightSegments(aTrack, *aVia, m_upperSegment, m_lowerSegment, 100);
}
else if (type == TEARDROP_CURVED) {
result = CurvedSegments(aTrack, *aVia, upperSegment, lowerSegment);
}
if (result == true) {
result = BuildTracks(aTrack, upperSegment, m_upperSegment);
result = BuildTracks(aTrack, lowerSegment, m_lowerSegment);
result = CurvedSegments(aTrack, *aVia, m_upperSegment, m_lowerSegment);
}
return result;
}
void TEARDROP::GetCoordinates(std::vector<VECTOR2I> &points)
{
points.insert(points.end(), m_upperSegment.begin(), m_upperSegment.end());
points.insert(points.end(), m_lowerSegment.begin(), m_lowerSegment.end());
}
bool TEARDROP::SetVector(TRACK &aTrack, const VIA & aVia, VECTOR2I &startPoint, VECTOR2I &endPoint)
{
// Decide which end of the track is inside via and set this point as end of vector
......@@ -63,6 +62,13 @@ bool TEARDROP::CurvedSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECTOR
return false;
}
// Check that the track is not too short
double segOutsideVia = aTrack.GetLength() - (aVia.GetWidth() / 2);
double minLength = (90 * aVia.GetWidth()) / 100;
if (segOutsideVia < minLength) {
return false;
}
VECTOR2I point(0, 0);
VECTOR2I viaCenter(aVia.GetPosition().x, aVia.GetPosition().y);
double coeff = M_PI / 180.0;
......@@ -97,6 +103,13 @@ bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECT
return false;
}
// Check that the track is not too short
double segOutsideVia = aTrack.GetLength() - (aVia.GetWidth() / 2);
double minLength = (distance * aVia.GetWidth()) / 100;
if (segOutsideVia < minLength) {
return false;
}
// Equation coefficients
double r = (aVia.GetWidth() / 2) + ((distance * aVia.GetWidth()) / (2 *100));
double a = pow((endPoint.x - startPoint.x), 2) + pow((endPoint.y - startPoint.y), 2);
......@@ -124,8 +137,8 @@ bool TEARDROP::StraightSegments(TRACK &aTrack, const VIA &aVia, std::vector<VECT
upperSegment.push_back(linePoint);
upperSegment.push_back(upperPoint);
lowerSegment.push_back(linePoint);
lowerSegment.push_back(lowerPoint);
lowerSegment.push_back(linePoint);
return true;
}
......
......@@ -27,10 +27,10 @@
#include "class_track.h"
class TEARDROP : public TRACK
class TEARDROP
{
public:
TEARDROP(BOARD_ITEM *aParent);
TEARDROP();
/**
* @brief Defines the type of a teardrop.
......@@ -54,12 +54,14 @@ public:
*/
bool Create(TRACK &aTrack, ENDPOINT_T endPoint, TEARDROP_TYPE type);
void GetCoordinates(std::vector<VECTOR2I> &points);
private:
///> Contains the type of teardrop
TEARDROP_TYPE m_type;
///> \a m_upperSegment and \a m_lowerSegment contain pointers to actual segments composing a teardrop
std::vector<TRACK *> m_upperSegment;
std::vector<TRACK *> m_lowerSegment;
///> \a m_upperSegment and \a m_lowerSegment contain coordinates of segments composing a teardrop
std::vector<VECTOR2I> m_upperSegment;
std::vector<VECTOR2I> m_lowerSegment;
/**
* @brief Function \a CurvedSegments computes several points on deltoid curve and moves
......
......@@ -38,6 +38,12 @@ void DIALOG_TEARDROPS::InitDialogSettings()
if (m_scopeTracks->IsChecked() == true) {
m_settings->m_scope = static_cast<TEARDROPS_SCOPE>(m_settings->m_scope | TEARDROPS_SCOPE_TRACKS);
}
if (m_checkClear->IsChecked() == true) {
m_settings->m_clearSelection = true;
}
else {
m_settings->m_clearSelection = false;
}
}
void DIALOG_TEARDROPS::OnModeAdd(wxCommandEvent &event)
......@@ -59,7 +65,7 @@ void DIALOG_TEARDROPS::OnTracksAll(wxCommandEvent &event)
if (m_settings != NULL) {
m_settings->m_track = TEARDROPS_TRACKS_ALL;
}
m_checkClear->Enable(false);
}
void DIALOG_TEARDROPS::OnTracksSelected(wxCommandEvent &event)
......@@ -67,6 +73,7 @@ void DIALOG_TEARDROPS::OnTracksSelected(wxCommandEvent &event)
if (m_settings != NULL) {
m_settings->m_track = TEARDROPS_TRACKS_SELECTED;
}
m_checkClear->Enable(true);
}
void DIALOG_TEARDROPS::OnScopeVias(wxCommandEvent &event)
......@@ -96,3 +103,13 @@ void DIALOG_TEARDROPS::OnStyleChanged(wxCommandEvent &event)
// }
}
}
void DIALOG_TEARDROPS::OnClearSelection(wxCommandEvent &event)
{
if (m_checkClear->IsChecked() == true) {
m_settings->m_clearSelection = true;
}
else {
m_settings->m_clearSelection = false;
}
}
......@@ -32,6 +32,7 @@ public:
TEARDROPS_TRACKS m_track;
TEARDROPS_SCOPE m_scope;
TEARDROPS_TYPE m_type;
bool m_clearSelection;
} TEARDROPS_SETTINGS;
DIALOG_TEARDROPS(PCB_EDIT_FRAME *aParent, TEARDROPS_SETTINGS *settings);
......@@ -40,6 +41,7 @@ public:
void OnTracksAll(wxCommandEvent &event);
void OnTracksSelected(wxCommandEvent &event);
void OnStyleChanged(wxCommandEvent &event);
void OnClearSelection(wxCommandEvent &event);
void OnScopeVias(wxCommandEvent &event);
private:
......
......@@ -53,6 +53,12 @@ DIALOG_TEARDROPS_BASE::DIALOG_TEARDROPS_BASE( wxWindow* parent, wxWindowID id, c
m_optionsSizer->Add( m_checkIgnore, 0, 0, 5 );
m_checkClear = new wxCheckBox( this, wxID_ANY, wxT("Clear selection"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkClear->SetValue(true);
m_checkClear->Enable( false );
m_optionsSizer->Add( m_checkClear, 0, 0, 5 );
wxBoxSizer* m_styleSizer;
m_styleSizer = new wxBoxSizer( wxHORIZONTAL );
......@@ -121,6 +127,7 @@ DIALOG_TEARDROPS_BASE::DIALOG_TEARDROPS_BASE( wxWindow* parent, wxWindowID id, c
m_modeRemove->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnModeRemove ), NULL, this );
m_tracksAll->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnTracksAll ), NULL, this );
m_tracksSelected->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnTracksSelected ), NULL, this );
m_checkClear->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnClearSelection ), NULL, this );
m_choiceStyle->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnStyleChanged ), NULL, this );
m_scopeVias->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnScopeVias ), NULL, this );
}
......@@ -132,6 +139,7 @@ DIALOG_TEARDROPS_BASE::~DIALOG_TEARDROPS_BASE()
m_modeRemove->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnModeRemove ), NULL, this );
m_tracksAll->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnTracksAll ), NULL, this );
m_tracksSelected->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnTracksSelected ), NULL, this );
m_checkClear->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnClearSelection ), NULL, this );
m_choiceStyle->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnStyleChanged ), NULL, this );
m_scopeVias->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TEARDROPS_BASE::OnScopeVias ), NULL, this );
}
......@@ -84,7 +84,7 @@
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="0">
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizer13</property>
<property name="orient">wxHORIZONTAL</property>
......@@ -418,6 +418,62 @@
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag"></property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="bg"></property>
<property name="checked">1</property>
<property name="context_help"></property>
<property name="enabled">0</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Clear selection</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">m_checkClear</property>
<property name="permission">protected</property>
<property name="pos"></property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox">OnClearSelection</event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
......
......@@ -42,6 +42,7 @@ class DIALOG_TEARDROPS_BASE : public DIALOG_SHIM
wxRadioButton* m_tracksAll;
wxRadioButton* m_tracksSelected;
wxCheckBox* m_checkIgnore;
wxCheckBox* m_checkClear;
wxStaticText* m_staticStyle;
wxChoice* m_choiceStyle;
wxCheckBox* m_scopeVias;
......@@ -57,6 +58,7 @@ class DIALOG_TEARDROPS_BASE : public DIALOG_SHIM
virtual void OnModeRemove( wxCommandEvent& event ) { event.Skip(); }
virtual void OnTracksAll( wxCommandEvent& event ) { event.Skip(); }
virtual void OnTracksSelected( wxCommandEvent& event ) { event.Skip(); }
virtual void OnClearSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnStyleChanged( wxCommandEvent& event ) { event.Skip(); }
virtual void OnScopeVias( wxCommandEvent& event ) { event.Skip(); }
......
#include "edit_teardrops.h"
#include "class_board.h"
TEARDROPS_EDITOR::TEARDROPS_EDITOR(PCB_EDIT_FRAME *frame, KIGFX::VIEW *view)
{
m_frame = frame;
m_view = view;
}
void TEARDROPS_EDITOR::FilterSelection(SELECTION &selection)
{
EDA_ITEM *item = NULL;
for (size_t i = 0; i < selection.items.GetCount(); i++) {
item = selection.items.GetPickedItem(i);
if ((item != NULL) && (item->Type() != PCB_TRACE_T)) {
selection.items.RemovePicker(i);
}
}
}
bool TEARDROPS_EDITOR::EditTeardrops(SELECTION &selection, const DIALOG_TEARDROPS::TEARDROPS_SETTINGS &settings)
{
bool retVal = false;
switch (settings.m_type) {
case DIALOG_TEARDROPS::TEARDROPS_TYPE_CURVED:
m_type = TEARDROP::TEARDROP_CURVED;
break;
default:
m_type = TEARDROP::TEARDROP_STRAIGHT;
}
FilterSelection(selection);
if (settings.m_mode == DIALOG_TEARDROPS::TEARDROPS_MODE_ADD) {
if (settings.m_track == DIALOG_TEARDROPS::TEARDROPS_TRACKS_ALL) {
retVal = AddToAll(settings);
}
else if (settings.m_track == DIALOG_TEARDROPS::TEARDROPS_TRACKS_SELECTED) {
retVal = AddToSelected(selection, settings);
}
}
else if (settings.m_mode == DIALOG_TEARDROPS::TEARDROPS_MODE_REMOVE) {
// TODO: consider using TRACKS_CLEARNER to remove teardrops
}
return retVal;
}
bool TEARDROPS_EDITOR::AddToAll(const DIALOG_TEARDROPS::TEARDROPS_SETTINGS &settings)
{
bool retVal = false;
return retVal;
}
bool TEARDROPS_EDITOR::AddToSelected(SELECTION &selection, const DIALOG_TEARDROPS::TEARDROPS_SETTINGS &settings)
{
bool retVal = false;
for (size_t i = 0; i < selection.items.GetCount(); i++) {
TRACK *track = static_cast<TRACK *>(selection.items.GetPickedItem(i));
TEARDROP teardropEnd;
retVal = teardropEnd.Create(*track, ENDPOINT_END, m_type);
if (retVal == true) {
DrawSegments(teardropEnd, *track);
}
TEARDROP teardropStart;
retVal = teardropStart.Create(*track, ENDPOINT_START, m_type);
if (retVal == true) {
DrawSegments(teardropStart, *track);
}
if (settings.m_clearSelection == true) {
track->ClearSelected();
}
}
return retVal;
}
void TEARDROPS_EDITOR::DrawSegments(TEARDROP &teardrop, TRACK &aTrack)
{
std::vector<VECTOR2I> coordinates;
teardrop.GetCoordinates(coordinates);
BOARD *board = aTrack.GetBoard();
wxPoint currentPoint(0, 0);
wxPoint prevPoint(coordinates[0].x, coordinates[0].y);
for (size_t i = 1; i < coordinates.size(); i++) {
TRACK *track = new TRACK(aTrack);
track->SetWidth(aTrack.GetWidth());
track->SetLayer(aTrack.GetLayer());
track->SetNetCode(aTrack.GetNetCode());
currentPoint.x = coordinates[i].x;
currentPoint.y = coordinates[i].y;
track->SetStart(prevPoint);
track->SetEnd(currentPoint);
track->ClearFlags();
board->Add(track);
m_view->Add(track);
prevPoint = currentPoint;
}
}
#ifndef TEARDROPS_EDITOR_H
#define TEARDROPS_EDITOR_H
#include "wxPcbStruct.h"
#include "tools/selection_tool.h"
#include "dialogs/dialog_teardrops.h"
#include "class_teardrop.h"
class TEARDROPS_EDITOR
{
public:
TEARDROPS_EDITOR(PCB_EDIT_FRAME *frame, KIGFX::VIEW *view);
bool EditTeardrops(SELECTION &selection, const DIALOG_TEARDROPS::TEARDROPS_SETTINGS &settings);
private:
PCB_EDIT_FRAME *m_frame;
KIGFX::VIEW *m_view;
TEARDROP::TEARDROP_TYPE m_type;
void FilterSelection(SELECTION &selection);
bool AddToAll(const DIALOG_TEARDROPS::TEARDROPS_SETTINGS &settings);
bool AddToSelected(SELECTION &selection, const DIALOG_TEARDROPS::TEARDROPS_SETTINGS &settings);
void DrawSegments(TEARDROP &teardrop, TRACK &track);
};
#endif // TEARDROPS_EDITOR_H
......@@ -66,10 +66,12 @@
#include <worksheet_viewitem.h>
#include <ratsnest_data.h>
#include <ratsnest_viewitem.h>
#include <edit_teardrops.h>
#include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h>
#include <tools/common_actions.h>
#include <tools/selection_tool.h>
#include <scripting/python_console_frame.h>
......@@ -730,20 +732,13 @@ void PCB_EDIT_FRAME::ShowTeardropsEditor( wxCommandEvent& event )
{
DIALOG_TEARDROPS::TEARDROPS_SETTINGS settings;
DIALOG_TEARDROPS *dlg_teardrops = new DIALOG_TEARDROPS(this, &settings);
int retVal = dlg_teardrops->ShowModal();
int retVal = dlg_teardrops->ShowModal();
if (retVal == wxID_OK) {
SELECTION selection = m_toolManager->GetTool<SELECTION_TOOL>()->GetSelection();
TEARDROPS_EDITOR editor(this, GetGalCanvas()->GetView());
editor.EditTeardrops(selection, settings);
}
// BOARD_ITEM *item = GetScreen()->GetCurItem();
// if ((item != NULL) && (item->Type() == PCB_TRACE_T)) {
// TEARDROP *td = new TEARDROP(item);
// TRACK *track = static_cast<TRACK *>(item);
// td->Create(*track, ENDPOINT_START, TEARDROP::TEARDROP_CURVED);
// td->Create(*track, ENDPOINT_END, TEARDROP::TEARDROP_CURVED);
// }
// m_canvas->Refresh();
}
void PCB_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment