KiCad PCB EDA Suite
Loading...
Searching...
No Matches
snap_resolver.h
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 3
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
20#ifndef SNAP_RESOLVER_H
21#define SNAP_RESOLVER_H
22
23#include <math/vector2d.h>
24#include <math/box2.h>
26
27#include <array>
28#include <cstdint>
29#include <chrono>
30#include <functional>
31#include <iosfwd>
32#include <optional>
33#include <string>
34#include <vector>
35
36
39constexpr double SNAP_SCREEN_RADIUS = 25.0;
40
43
44
55
56
65
66
80
81
100
101
111
112
113std::ostream& operator<<( std::ostream& aStream, SNAP_RESULT_STATUS aStatus );
114
115
140
141
142// Preserve source byte order: lexicographic ordering participates in stable ID construction.
143using SNAP_TARGET_ID = std::array<uint8_t, 16>;
144
145
147{
152
153 bool operator==( const SNAP_STABLE_ID& aOther ) const = default;
154 bool operator<( const SNAP_STABLE_ID& aOther ) const;
155};
156
157
158SNAP_STABLE_ID MakeDerivedSnapId( SNAP_ID_KIND aKind, const SNAP_STABLE_ID& aSource, int aFeatureIndex = 0,
159 int aSolutionBranch = 0 );
161 int aSolutionBranch );
162SNAP_STABLE_ID MakePointSnapId( SNAP_ID_KIND aKind, const VECTOR2I& aPoint, int aFeatureIndex = 0 );
163SNAP_STABLE_ID MakeCompositeSnapId( SNAP_ID_KIND aKind, const std::vector<SNAP_TARGET_ID>& aTargets,
164 int aFeatureIndex = 0 );
165
166
172
173
180
181
188
189
196
197
199{
202 std::optional<VECTOR2I> stationarySourceLeg;
203 std::vector<SNAP_STABLE_ID> movingFeatures;
204 std::vector<SNAP_STABLE_ID> stationarySelfFeatures;
205 std::optional<SNAP_STABLE_ID> movingItem;
206 std::optional<BOX2I> movingBounds;
207 // Reference point represented by the live bounds; inference projects them to sourcePoint.
208 std::optional<VECTOR2I> movingReferencePoint;
210};
211
212
214{
223 int consumedDof = 0;
224 bool finite = false;
225 double domainStart = 0.0;
226 double domainEnd = 0.0;
227 std::vector<SNAP_GUIDE> guides;
228 std::optional<INTERSECTABLE_GEOM> manifold;
229
231 const VECTOR2I& aPoint, double aResidual );
233 const VECTOR2I& aOrigin, const VECTOR2D& aDirection, double aResidual );
235 int aCoordinate, double aResidual );
237 int aCoordinate, double aResidual );
238};
239
240
242{
244 std::vector<SNAP_STABLE_ID> accepted;
247 std::vector<double> quantizedResiduals;
248 std::vector<SNAP_GUIDE> guides;
249
250 bool Accepted( const SNAP_STABLE_ID& aId ) const;
251};
252
253
255{
256public:
257 using CLOCK = std::chrono::steady_clock;
258 using CLOCK_CALLBACK = std::function<CLOCK::time_point()>;
259 // The candidate-vector reference is valid only during the synchronous callback and must not be retained.
261 std::function<SNAP_RESULT( const SNAP_SOURCE_CONTEXT&, const std::vector<SNAP_CANDIDATE>& )>;
262 using TRACE_CALLBACK = std::function<void( const std::string& )>;
263
264 void AddCandidate( SNAP_CANDIDATE aCandidate );
265 void Clear();
266 void SetRetainedCandidate( std::optional<SNAP_STABLE_ID> aId );
267
274 void SetStickyCandidates( std::vector<SNAP_STABLE_ID> aIds );
275
279 void SetRankingHysteresis( double aNormalizedResidual );
280
282 void SetTraceCallback( TRACE_CALLBACK aCallback );
283 void SetClock( CLOCK_CALLBACK aClock );
284 void SetDeadline( CLOCK::duration aDeadline );
285
286 SNAP_RESULT Resolve( const SNAP_SOURCE_CONTEXT& aContext ) const;
287
288private:
290 bool hasHysteresis( const SNAP_STABLE_ID& aId ) const;
291
292 std::vector<SNAP_CANDIDATE> m_candidates;
293 std::optional<SNAP_STABLE_ID> m_retainedCandidate;
294 std::vector<SNAP_STABLE_ID> m_stickyCandidates;
299 {
300 return CLOCK::now();
301 };
302 CLOCK::duration m_deadline = std::chrono::milliseconds( 8 );
303};
304
305#endif
The SIMULATOR_FRAME holds the main user-interface for running simulations.
bool hasHysteresis(const SNAP_STABLE_ID &aId) const
True when a candidate should earn the ranking hysteresis (retained or sticky).
SNAP_RESULT Resolve(const SNAP_SOURCE_CONTEXT &aContext) const
double m_rankingHysteresis
FEASIBILITY_CALLBACK m_feasibilityCallback
std::function< SNAP_RESULT(const SNAP_SOURCE_CONTEXT &, const std::vector< SNAP_CANDIDATE > &)> FEASIBILITY_CALLBACK
std::function< void(const std::string &)> TRACE_CALLBACK
void SetFeasibilityCallback(FEASIBILITY_CALLBACK aCallback)
void SetStickyCandidates(std::vector< SNAP_STABLE_ID > aIds)
Bias the ranking toward candidates accepted on a previous resolve so the chosen snap stays put until ...
TRACE_CALLBACK m_traceCallback
std::chrono::steady_clock CLOCK
void SetDeadline(CLOCK::duration aDeadline)
void SetClock(CLOCK_CALLBACK aClock)
std::optional< SNAP_STABLE_ID > m_retainedCandidate
CLOCK::duration m_deadline
void SetTraceCallback(TRACE_CALLBACK aCallback)
std::vector< SNAP_CANDIDATE > m_candidates
void AddCandidate(SNAP_CANDIDATE aCandidate)
void SetRankingHysteresis(double aNormalizedResidual)
Set how strongly a candidate with hysteresis is favoured, as a fraction of the snap radius.
CLOCK_CALLBACK m_clock
std::function< CLOCK::time_point()> CLOCK_CALLBACK
void SetRetainedCandidate(std::optional< SNAP_STABLE_ID > aId)
std::vector< SNAP_STABLE_ID > m_stickyCandidates
@ NONE
Definition eda_shape.h:72
NORMAL
Follows standard pretty-printing rules.
SNAP_REFERENCE_KIND
SNAP_EDITOR_PROFILE
SNAP_STABLE_ID MakeIntersectionSnapId(const SNAP_STABLE_ID &aFirst, const SNAP_STABLE_ID &aSecond, int aSolutionBranch)
constexpr double SNAP_SCREEN_RADIUS
Screen-space radius (px) inside which a candidate is snappable.
SNAP_STABLE_ID MakePointSnapId(SNAP_ID_KIND aKind, const VECTOR2I &aPoint, int aFeatureIndex=0)
SNAP_STABLE_ID MakeCompositeSnapId(SNAP_ID_KIND aKind, const std::vector< SNAP_TARGET_ID > &aTargets, int aFeatureIndex=0)
SNAP_RELATION
SNAP_STABLE_ID MakeDerivedSnapId(SNAP_ID_KIND aKind, const SNAP_STABLE_ID &aSource, int aFeatureIndex=0, int aSolutionBranch=0)
SNAP_ID_KIND
SNAP_PRIORITY_TIER
constexpr double SNAP_DEFAULT_RANKING_HYSTERESIS
Default ranking stickiness, as a fraction of SNAP_SCREEN_RADIUS.
std::ostream & operator<<(std::ostream &aStream, SNAP_RESULT_STATUS aStatus)
SNAP_GUIDE_STYLE
SNAP_CANDIDATE_SUBTYPE
std::array< uint8_t, 16 > SNAP_TARGET_ID
SNAP_RESULT_STATUS
Common grid settings, available to every frame.
SNAP_PRIORITY_TIER priority
static SNAP_CANDIDATE Point(SNAP_STABLE_ID aId, SNAP_PRIORITY_TIER aPriority, SNAP_CANDIDATE_SUBTYPE aSubtype, const VECTOR2I &aPoint, double aResidual)
std::optional< INTERSECTABLE_GEOM > manifold
double normalizedScreenResidual
SNAP_STABLE_ID id
static SNAP_CANDIDATE Line(SNAP_STABLE_ID aId, SNAP_PRIORITY_TIER aPriority, SNAP_CANDIDATE_SUBTYPE aSubtype, const VECTOR2I &aOrigin, const VECTOR2D &aDirection, double aResidual)
static SNAP_CANDIDATE AxisY(SNAP_STABLE_ID aId, SNAP_PRIORITY_TIER aPriority, SNAP_CANDIDATE_SUBTYPE aSubtype, int aCoordinate, double aResidual)
static SNAP_CANDIDATE AxisX(SNAP_STABLE_ID aId, SNAP_PRIORITY_TIER aPriority, SNAP_CANDIDATE_SUBTYPE aSubtype, int aCoordinate, double aResidual)
std::vector< SNAP_GUIDE > guides
SNAP_RELATION relation
SNAP_CANDIDATE_SUBTYPE subtype
SNAP_GUIDE_STYLE style
VECTOR2I end
VECTOR2I start
SNAP_REFERENCE_KIND kind
std::vector< double > quantizedResiduals
VECTOR2I position
std::vector< SNAP_GUIDE > guides
std::vector< SNAP_STABLE_ID > accepted
bool Accepted(const SNAP_STABLE_ID &aId) const
SNAP_RESULT_STATUS status
std::optional< VECTOR2I > stationarySourceLeg
std::vector< SNAP_STABLE_ID > movingFeatures
std::optional< BOX2I > movingBounds
std::optional< VECTOR2I > movingReferencePoint
std::optional< SNAP_STABLE_ID > movingItem
std::vector< SNAP_STABLE_ID > stationarySelfFeatures
SNAP_EDITOR_PROFILE profile
SNAP_REFERENCE_PREFERENCE referencePreference
SNAP_ID_KIND kind
SNAP_TARGET_ID target
bool operator<(const SNAP_STABLE_ID &aOther) const
bool operator==(const SNAP_STABLE_ID &aOther) const =default
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682