KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_constraint_apply.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
25
27
28#include <algorithm>
29
30#include <board.h>
31#include <pcb_shape.h>
32
35
37
38using namespace KI_TEST;
39
40
41BOOST_AUTO_TEST_SUITE( ConstraintApply )
42
43
44BOOST_AUTO_TEST_CASE( CoincidentSnapsSecondPointToFirst )
45{
46 BOARD board;
47
48 PCB_SHAPE* a = addSegment( board, { 0, 0 }, { 10 * MM, 0 } );
49 PCB_SHAPE* b = addSegment( board, { 11 * MM, 1 * MM }, { 20 * MM, 0 } );
50
51 // Bind a's END to b's START; pinning a's END should pull b's START onto it.
54 { b->m_Uuid, CONSTRAINT_ANCHOR::START } } );
55
56 std::vector<PCB_SHAPE*> modified;
57 CONSTRAINT_DIAGNOSIS diag = ApplyConstraintImmediately( &board, c, &modified );
58
59 BOOST_TEST( diag.solved );
60 BOOST_CHECK_EQUAL( a->GetEnd().x, 10 * MM ); // pinned, unmoved
61 BOOST_CHECK_EQUAL( a->GetEnd().y, 0 );
62 BOOST_CHECK_EQUAL( b->GetStart().x, 10 * MM ); // pulled onto a's END
63 BOOST_CHECK_EQUAL( b->GetStart().y, 0 );
64}
65
66
67BOOST_AUTO_TEST_CASE( SingleShapeFixedLengthStagesThePinnedShape )
68{
69 BOARD board;
70
71 // A 12mm segment driven to 8mm: pinning START keeps it put, END moves in. The pinned shape is
72 // the only shape, so it must be reported as modified (else the move would not be committed).
73 PCB_SHAPE* seg = addSegment( board, { 0, 0 }, { 12 * MM, 0 } );
75 { { seg->m_Uuid, CONSTRAINT_ANCHOR::WHOLE } },
76 8.0 * MM );
77
78 std::vector<PCB_SHAPE*> modified;
79 CONSTRAINT_DIAGNOSIS diag = ApplyConstraintImmediately( &board, c, &modified );
80
81 BOOST_TEST( diag.solved );
82 BOOST_TEST( ( std::find( modified.begin(), modified.end(), seg ) != modified.end() ) );
83 BOOST_CHECK_EQUAL( seg->GetStart().x, 0 );
84 BOOST_CHECK_EQUAL( seg->GetEnd().x, 8 * MM );
85}
86
87
88BOOST_AUTO_TEST_CASE( CircleFirstMemberPinsCenterAndSolves )
89{
90 BOARD board;
91
92 // Concentric circles authored as WHOLE members: WHOLE must pin the circle's CENTER (its only
93 // anchor), not a non-existent START, or the solve silently does nothing.
94 PCB_SHAPE* a = addCircle( board, { 0, 0 }, 5 * MM );
95 PCB_SHAPE* b = addCircle( board, { 3 * MM, 0 }, 2 * MM );
98 { b->m_Uuid, CONSTRAINT_ANCHOR::WHOLE } } );
99
100 std::vector<PCB_SHAPE*> modified;
101 CONSTRAINT_DIAGNOSIS diag = ApplyConstraintImmediately( &board, c, &modified );
102
103 BOOST_TEST( diag.solved );
104 BOOST_CHECK_EQUAL( a->GetCenter().x, 0 ); // pinned
105 BOOST_CHECK_EQUAL( b->GetCenter().x, 0 ); // moved concentric with a
106 BOOST_CHECK_EQUAL( b->GetCenter().y, 0 );
107}
108
109
110BOOST_AUTO_TEST_CASE( FailedOrEmptyClusterLeavesGeometry )
111{
112 BOARD board;
113
114 // A constraint with no members cannot pin or solve anything.
116
117 std::vector<PCB_SHAPE*> modified;
118 CONSTRAINT_DIAGNOSIS diag = ApplyConstraintImmediately( &board, &empty, &modified );
119
120 BOOST_TEST( !diag.solved );
121 BOOST_TEST( modified.empty() );
122}
123
124
CONSTRAINT_DIAGNOSIS ApplyConstraintImmediately(BOARD *aBoard, const PCB_CONSTRAINT *aConstraint, std::vector< PCB_SHAPE * > *aModified, const std::function< void(BOARD_ITEM *)> &aBeforeModify)
Solve a just-created constraint's cluster so the geometry snaps to satisfy it (SolidWorks-style),...
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:373
const KIID m_Uuid
Definition eda_item.h:531
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:240
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:190
A geometric constraint between board items (issue #2329).
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition pcb_shape.h:78
static bool empty(const wxTextEntryBase *aCtrl)
PCB_SHAPE * addSegment(BOARD &aBoard, const VECTOR2I &aStart, const VECTOR2I &aEnd)
PCB_SHAPE * addCircle(BOARD &aBoard, const VECTOR2I &aCenter, int aRadius)
constexpr int MM
PCB_CONSTRAINT * addConstraint(BOARD &aBoard, PCB_CONSTRAINT_TYPE aType, const std::vector< CONSTRAINT_MEMBER > &aMembers, std::optional< double > aValue=std::nullopt)
@ 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.
@ CONCENTRIC
Two arcs/circles share a center.
@ COINCIDENT
Two points are made to coincide.
@ FIXED_LENGTH
A segment has a driving length value.
The outcome of a constraint solve, in plain data so callers need not know planegcs.
bool solved
Solver reached Success or Converged.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(CoincidentSnapsSecondPointToFirst)
BOOST_AUTO_TEST_SUITE_END()
BOOST_TEST(netlist.find("R_G1 ARM_OUT1 DIE_B R='0.001 / ((SW_STATE)") !=std::string::npos)
BOOST_CHECK_EQUAL(result, "25.4")