42constexpr int MM = 1000000;
49 KI_TEST::DUMMY_TOOL* tool;
51 DRAG_FIXTURE() : tool( new KI_TEST::DUMMY_TOOL() )
53 mgr.SetEnvironment( &board,
nullptr,
nullptr,
nullptr,
nullptr );
54 mgr.RegisterTool( tool );
92 PCB_SHAPE*
addPoly(
const std::vector<VECTOR2I>& aPoints )
100 PCB_CONSTRAINT* addCoincident( PCB_SHAPE* aA,
CONSTRAINT_ANCHOR aAnchorA, PCB_SHAPE* aB,
116 std::vector<PCB_SHAPE*>* aModified )
123 aShape->
SetEnd( aCursor );
146 const VECTOR2I bStart0 = b->GetStart();
148 std::vector<PCB_SHAPE*> modified;
154 BOOST_CHECK_LE( ( a->
GetEnd() - b->GetStart() ).EuclideanNorm(), 100 );
155 BOOST_CHECK( std::find( modified.begin(), modified.end(), b ) != modified.end() );
156 BOOST_CHECK( a->
GetEnd() != aEnd0 );
177 std::vector<PCB_SHAPE*> modified;
183 BOOST_CHECK_LE( ( a->
GetCenter() - b->GetCenter() ).EuclideanNorm(), 2000 );
184 BOOST_CHECK( std::find( modified.begin(), modified.end(), b ) != modified.end() );
204 const VECTOR2I bStart0 = b->GetStart();
207 std::vector<PCB_SHAPE*> modified;
212 BOOST_CHECK( modified.empty() );
235 BOOST_REQUIRE_EQUAL( board.
Constraints().size(), 1 );
239 commit.
Push( wxT(
"delete segment" ) );
242 BOOST_REQUIRE_EQUAL( board.
Constraints().size(), 1 );
244 BOOST_REQUIRE_EQUAL( survivor->
GetMembers().size(), 2 );
246 bool referencesDeleted =
false;
250 if( m.m_item == aId )
251 referencesDeleted =
true;
254 BOOST_CHECK( referencesDeleted );
255 BOOST_CHECK( board.
ResolveItem( aId,
true ) ==
nullptr );
279 seg->Move( { 0, 3 *
MM } );
282 std::vector<PCB_SHAPE*> modified;
286 BOOST_CHECK_LE(
std::abs( seg->GetEnd().y ), 5000 );
287 BOOST_CHECK_LE( ( seg->GetStart() -
VECTOR2I( 2 *
MM, 8 *
MM ) ).EuclideanNorm(), 5000.0 );
290 BOOST_CHECK( std::find( modified.begin(), modified.end(), seg ) != modified.end() );
305 const VECTOR2I bStart0 = b->GetStart();
310 std::vector<PCB_SHAPE*> modified;
319 BOOST_CHECK_LE( ( a->
GetEnd() - b->GetStart() ).EuclideanNorm(), 100 );
320 BOOST_CHECK( b->GetStart() != bStart0 );
340 const VECTOR2I bStart0 = b->GetStart();
343 std::vector<PCB_SHAPE*> modified;
350 BOOST_CHECK( modified.empty() );
352 BOOST_CHECK( commit.
Empty() );
365 len->SetValue( 10.0 *
MM );
370 std::vector<PCB_SHAPE*> modified;
378 BOOST_CHECK_LE( ( seg->
GetStart() - start0 ).EuclideanNorm(), 5000.0 );
382 BOOST_CHECK_LE( ( seg->
GetEnd() -
VECTOR2I( 6 *
MM, 8 *
MM ) ).EuclideanNorm(), 20000.0 );
396 len->SetValue( 10.0 *
MM );
401 std::vector<PCB_SHAPE*> modified;
407 BOOST_CHECK_LE( ( seg->
GetStart() - start0 ).EuclideanNorm(), 5000.0 );
409 BOOST_CHECK_LE( ( seg->
GetEnd() -
VECTOR2I( 10 *
MM, 0 ) ).EuclideanNorm(), 20000.0 );
419 PCB_SHAPE* arc = addArc( { 10 *
MM, 0 }, { 7071068, 7071068 }, { 0, 10 *
MM } );
429 std::vector<PCB_SHAPE*> modified;
434 BOOST_CHECK_LE( ( arc->
GetCenter() - center0 ).EuclideanNorm(), 20000.0 );
436 BOOST_CHECK_LE( ( arc->
GetEnd() - end0 ).EuclideanNorm(), 20000.0 );
437 BOOST_CHECK( ( arc->
GetStart() -
VECTOR2I( 10 *
MM, 0 ) ).EuclideanNorm() > 20000.0 );
445 PCB_SHAPE* arc = addArc( { 10 *
MM, 0 }, { 7071068, 7071068 }, { 0, 10 *
MM } );
449 r->SetValue( 12.0 *
MM );
452 std::vector<PCB_SHAPE*> modified;
479 std::vector<PCB_SHAPE*> modified;
490 BOOST_CHECK_LE( (
VECTOR2I( br.
x, tl.y ) -
cursor ).EuclideanNorm(), 5000.0 );
491 BOOST_CHECK_LE( ( seg->GetStart() -
cursor ).EuclideanNorm(), 5000.0 );
494 BOOST_CHECK_LE( (
VECTOR2I( tl.x, br.
y ) -
VECTOR2I( 0, 10 *
MM ) ).EuclideanNorm(), 5000.0 );
502 const std::vector<VECTOR2I> points{ { 0, 0 },
506 { -3 *
MM, 8 *
MM } };
519 std::vector<PCB_SHAPE*> modified;
526 BOOST_REQUIRE_EQUAL( outline.PointCount(), 5 );
527 BOOST_CHECK_LE( ( outline.CPoint( 2 ) -
cursor ).EuclideanNorm(), 5000.0 );
529 for(
int i : { 0, 1, 3, 4 } )
530 BOOST_CHECK_LE( ( outline.CPoint( i ) - points[i] ).EuclideanNorm(), 5000.0 );
540 PCB_SHAPE* swapped = addRect( { 10 *
MM, 10 *
MM }, { 0, 0 } );
542 for(
PCB_SHAPE* shape : { rect, swapped } )
544 const std::vector<VECTOR2I> corners{ { 0, 0 },
546 { 10 *
MM, 10 *
MM },
549 for(
size_t i = 0; i < corners.size(); ++i )
556 BOOST_CHECK( vertex->pos == corners[i] );
573 const std::vector<VECTOR2I> points{ { 0, 0 },
577 { -3 *
MM, 8 *
MM } };
581 for(
size_t i = 0; i < points.size(); ++i )
588 BOOST_CHECK( vertex->pos == points[i] );
600 chain.SetClosed(
true );
603 board.
Add( arcPoly );
632 BOOST_CHECK( vertex->pos ==
cursor );
634 std::vector<PCB_SHAPE*> modified;
636 SolveCluster( &board, { rect->
m_Uuid, vertex->anchor, vertex->index }, vertex->pos, &modified,
639 BOOST_CHECK_LE( ( seg->GetStart() -
cursor ).EuclideanNorm(), 5000.0 );
658 const int minWidth = 25400;
659 const VECTOR2I clamped( minWidth, rawCursor.
y );
667 BOOST_CHECK( vertex->pos == clamped );
668 BOOST_CHECK( vertex->pos != rawCursor );
670 std::vector<PCB_SHAPE*> modified;
672 SolveCluster( &board, { rect->
m_Uuid, vertex->anchor, vertex->index }, vertex->pos, &modified,
675 BOOST_CHECK_LE( ( seg->GetStart() - clamped ).EuclideanNorm(), 5000.0 );
715 addDrivingVertexLength( board, rect, 0, 1, 10.0 *
MM );
724 BOOST_CHECK( corner->pos ==
VECTOR2I( 15 *
MM, 0 ) );
726 std::vector<PCB_SHAPE*> modified;
728 SolveCluster( &board, { rect->
m_Uuid, corner->anchor, corner->index }, corner->pos, &modified,
731 const VECTOR2I tl = dragRectTopLeft( rect );
732 const VECTOR2I br = dragRectBotRight( rect );
735 BOOST_CHECK_LE(
std::abs( ( br.
x - tl.x ) - 10 *
MM ), 20000 );
736 BOOST_CHECK_LE(
std::abs( ( br.
y - tl.y ) - 10 *
MM ), 20000 );
739 BOOST_CHECK_GT( tl.x, 1 *
MM );
740 BOOST_CHECK_LT( br.
x, 14 *
MM );
742 BOOST_TEST_MESSAGE(
"side drag under driving width settled TL at " << tl.x <<
"," << tl.y );
747 BOOST_REQUIRE_EQUAL( corners.size(), 4 );
759 addDrivingVertexLength( board, rect, 0, 1, 10.0 *
MM );
767 BOOST_CHECK( corner->pos ==
VECTOR2I( 10 *
MM, 15 *
MM ) );
769 std::vector<PCB_SHAPE*> modified;
771 SolveCluster( &board, { rect->
m_Uuid, corner->anchor, corner->index }, corner->pos, &modified,
774 const VECTOR2I tl = dragRectTopLeft( rect );
775 const VECTOR2I br = dragRectBotRight( rect );
777 BOOST_CHECK_LE( tl.EuclideanNorm(), 5000.0 );
778 BOOST_CHECK_LE(
std::abs( ( br.
x - tl.x ) - 10 *
MM ), 5000 );
779 BOOST_CHECK_LE(
std::abs( ( br.
y - tl.y ) - 15 *
MM ), 5000 );
801 std::vector<PCB_SHAPE*> modified;
803 SolveCluster( &board, { rect->
m_Uuid, corner->anchor, corner->index }, corner->pos, &modified,
806 BOOST_CHECK_LE( dragRectTopLeft( rect ).EuclideanNorm(), 5000.0 );
807 BOOST_CHECK_LE( ( dragRectBotRight( rect ) -
VECTOR2I( 15 *
MM, 10 *
MM ) ).EuclideanNorm(), 5000.0 );
808 BOOST_CHECK_LE( seg->GetStart().EuclideanNorm(), 5000.0 );
816 const std::vector<VECTOR2I> points{ { 0, 0 },
820 { -3 *
MM, 8 *
MM } };
823 const double edgeLen = std::hypot( 3.0, 8.0 ) *
MM;
825 addDrivingVertexLength( board, poly, 1, 2, edgeLen );
828 std::vector<VECTOR2I> dragged = points;
829 dragged[1] = { 8 *
MM, -2 *
MM };
830 dragged[2] = { 16 *
MM, 9 *
MM };
833 std::vector<PCB_SHAPE*> modified;
842 double solvedLen = ( outline.CPoint( 2 ) - outline.CPoint( 1 ) ).EuclideanNorm();
844 BOOST_CHECK_LE(
std::abs( solvedLen - edgeLen ), 20000.0 );
848 const VECTOR2I midBefore = ( points[1] + points[2] ) / 2;
849 const VECTOR2I midTarget = ( dragged[1] + dragged[2] ) / 2;
850 const VECTOR2I midSolved = ( outline.CPoint( 1 ) + outline.CPoint( 2 ) ) / 2;
852 BOOST_CHECK_LT( ( midSolved - midTarget ).EuclideanNorm(), ( midBefore - midTarget ).EuclideanNorm() );
853 BOOST_CHECK_GT( ( midSolved - midBefore ).EuclideanNorm(), 250000.0 );
855 for(
int i : { 0, 3, 4 } )
856 BOOST_CHECK_LE( ( outline.CPoint( i ) - points[i] ).EuclideanNorm(), 5000.0 );
864 const std::vector<VECTOR2I> points{ { 0, 0 },
868 { -3 *
MM, 8 *
MM } };
879 std::vector<VECTOR2I> dragged = points;
884 std::vector<PCB_SHAPE*> modified;
893 BOOST_CHECK_LE( ( outline.CPoint( 1 ) - dragged[1] ).EuclideanNorm(), 5000.0 );
894 BOOST_CHECK_LE( ( outline.CPoint( 2 ) - dragged[2] ).EuclideanNorm(), 5000.0 );
895 BOOST_CHECK_LE( ( seg->
GetStart() - dragged[1] ).EuclideanNorm(), 5000.0 );
896 BOOST_CHECK( std::find( modified.begin(), modified.end(), seg ) != modified.end() );
898 for(
int i : { 0, 3, 4 } )
899 BOOST_CHECK_LE( ( outline.CPoint( i ) - points[i] ).EuclideanNorm(), 5000.0 );
906 PCB_SHAPE* arc = addArc( { 10 *
MM, 0 }, { 7071068, 7071068 }, { 0, 10 *
MM } );
913 std::vector<PCB_SHAPE*> modified;
918 BOOST_CHECK_LE( ( arc->
GetStart() - start0 ).EuclideanNorm(), 20000.0 );
919 BOOST_CHECK_LE( ( arc->
GetEnd() - end0 ).EuclideanNorm(), 20000.0 );
920 BOOST_CHECK( ( arc->
GetCenter() -
VECTOR2I( 0, 0 ) ).EuclideanNorm() > 100000.0 );
void ReSolveShapeClusters(BOARD *aBoard, const std::vector< PCB_SHAPE * > &aShapes, std::vector< PCB_SHAPE * > *aModified, const std::function< void(BOARD_ITEM *)> &aBeforeModify)
Re-solve the clusters of shapes edited outside the solver, e.g.
CONSTRAINT_DIAGNOSIS SolveCluster(BOARD *aBoard, const CONSTRAINT_MEMBER &aDragged, const VECTOR2I &aCursor, std::vector< PCB_SHAPE * > *aModified, const std::function< void(BOARD_ITEM *)> &aBeforeModify, bool aIncludeDragged, bool aStabilize, const std::set< KIID > &aEdited, const std::optional< std::pair< CONSTRAINT_MEMBER, VECTOR2I > > &aCoDragged)
Gather the cluster of shapes transitively constrained with the dragged shape, solve with the dragged ...
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
virtual void Revert() override
Revert the commit by restoring the modified items state.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Information pertinent to a Pcbnew printed circuit board.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
const CONSTRAINTS & Constraints() const
Geometric constraints (#2329) owned by this board.
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
void SetCenter(const VECTOR2I &aCenter)
SHAPE_POLY_SET & GetPolyShape()
virtual void SetBottom(int val)
virtual void SetTop(int val)
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
virtual void SetRight(int val)
A geometric constraint between board items (issue #2329).
const std::vector< CONSTRAINT_MEMBER > & GetMembers() const
void AddMember(const KIID &aItem, CONSTRAINT_ANCHOR aAnchor=CONSTRAINT_ANCHOR::WHOLE, int aIndex=-1)
void SetValue(std::optional< double > aValue)
void SetDriving(bool aDriving)
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
void SetEnd(const VECTOR2I &aEnd) override
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void SetStart(const VECTOR2I &aStart) override
void SetRadius(int aRadius)
void SetCenter(const VECTOR2I &aCenter)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
std::optional< CONSTRAINT_ANCHOR_POINT > ConstraintShapeVertex(const PCB_SHAPE *aShape, int aIndex)
VERTEX anchor at ordinal aIndex of a rectangle or eligible polygon or std::nullopt if the shape has n...
std::vector< CONSTRAINT_ANCHOR_POINT > ConstraintShapeAnchors(const PCB_SHAPE *aShape)
Enumerate a shape constraint anchors with positions segment and arc endpoints arc centre circle centr...
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
PCB_SHAPE * addPoly(BOARD &aBoard, const std::vector< VECTOR2I > &aPoints)
PCB_SHAPE * addArc(BOARD &aBoard, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
PCB_SHAPE * addCircle(BOARD &aBoard, const VECTOR2I &aCenter, int aRadius)
PCB_SHAPE * addRect(BOARD &aBoard, const VECTOR2I &aStart, const VECTOR2I &aEnd)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
CONSTRAINT_ANCHOR
Which feature of a referenced board item participates in a constraint.
@ VERTEX
An indexed rectangle corner or polygon outline vertex; pairs with CONSTRAINT_MEMBER::m_index.
@ WHOLE
The item as a whole (a segment as a line, a circle).
@ START
First endpoint of a segment or arc.
@ END
Second endpoint of a segment or arc.
@ CENTER
Center of an arc or circle.
@ CONCENTRIC
Two arcs/circles share a center.
@ FIXED_POSITION
A point is locked at its current location.
@ COINCIDENT
Two points are made to coincide.
@ FIXED_RADIUS
An arc/circle has a driving radius value.
@ POINT_ON_LINE
A point lies on a segment's supporting line.
@ FIXED_LENGTH
A segment has a driving length value.
static bool addSegment(VRML_LAYER &model, IDF_SEGMENT *seg, int icont, int iseg)
One participant in a constraint: a referenced board item plus the feature of that item that participa...
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_FIXTURE_TEST_CASE(DragReDerivesNeighborRevertRestores, DRAG_FIXTURE)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
static const long long MM
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
const SHAPE_LINE_CHAIN chain
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I