mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Compare commits
2 Commits
f20f3d3819
...
266e5cbbd5
Author | SHA1 | Date | |
---|---|---|---|
|
266e5cbbd5 | ||
|
59ea32eef6 |
@ -172,6 +172,17 @@ void CONNECTIVITY_DATA::Move( const VECTOR2I& aDelta )
|
||||
} );
|
||||
}
|
||||
|
||||
void CONNECTIVITY_DATA::Rotate( const VECTOR2I& aCenter, EDA_ANGLE rot )
|
||||
{
|
||||
m_connAlgo->ForEachAnchor(
|
||||
[&aCenter, rot]( CN_ANCHOR& anchor )
|
||||
{
|
||||
VECTOR2I v = anchor.Pos();
|
||||
RotatePoint( v, aCenter, rot );
|
||||
anchor.SetPos( v );
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
void CONNECTIVITY_DATA::updateRatsnest()
|
||||
{
|
||||
|
@ -138,6 +138,7 @@ public:
|
||||
* @param aDelta vector for movement of the tree
|
||||
*/
|
||||
void Move( const VECTOR2I& aDelta );
|
||||
void Rotate( const VECTOR2I& aCenter, EDA_ANGLE rot );
|
||||
|
||||
/**
|
||||
* Function Clear()
|
||||
|
@ -76,6 +76,8 @@ public:
|
||||
|
||||
const VECTOR2I& Pos() const { return m_pos; }
|
||||
|
||||
void SetPos( const VECTOR2I& aPos ) { m_pos = aPos; }
|
||||
|
||||
void Move( const VECTOR2I& aPos )
|
||||
{
|
||||
m_pos += aPos;
|
||||
|
@ -28,6 +28,9 @@
|
||||
|
||||
#include "pns_component_dragger.h"
|
||||
#include "pns_debug_decorator.h"
|
||||
#include <geometry/shape.h>
|
||||
#include <geometry/shape_simple.h>
|
||||
#include <geometry/shape_rect.h>
|
||||
|
||||
namespace PNS
|
||||
{
|
||||
@ -152,6 +155,107 @@ bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
|
||||
return true;
|
||||
}
|
||||
|
||||
bool COMPONENT_DRAGGER::Transform( const VECTOR2I& aP, const EDA_ANGLE& rot )
|
||||
{
|
||||
assert( m_world );
|
||||
|
||||
m_world->KillChildren();
|
||||
m_currentNode = m_world->Branch();
|
||||
|
||||
for( ITEM* item : m_initialDraggedItems )
|
||||
m_currentNode->Remove( item );
|
||||
|
||||
m_draggedItems.Clear();
|
||||
|
||||
for( SOLID* s : m_solids )
|
||||
{
|
||||
std::unique_ptr<SOLID> snew( static_cast<SOLID*>( s->Clone() ) );
|
||||
|
||||
// SH_RECT can't be rotated with arbitrary angles, SH_SIMPLE can
|
||||
if( snew->Shape( 0 )->Type() == SH_RECT )
|
||||
{
|
||||
snew->SetShape( new SHAPE_SIMPLE( snew->Hull() ) );
|
||||
}
|
||||
|
||||
snew->Rotate( rot, m_p0 );
|
||||
VECTOR2I p_next = aP - m_p0 + snew->Pos();
|
||||
snew->SetPos( p_next );
|
||||
m_draggedItems.Add( snew.get() );
|
||||
m_currentNode->Add( std::move( snew ) );
|
||||
|
||||
if( !s->IsRoutable() )
|
||||
continue;
|
||||
|
||||
for( DRAGGED_CONNECTION& l : m_conns )
|
||||
{
|
||||
if( l.attachedPad == s )
|
||||
{
|
||||
l.p_orig = s->Pos() + l.offset;
|
||||
l.p_next = p_next + l.offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( ITEM* item : m_fixedItems )
|
||||
{
|
||||
m_currentNode->Remove( item );
|
||||
|
||||
switch( item->Kind() )
|
||||
{
|
||||
case ITEM::SEGMENT_T:
|
||||
{
|
||||
SEGMENT* s = static_cast<SEGMENT*>( item );
|
||||
std::unique_ptr<SEGMENT> s_new( s->Clone() );
|
||||
|
||||
SEG orig = s->Seg();
|
||||
VECTOR2I endA = aP - m_p0 + orig.A;
|
||||
VECTOR2I endB = aP - m_p0 + orig.B;
|
||||
RotatePoint( endA, aP, rot );
|
||||
RotatePoint( endB, aP, rot );
|
||||
s_new->SetEnds( endA, endB );
|
||||
m_draggedItems.Add( s_new.get() );
|
||||
m_currentNode->Add( std::move( s_new ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ITEM::ARC_T:
|
||||
{
|
||||
ARC* a = static_cast<ARC*>( item );
|
||||
std::unique_ptr<ARC> a_new( a->Clone() );
|
||||
|
||||
SHAPE_ARC& arc = a_new->Arc();
|
||||
arc.Move( aP - m_p0 );
|
||||
arc.Rotate( rot, aP );
|
||||
|
||||
m_draggedItems.Add( a_new.get() );
|
||||
m_currentNode->Add( std::move( a_new ) );
|
||||
break;
|
||||
}
|
||||
|
||||
default: wxFAIL_MSG( wxT( "Unexpected item type in COMPONENT_DRAGGER::m_fixedItems" ) );
|
||||
}
|
||||
}
|
||||
|
||||
for( COMPONENT_DRAGGER::DRAGGED_CONNECTION& cn : m_conns )
|
||||
{
|
||||
LINE l_new( cn.origLine );
|
||||
l_new.Unmark();
|
||||
l_new.ClearLinks();
|
||||
l_new.DragCorner( cn.p_next, cn.origLine.CLine().Find( cn.p_orig ) );
|
||||
|
||||
PNS_DBG( Dbg(), AddItem, &l_new, BLUE, 0, wxT( "cdrag-new-fanout" ) );
|
||||
m_draggedItems.Add( l_new );
|
||||
|
||||
LINE l_orig( cn.origLine );
|
||||
m_currentNode->Remove( l_orig );
|
||||
m_currentNode->Add( l_new );
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool COMPONENT_DRAGGER::Drag( const VECTOR2I& aP )
|
||||
{
|
||||
|
@ -59,6 +59,16 @@ public:
|
||||
*/
|
||||
bool Drag( const VECTOR2I& aP ) override;
|
||||
|
||||
/**
|
||||
* Function Transform()
|
||||
*
|
||||
* Drags the current item(s) to the point aP and rotates them around aP by the given angle.
|
||||
* Currently only overridden in pns_component_dragger, default implementation just drags.
|
||||
* @return true, if transformation finished with success.
|
||||
*/
|
||||
|
||||
bool Transform( const VECTOR2I& aP, const EDA_ANGLE& rot ) override;
|
||||
|
||||
/**
|
||||
* Function FixRoute()
|
||||
*
|
||||
|
@ -79,6 +79,16 @@ public:
|
||||
*/
|
||||
virtual bool Drag( const VECTOR2I& aP ) = 0;
|
||||
|
||||
/**
|
||||
* Function Transform()
|
||||
*
|
||||
* Drags the current item(s) to the point aP and rotates them around aP by the given angle.
|
||||
* Currently only overridden in pns_component_dragger, default implementation just drags.
|
||||
* @return true, if transformation finished with success.
|
||||
*/
|
||||
|
||||
virtual bool Transform( const VECTOR2I& aP, const EDA_ANGLE& rot ) { return Drag( aP ); };
|
||||
|
||||
/**
|
||||
* Function FixRoute()
|
||||
*
|
||||
|
@ -736,7 +736,6 @@ bool DRAGGER::FixRoute( bool aForceCommit )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool DRAGGER::Drag( const VECTOR2I& aP )
|
||||
{
|
||||
m_mouseTrailTracer.AddTrailPoint( aP );
|
||||
|
@ -128,6 +128,11 @@ void HOLE::Move( const VECTOR2I& delta )
|
||||
}
|
||||
|
||||
|
||||
void HOLE::Rotate( const VECTOR2I& center, const EDA_ANGLE& rot )
|
||||
{
|
||||
m_holeShape->Rotate( rot, center );
|
||||
}
|
||||
|
||||
HOLE* HOLE::MakeCircularHole( const VECTOR2I& pos, int radius, PNS_LAYER_RANGE aLayers )
|
||||
{
|
||||
SHAPE_CIRCLE* circle = new SHAPE_CIRCLE( pos, radius );
|
||||
|
@ -86,6 +86,7 @@ public:
|
||||
void SetRadius( int aRadius );
|
||||
|
||||
void Move( const VECTOR2I& delta );
|
||||
void Rotate( const VECTOR2I& center, const EDA_ANGLE& rot );
|
||||
|
||||
static HOLE* MakeCircularHole( const VECTOR2I& pos, int radius, PNS_LAYER_RANGE aLayers );
|
||||
|
||||
|
@ -2063,11 +2063,18 @@ void PNS_KICAD_IFACE::modifyBoardItem( PNS::ITEM* aItem )
|
||||
{
|
||||
PAD* pad = static_cast<PAD*>( aItem->Parent() );
|
||||
VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
|
||||
EDA_ANGLE rot = static_cast<PNS::SOLID*>( aItem )->GetOrientation();
|
||||
|
||||
// Don't add to commit; we'll add the parent footprints when processing the m_fpOffsets
|
||||
|
||||
FOOTPRINT* fp = pad->GetParentFootprint();
|
||||
EDA_ANGLE oldr = fp->GetOrientation();
|
||||
fp->SetOrientation( rot );
|
||||
m_fpOffsets[pad].p_old = pad->GetPosition();
|
||||
fp->SetOrientation( oldr );
|
||||
m_fpOffsets[pad].p_new = pos;
|
||||
m_fpOffsets[pad].r_old = pad->GetOrientation();
|
||||
m_fpOffsets[pad].r_new = rot;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2226,13 +2233,16 @@ void PNS_KICAD_IFACE::Commit()
|
||||
FOOTPRINT* footprint = pad->GetParentFootprint();
|
||||
VECTOR2I p_orig = footprint->GetPosition();
|
||||
VECTOR2I p_new = p_orig + offset;
|
||||
|
||||
EDA_ANGLE roffs = fpOffset.r_new - fpOffset.r_old;
|
||||
EDA_ANGLE r_orig = footprint->GetOrientation();
|
||||
EDA_ANGLE r_new = r_orig + roffs;
|
||||
if( processedFootprints.find( footprint ) != processedFootprints.end() )
|
||||
continue;
|
||||
|
||||
processedFootprints.insert( footprint );
|
||||
m_commit->Modify( footprint );
|
||||
footprint->SetPosition( p_new );
|
||||
footprint->SetOrientation( r_new );
|
||||
}
|
||||
|
||||
m_fpOffsets.clear();
|
||||
|
@ -173,6 +173,7 @@ protected:
|
||||
struct OFFSET
|
||||
{
|
||||
VECTOR2I p_old, p_new;
|
||||
EDA_ANGLE r_old, r_new;
|
||||
};
|
||||
|
||||
std::map<PAD*, OFFSET> m_fpOffsets;
|
||||
|
@ -488,6 +488,24 @@ bool ROUTER::Move( const VECTOR2I& aP, ITEM* endItem )
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ROUTER::Transform( const VECTOR2I& aP, const EDA_ANGLE& rot, ITEM* endItem )
|
||||
{
|
||||
if( m_logger )
|
||||
m_logger->Log( LOGGER::EVT_MOVE, aP, endItem );
|
||||
|
||||
switch( m_state )
|
||||
{
|
||||
case ROUTE_TRACK: return movePlacing( aP, endItem );
|
||||
case DRAG_SEGMENT:
|
||||
case DRAG_COMPONENT: return rotDragging( aP, rot, endItem );
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
GetRuleResolver()->ClearTemporaryCaches();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ROUTER::GetNearestRatnestAnchor( VECTOR2I& aOtherEnd, PNS_LAYER_RANGE& aOtherEndLayers,
|
||||
ITEM*& aOtherEndItem )
|
||||
@ -640,6 +658,19 @@ bool ROUTER::moveDragging( const VECTOR2I& aP, ITEM* aEndItem )
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ROUTER::rotDragging( const VECTOR2I& aP, const EDA_ANGLE& rot, ITEM* aEndItem )
|
||||
{
|
||||
m_iface->EraseView();
|
||||
|
||||
bool ret = m_dragger->Transform( aP, rot );
|
||||
ITEM_SET dragged = m_dragger->Traces();
|
||||
|
||||
m_leaderSegments = m_dragger->GetLastCommittedLeaderSegments();
|
||||
|
||||
updateView( m_dragger->CurrentNode(), dragged, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void ROUTER::markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved )
|
||||
{
|
||||
|
@ -161,6 +161,7 @@ public:
|
||||
bool RoutingInProgress() const;
|
||||
bool StartRouting( const VECTOR2I& aP, ITEM* aItem, int aLayer );
|
||||
bool Move( const VECTOR2I& aP, ITEM* aItem );
|
||||
bool Transform( const VECTOR2I& aP, const EDA_ANGLE& rot, ITEM* aItem );
|
||||
bool Finish();
|
||||
bool ContinueFromEnd( ITEM** aNewStartItem );
|
||||
bool FixRoute( const VECTOR2I& aP, ITEM* aItem, bool aForceFinish, bool aForceCommit );
|
||||
@ -241,6 +242,7 @@ public:
|
||||
private:
|
||||
bool movePlacing( const VECTOR2I& aP, ITEM* aItem );
|
||||
bool moveDragging( const VECTOR2I& aP, ITEM* aItem );
|
||||
bool rotDragging( const VECTOR2I& aP, const EDA_ANGLE& rot, ITEM* aItem );
|
||||
|
||||
void updateView( NODE* aNode, ITEM_SET& aCurrent, bool aDragging = false );
|
||||
|
||||
|
@ -77,6 +77,21 @@ ITEM* SOLID::Clone() const
|
||||
return solid;
|
||||
}
|
||||
|
||||
void SOLID::Rotate( const EDA_ANGLE& a, const VECTOR2I& center )
|
||||
{
|
||||
if( m_shape )
|
||||
{
|
||||
m_shape->Rotate( a, center );
|
||||
RotatePoint( m_pos, center, a );
|
||||
}
|
||||
|
||||
if( m_hole )
|
||||
{
|
||||
m_hole->Rotate( center, a );
|
||||
}
|
||||
|
||||
m_orientation = ( m_orientation + a );
|
||||
}
|
||||
|
||||
void SOLID::SetPos( const VECTOR2I& aCenter )
|
||||
{
|
||||
|
@ -136,6 +136,8 @@ public:
|
||||
EDA_ANGLE GetOrientation() const { return m_orientation; }
|
||||
void SetOrientation( const EDA_ANGLE& aOrientation ) { m_orientation = aOrientation; }
|
||||
|
||||
void Rotate( const EDA_ANGLE& aOrientation, const VECTOR2I& center );
|
||||
|
||||
virtual void SetHole( HOLE* aHole ) override
|
||||
{
|
||||
if( m_hole && m_hole->BelongsTo( this ) )
|
||||
|
@ -2377,6 +2377,8 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||
|
||||
bool hasMouseMoved = false;
|
||||
bool hasMultidragCancelled = false;
|
||||
EDA_ANGLE rot = EDA_ANGLE( 0.0 );
|
||||
EDA_ANGLE rotationAngle = getEditFrame<PCB_BASE_EDIT_FRAME>()->GetRotationAngle();
|
||||
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
@ -2391,11 +2393,19 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||
|
||||
break;
|
||||
}
|
||||
else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
|
||||
else if( evt->IsMotion() || evt->IsAction( &PCB_ACTIONS::rotateCw )
|
||||
|| evt->IsAction( &PCB_ACTIONS::rotateCcw ) )
|
||||
{
|
||||
// passing rotation angles >360 or <-360 to downstream functions does not seem to cause problems
|
||||
if( evt->IsAction( &PCB_ACTIONS::rotateCw ) )
|
||||
rot = rot - rotationAngle;
|
||||
|
||||
if( evt->IsAction( &PCB_ACTIONS::rotateCcw ) )
|
||||
rot = rot + rotationAngle;
|
||||
|
||||
hasMouseMoved = true;
|
||||
updateEndItem( *evt );
|
||||
m_router->Move( m_endSnapPoint, m_endItem );
|
||||
m_router->Transform( m_endSnapPoint, EDA_ANGLE( rot ), m_endItem );
|
||||
|
||||
view()->ClearPreview();
|
||||
|
||||
@ -2403,6 +2413,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
VECTOR2I offset = m_endSnapPoint - p;
|
||||
BOARD_ITEM* previewItem;
|
||||
VECTOR2I center = m_endSnapPoint;
|
||||
|
||||
for( FOOTPRINT* footprint : footprints )
|
||||
{
|
||||
@ -2410,6 +2421,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
previewItem = static_cast<BOARD_ITEM*>( drawing->Clone() );
|
||||
previewItem->Move( offset );
|
||||
previewItem->Rotate( center, rot );
|
||||
|
||||
view()->AddToPreview( previewItem );
|
||||
view()->Hide( drawing, true );
|
||||
@ -2422,6 +2434,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
previewItem = static_cast<BOARD_ITEM*>( pad->Clone() );
|
||||
previewItem->Move( offset );
|
||||
previewItem->Rotate( center, rot );
|
||||
|
||||
view()->AddToPreview( previewItem );
|
||||
}
|
||||
@ -2435,16 +2448,21 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||
|
||||
previewItem = static_cast<BOARD_ITEM*>( footprint->Reference().Clone() );
|
||||
previewItem->Move( offset );
|
||||
previewItem->Rotate( center, rot );
|
||||
view()->AddToPreview( previewItem );
|
||||
view()->Hide( &footprint->Reference() );
|
||||
|
||||
previewItem = static_cast<BOARD_ITEM*>( footprint->Value().Clone() );
|
||||
previewItem->Move( offset );
|
||||
previewItem->Rotate( center, rot );
|
||||
view()->AddToPreview( previewItem );
|
||||
view()->Hide( &footprint->Value() );
|
||||
|
||||
if( showCourtyardConflicts )
|
||||
{
|
||||
footprint->Move( offset );
|
||||
footprint->Rotate( center, rot );
|
||||
}
|
||||
}
|
||||
|
||||
if( showCourtyardConflicts )
|
||||
@ -2453,11 +2471,21 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||
courtyardClearanceDRC.UpdateConflicts( getView(), false );
|
||||
|
||||
for( FOOTPRINT* footprint : footprints )
|
||||
{
|
||||
footprint->Rotate( center, -rot );
|
||||
footprint->Move( -offset );
|
||||
}
|
||||
}
|
||||
|
||||
// Update ratsnest
|
||||
dynamicData->Move( offset - lastOffset );
|
||||
|
||||
if( evt->IsAction( &PCB_ACTIONS::rotateCw ) )
|
||||
dynamicData->Rotate( center, -getEditFrame<PCB_BASE_EDIT_FRAME>()->GetRotationAngle() );
|
||||
|
||||
if( evt->IsAction( &PCB_ACTIONS::rotateCcw ) )
|
||||
dynamicData->Rotate( center, getEditFrame<PCB_BASE_EDIT_FRAME>()->GetRotationAngle() );
|
||||
|
||||
lastOffset = offset;
|
||||
connectivityData->ComputeLocalRatsnest( dynamicItems, dynamicData.get(), offset );
|
||||
}
|
||||
@ -2494,6 +2522,9 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||
|
||||
break;
|
||||
}
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
}
|
||||
else if( evt->IsUndoRedo() )
|
||||
{
|
||||
// We're in an UndoRedoBlock. If we get here, something's broken.
|
||||
|
Loading…
x
Reference in New Issue
Block a user