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 undoredo::{ApplyDelta, Delta, FlushDelta};
|
||||||
|
|
||||||
use crate::layout::{
|
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 {
|
struct Layer {
|
||||||
|
|
@ -41,6 +42,10 @@ impl Board {
|
||||||
pub fn add_via(&mut self, via: Via) -> ViaId {
|
pub fn add_via(&mut self, via: Via) -> ViaId {
|
||||||
self.layout.add_via(via)
|
self.layout.add_via(via)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||||
|
self.layout.add_polygon(polygon)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Dissolve)]
|
#[derive(Clone, Debug, Dissolve)]
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder};
|
||||||
pub struct JointId(usize);
|
pub struct JointId(usize);
|
||||||
|
|
||||||
impl JointId {
|
impl JointId {
|
||||||
/// Wrap a vertex index in a newtype struct.
|
/// Wrap a joint index in a newtype struct.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(id: usize) -> Self {
|
pub fn new(id: usize) -> Self {
|
||||||
Self(id)
|
Self(id)
|
||||||
|
|
@ -36,7 +36,7 @@ pub struct Joint {
|
||||||
pub struct SegmentId(usize);
|
pub struct SegmentId(usize);
|
||||||
|
|
||||||
impl SegmentId {
|
impl SegmentId {
|
||||||
/// Wrap a vertex index in a newtype struct.
|
/// Wrap a segment index in a newtype struct.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(id: usize) -> Self {
|
pub fn new(id: usize) -> Self {
|
||||||
Self(id)
|
Self(id)
|
||||||
|
|
@ -60,7 +60,7 @@ pub struct Segment {
|
||||||
pub struct ArcId(usize);
|
pub struct ArcId(usize);
|
||||||
|
|
||||||
impl ArcId {
|
impl ArcId {
|
||||||
/// Wrap a vertex index in a newtype struct.
|
/// Wrap an arc index in a newtype struct.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(id: usize) -> Self {
|
pub fn new(id: usize) -> Self {
|
||||||
Self(id)
|
Self(id)
|
||||||
|
|
@ -85,7 +85,7 @@ pub struct Arc {
|
||||||
pub struct ViaId(usize);
|
pub struct ViaId(usize);
|
||||||
|
|
||||||
impl ViaId {
|
impl ViaId {
|
||||||
/// Wrap a vertex index in a newtype struct.
|
/// Wrap a via index in a newtype struct.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(id: usize) -> Self {
|
pub fn new(id: usize) -> Self {
|
||||||
Self(id)
|
Self(id)
|
||||||
|
|
@ -105,6 +105,29 @@ pub struct Via {
|
||||||
pub radius: u64,
|
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)]
|
#[derive(Clone, Debug, Getters)]
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
boundary: Vec<[i64; 2]>,
|
boundary: Vec<[i64; 2]>,
|
||||||
|
|
@ -113,6 +136,7 @@ pub struct Layout {
|
||||||
segments: Recorder<StableVec<Segment>>,
|
segments: Recorder<StableVec<Segment>>,
|
||||||
arcs: Recorder<StableVec<Arc>>,
|
arcs: Recorder<StableVec<Arc>>,
|
||||||
vias: Recorder<StableVec<Via>>,
|
vias: Recorder<StableVec<Via>>,
|
||||||
|
polygons: Recorder<StableVec<Polygon>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layout {
|
impl Layout {
|
||||||
|
|
@ -124,6 +148,7 @@ impl Layout {
|
||||||
segments: Recorder::new(StableVec::new()),
|
segments: Recorder::new(StableVec::new()),
|
||||||
arcs: Recorder::new(StableVec::new()),
|
arcs: Recorder::new(StableVec::new()),
|
||||||
vias: 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 {
|
pub fn add_via(&mut self, via: Via) -> ViaId {
|
||||||
ViaId::new(self.vias.push(via))
|
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)]
|
#[derive(Clone, Debug, Dissolve)]
|
||||||
|
|
@ -150,6 +179,7 @@ pub struct LayoutHalfDelta {
|
||||||
segments: BTreeMap<usize, Segment>,
|
segments: BTreeMap<usize, Segment>,
|
||||||
arcs: BTreeMap<usize, Arc>,
|
arcs: BTreeMap<usize, Arc>,
|
||||||
vias: BTreeMap<usize, Via>,
|
vias: BTreeMap<usize, Via>,
|
||||||
|
polygons: BTreeMap<usize, Polygon>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApplyDelta<LayoutHalfDelta> for Layout {
|
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);
|
let vias_delta = Delta::with_removed_inserted(removed.vias, inserted.vias);
|
||||||
self.vias.apply_delta(&vias_delta);
|
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_segments, inserted_segments) = self.segments.flush_delta().dissolve();
|
||||||
let (removed_arcs, inserted_arcs) = self.arcs.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_vias, inserted_vias) = self.vias.flush_delta().dissolve();
|
||||||
|
let (removed_polygons, inserted_polygons) = self.polygons.flush_delta().dissolve();
|
||||||
|
|
||||||
Delta::with_removed_inserted(
|
Delta::with_removed_inserted(
|
||||||
LayoutHalfDelta {
|
LayoutHalfDelta {
|
||||||
|
|
@ -183,12 +217,14 @@ impl FlushDelta<LayoutHalfDelta> for Layout {
|
||||||
segments: removed_segments,
|
segments: removed_segments,
|
||||||
arcs: removed_arcs,
|
arcs: removed_arcs,
|
||||||
vias: removed_vias,
|
vias: removed_vias,
|
||||||
|
polygons: removed_polygons,
|
||||||
},
|
},
|
||||||
LayoutHalfDelta {
|
LayoutHalfDelta {
|
||||||
joints: inserted_joints,
|
joints: inserted_joints,
|
||||||
segments: inserted_segments,
|
segments: inserted_segments,
|
||||||
arcs: inserted_arcs,
|
arcs: inserted_arcs,
|
||||||
vias: inserted_vias,
|
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::{
|
use crate::{
|
||||||
Board,
|
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)]
|
#[derive(Clone, Debug, Getters)]
|
||||||
|
|
@ -123,4 +123,9 @@ impl NavmesherBoard {
|
||||||
// TODO: Insert into navmesh.
|
// TODO: Insert into navmesh.
|
||||||
self.board.add_via(via)
|
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,
|
&mut board,
|
||||||
place.point_with_rotation(),
|
place.point_with_rotation(),
|
||||||
pin.point_with_rotation(),
|
pin.point_with_rotation(),
|
||||||
|
0,
|
||||||
(circle.diameter / 2.0) as u64,
|
(circle.diameter / 2.0) as u64,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
|
@ -64,31 +65,52 @@ impl Board {
|
||||||
board: &mut Board,
|
board: &mut Board,
|
||||||
place: PointWithRotation,
|
place: PointWithRotation,
|
||||||
pin: PointWithRotation,
|
pin: PointWithRotation,
|
||||||
|
layer: usize,
|
||||||
radius: u64,
|
radius: u64,
|
||||||
flip: bool,
|
flip: bool,
|
||||||
) {
|
) {
|
||||||
let pos = Self::pos(place, pin, 0.0, 0.0, flip);
|
|
||||||
|
|
||||||
board.add_joint(Joint {
|
board.add_joint(Joint {
|
||||||
position: [pos.x, pos.y],
|
position: Self::pos(place, pin, 0.0, 0.0, flip),
|
||||||
layer: 0,
|
layer,
|
||||||
radius,
|
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(
|
fn pos(
|
||||||
place: PointWithRotation,
|
place: PointWithRotation,
|
||||||
pin: PointWithRotation,
|
pin: PointWithRotation,
|
||||||
x: f64,
|
x: f64,
|
||||||
y: f64,
|
y: f64,
|
||||||
flip: bool,
|
flip: bool,
|
||||||
) -> Vector2<i64> {
|
) -> [i64; 2] {
|
||||||
let pos = (Vector2::new(x, y) + Vector2::new(pin.pos.x(), pin.pos.y()))
|
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()));
|
.rotate_around_point_degrees(pin.rot, Vector2::new(pin.pos.x(), pin.pos.y()));
|
||||||
let pos = (Vector2::new(place.pos.x(), place.pos.y())
|
let pos = (Vector2::new(place.pos.x(), place.pos.y())
|
||||||
+ flip.then_some(Vector2::new(-pos.x, pos.y)).unwrap_or(pos))
|
+ 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()));
|
.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