mirror of https://codeberg.org/topola/topola.git
Add polygon insertion
This commit is contained in:
parent
f4a8bee711
commit
c927ad281f
|
|
@ -6,7 +6,8 @@ use derive_getters::{Dissolve, Getters};
|
|||
use undoredo::{ApplyDelta, Delta, FlushDelta};
|
||||
|
||||
use crate::layout::{
|
||||
Arc, ArcId, Joint, JointId, Layout, LayoutHalfDelta, Segment, SegmentId, Via, ViaId,
|
||||
Arc, ArcId, Joint, JointId, Layout, LayoutHalfDelta, Polygon, PolygonId, Segment, SegmentId,
|
||||
Via, ViaId,
|
||||
};
|
||||
|
||||
struct Layer {
|
||||
|
|
@ -41,6 +42,10 @@ impl Board {
|
|||
pub fn add_via(&mut self, via: Via) -> ViaId {
|
||||
self.layout.add_via(via)
|
||||
}
|
||||
|
||||
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||
self.layout.add_polygon(polygon)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Dissolve)]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder};
|
|||
pub struct JointId(usize);
|
||||
|
||||
impl JointId {
|
||||
/// Wrap a vertex index in a newtype struct.
|
||||
/// Wrap a joint index in a newtype struct.
|
||||
#[inline]
|
||||
pub fn new(id: usize) -> Self {
|
||||
Self(id)
|
||||
|
|
@ -36,7 +36,7 @@ pub struct Joint {
|
|||
pub struct SegmentId(usize);
|
||||
|
||||
impl SegmentId {
|
||||
/// Wrap a vertex index in a newtype struct.
|
||||
/// Wrap a segment index in a newtype struct.
|
||||
#[inline]
|
||||
pub fn new(id: usize) -> Self {
|
||||
Self(id)
|
||||
|
|
@ -60,7 +60,7 @@ pub struct Segment {
|
|||
pub struct ArcId(usize);
|
||||
|
||||
impl ArcId {
|
||||
/// Wrap a vertex index in a newtype struct.
|
||||
/// Wrap an arc index in a newtype struct.
|
||||
#[inline]
|
||||
pub fn new(id: usize) -> Self {
|
||||
Self(id)
|
||||
|
|
@ -85,7 +85,7 @@ pub struct Arc {
|
|||
pub struct ViaId(usize);
|
||||
|
||||
impl ViaId {
|
||||
/// Wrap a vertex index in a newtype struct.
|
||||
/// Wrap a via index in a newtype struct.
|
||||
#[inline]
|
||||
pub fn new(id: usize) -> Self {
|
||||
Self(id)
|
||||
|
|
@ -105,6 +105,29 @@ pub struct Via {
|
|||
pub radius: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct PolygonId(usize);
|
||||
|
||||
impl PolygonId {
|
||||
/// Wrap a polygon index in a newtype struct.
|
||||
#[inline]
|
||||
pub fn new(id: usize) -> Self {
|
||||
Self(id)
|
||||
}
|
||||
|
||||
/// Returns the underlying index.
|
||||
#[inline]
|
||||
pub fn id(self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Polygon {
|
||||
pub vertices: Vec<[i64; 2]>,
|
||||
pub layer: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Getters)]
|
||||
pub struct Layout {
|
||||
boundary: Vec<[i64; 2]>,
|
||||
|
|
@ -113,6 +136,7 @@ pub struct Layout {
|
|||
segments: Recorder<StableVec<Segment>>,
|
||||
arcs: Recorder<StableVec<Arc>>,
|
||||
vias: Recorder<StableVec<Via>>,
|
||||
polygons: Recorder<StableVec<Polygon>>,
|
||||
}
|
||||
|
||||
impl Layout {
|
||||
|
|
@ -124,6 +148,7 @@ impl Layout {
|
|||
segments: Recorder::new(StableVec::new()),
|
||||
arcs: Recorder::new(StableVec::new()),
|
||||
vias: Recorder::new(StableVec::new()),
|
||||
polygons: Recorder::new(StableVec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,6 +167,10 @@ impl Layout {
|
|||
pub fn add_via(&mut self, via: Via) -> ViaId {
|
||||
ViaId::new(self.vias.push(via))
|
||||
}
|
||||
|
||||
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||
PolygonId::new(self.polygons.push(polygon))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Dissolve)]
|
||||
|
|
@ -150,6 +179,7 @@ pub struct LayoutHalfDelta {
|
|||
segments: BTreeMap<usize, Segment>,
|
||||
arcs: BTreeMap<usize, Arc>,
|
||||
vias: BTreeMap<usize, Via>,
|
||||
polygons: BTreeMap<usize, Polygon>,
|
||||
}
|
||||
|
||||
impl ApplyDelta<LayoutHalfDelta> for Layout {
|
||||
|
|
@ -167,6 +197,9 @@ impl ApplyDelta<LayoutHalfDelta> for Layout {
|
|||
|
||||
let vias_delta = Delta::with_removed_inserted(removed.vias, inserted.vias);
|
||||
self.vias.apply_delta(&vias_delta);
|
||||
|
||||
let polygons_delta = Delta::with_removed_inserted(removed.polygons, inserted.polygons);
|
||||
self.polygons.apply_delta(&polygons_delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -176,6 +209,7 @@ impl FlushDelta<LayoutHalfDelta> for Layout {
|
|||
let (removed_segments, inserted_segments) = self.segments.flush_delta().dissolve();
|
||||
let (removed_arcs, inserted_arcs) = self.arcs.flush_delta().dissolve();
|
||||
let (removed_vias, inserted_vias) = self.vias.flush_delta().dissolve();
|
||||
let (removed_polygons, inserted_polygons) = self.polygons.flush_delta().dissolve();
|
||||
|
||||
Delta::with_removed_inserted(
|
||||
LayoutHalfDelta {
|
||||
|
|
@ -183,12 +217,14 @@ impl FlushDelta<LayoutHalfDelta> for Layout {
|
|||
segments: removed_segments,
|
||||
arcs: removed_arcs,
|
||||
vias: removed_vias,
|
||||
polygons: removed_polygons,
|
||||
},
|
||||
LayoutHalfDelta {
|
||||
joints: inserted_joints,
|
||||
segments: inserted_segments,
|
||||
arcs: inserted_arcs,
|
||||
vias: inserted_vias,
|
||||
polygons: inserted_polygons,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use derive_more::{Add, Constructor, From, Into, Sub};
|
||||
|
||||
#[derive(Add, Clone, Constructor, Copy, Debug, From, Into, Sub)]
|
||||
pub struct Vector2<T> {
|
||||
pub x: T,
|
||||
pub y: T,
|
||||
}
|
||||
|
||||
macro_rules! impl_rotate_around_point {
|
||||
($t:ty) => {
|
||||
impl Vector2<$t> {
|
||||
pub fn rotate_around_point(&mut self, angle: $t, origin: Vector2<$t>) -> Self {
|
||||
let sin = angle.sin();
|
||||
let cos = angle.cos();
|
||||
|
||||
let tx = self.x - origin.x;
|
||||
let ty = self.y - origin.y;
|
||||
|
||||
let rx = tx * cos - ty * sin;
|
||||
let ry = tx * sin + ty * cos;
|
||||
|
||||
self.x = rx + origin.x;
|
||||
self.y = ry + origin.y;
|
||||
|
||||
*self
|
||||
}
|
||||
|
||||
pub fn rotate_around_point_degrees(&mut self, angle: $t, origin: Vector2<$t>) -> Self {
|
||||
self.rotate_around_point(angle.to_radians(), origin)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_rotate_around_point!(f32);
|
||||
impl_rotate_around_point!(f64);
|
||||
|
|
@ -7,7 +7,7 @@ use derive_getters::Getters;
|
|||
|
||||
use crate::{
|
||||
Board,
|
||||
layout::{Arc, ArcId, Joint, JointId, Segment, SegmentId, Via, ViaId},
|
||||
layout::{Arc, ArcId, Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Via, ViaId},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Getters)]
|
||||
|
|
@ -123,4 +123,9 @@ impl NavmesherBoard {
|
|||
// TODO: Insert into navmesh.
|
||||
self.board.add_via(via)
|
||||
}
|
||||
|
||||
pub fn insert_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||
// TODO: Insert into navmesh.
|
||||
self.board.add_polygon(polygon)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ impl Board {
|
|||
&mut board,
|
||||
place.point_with_rotation(),
|
||||
pin.point_with_rotation(),
|
||||
0,
|
||||
(circle.diameter / 2.0) as u64,
|
||||
false,
|
||||
),
|
||||
|
|
@ -64,31 +65,52 @@ impl Board {
|
|||
board: &mut Board,
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
layer: usize,
|
||||
radius: u64,
|
||||
flip: bool,
|
||||
) {
|
||||
let pos = Self::pos(place, pin, 0.0, 0.0, flip);
|
||||
|
||||
board.add_joint(Joint {
|
||||
position: [pos.x, pos.y],
|
||||
layer: 0,
|
||||
position: Self::pos(place, pin, 0.0, 0.0, flip),
|
||||
layer,
|
||||
radius,
|
||||
});
|
||||
}
|
||||
|
||||
/*pub fn place_rect(
|
||||
board: &mut Board,
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
x1: f64,
|
||||
y1: f64,
|
||||
x2: f64,
|
||||
y2: f64,
|
||||
layer: usize,
|
||||
flip: bool,
|
||||
) {
|
||||
board.add_polygon(Polygon {
|
||||
vertices: [
|
||||
Self::pos(place, pin, x1, y1, flip),
|
||||
Self::pos(place, pin, x2, y1, flip),
|
||||
Self::pos(place, pin, x2, y2, flip),
|
||||
Self::pos(place, pin, x1, y2, flip),
|
||||
],
|
||||
layer,
|
||||
})
|
||||
}*/
|
||||
|
||||
fn pos(
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
x: f64,
|
||||
y: f64,
|
||||
flip: bool,
|
||||
) -> Vector2<i64> {
|
||||
) -> [i64; 2] {
|
||||
let pos = (Vector2::new(x, y) + Vector2::new(pin.pos.x(), pin.pos.y()))
|
||||
.rotate_around_point_degrees(pin.rot, Vector2::new(pin.pos.x(), pin.pos.y()));
|
||||
let pos = (Vector2::new(place.pos.x(), place.pos.y())
|
||||
+ flip.then_some(Vector2::new(-pos.x, pos.y)).unwrap_or(pos))
|
||||
.rotate_around_point_degrees(place.rot, Vector2::new(place.pos.x(), place.pos.y()));
|
||||
|
||||
Vector2::new(pos.x as i64, pos.y as i64)
|
||||
[pos.x as i64, pos.y as i64]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue