mirror of https://codeberg.org/topola/topola.git
Compare commits
2 Commits
7f67a24808
...
618905f56d
| Author | SHA1 | Date |
|---|---|---|
|
|
618905f56d | |
|
|
b2a75fd520 |
|
|
@ -52,7 +52,7 @@ impl Display {
|
|||
joint,
|
||||
workspace.appearance_panel.layer_color(
|
||||
ctx,
|
||||
board.layer_name(joint.layer),
|
||||
board.layer_name(joint.spec.layer),
|
||||
board.pin_selection_contains_joint(&workspace.pin_selection, joint_id),
|
||||
),
|
||||
);
|
||||
|
|
@ -113,8 +113,8 @@ impl Display {
|
|||
color: egui::Color32,
|
||||
) {
|
||||
ui.painter().circle_filled(
|
||||
egui::pos2(joint.position.x as f32, joint.position.y as f32),
|
||||
joint.radius as f32,
|
||||
egui::pos2(joint.spec.position.x as f32, joint.spec.position.y as f32),
|
||||
joint.spec.radius as f32,
|
||||
color,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ use crate::{
|
|||
layout::{Layout, LayoutHalfDelta, NetId, PinId},
|
||||
math::Vector2,
|
||||
primitives::{
|
||||
Joint, JointId, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId, ViaSpec,
|
||||
JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId,
|
||||
ViaSpec,
|
||||
},
|
||||
selection::{PinSelection, PinSelector},
|
||||
};
|
||||
|
|
@ -61,8 +62,8 @@ impl Board {
|
|||
pin_id
|
||||
}
|
||||
|
||||
pub fn add_joint(&mut self, joint: Joint) -> JointId {
|
||||
self.layout.add_joint(joint)
|
||||
pub fn add_joint(&mut self, spec: JointSpec) -> JointId {
|
||||
self.layout.add_joint(spec)
|
||||
}
|
||||
|
||||
pub fn add_segment(&mut self, spec: SegmentSpec) -> SegmentId {
|
||||
|
|
@ -89,8 +90,8 @@ impl Board {
|
|||
let joint = self.layout.joint(joint_id);
|
||||
|
||||
Some(PinSelector {
|
||||
pin: self.pin_name(joint.pin?)?.to_string(),
|
||||
layer: self.layer_name(joint.layer)?.to_string(),
|
||||
pin: self.pin_name(joint.spec.pin?)?.to_string(),
|
||||
layer: self.layer_name(joint.spec.layer)?.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use undoredo::{Delta, Recorder};
|
|||
|
||||
use crate::{
|
||||
Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Vector2, Via, ViaId,
|
||||
primitives::{SegmentSpec, ViaSpec},
|
||||
primitives::{JointSpec, SegmentSpec, ViaSpec},
|
||||
};
|
||||
|
||||
#[derive(
|
||||
|
|
@ -123,9 +123,14 @@ impl Layout {
|
|||
PinId::new(self.pins.push(Pin::new()))
|
||||
}
|
||||
|
||||
pub fn add_joint(&mut self, joint: Joint) -> JointId {
|
||||
pub fn add_joint(&mut self, spec: JointSpec) -> JointId {
|
||||
let joint = Joint {
|
||||
spec,
|
||||
segments: Vec::new(),
|
||||
vias: Vec::new(),
|
||||
};
|
||||
let bbox = joint.bbox();
|
||||
let pin_id = joint.pin;
|
||||
let pin_id = joint.spec.pin;
|
||||
let joint_id = JointId::new(self.joints.push(joint));
|
||||
|
||||
self.joints_rtree
|
||||
|
|
@ -138,15 +143,38 @@ impl Layout {
|
|||
joint_id
|
||||
}
|
||||
|
||||
pub fn modify_joint<F>(&mut self, id: JointId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut JointSpec),
|
||||
{
|
||||
let old_joint = self.joints.get(&id.index()).unwrap();
|
||||
self.joints_rtree
|
||||
.remove(&GeomWithData::new(old_joint.bbox(), id));
|
||||
|
||||
self.joints.modify(id.index(), |joint| f(&mut joint.spec));
|
||||
|
||||
let new_joint = self.joints.get(&id.index()).unwrap().clone();
|
||||
self.joints_rtree
|
||||
.insert(GeomWithData::new(new_joint.bbox(), id), ());
|
||||
|
||||
for &segment in &new_joint.segments {
|
||||
self.update_segment(segment);
|
||||
}
|
||||
|
||||
for &via in &new_joint.vias {
|
||||
self.update_via(via);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_segment(&mut self, spec: SegmentSpec) -> SegmentId {
|
||||
self.add_segment_raw(Segment {
|
||||
spec,
|
||||
endpoints: [
|
||||
self.joint(spec.endjoints[0]).position,
|
||||
self.joint(spec.endjoints[1]).position,
|
||||
self.joint(spec.endjoints[0]).spec.position,
|
||||
self.joint(spec.endjoints[1]).spec.position,
|
||||
],
|
||||
layer: self.joint(spec.endjoints[0]).layer,
|
||||
net: self.joint(spec.endjoints[0]).net,
|
||||
layer: self.joint(spec.endjoints[0]).spec.layer,
|
||||
net: self.joint(spec.endjoints[0]).spec.net,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -155,6 +183,15 @@ impl Layout {
|
|||
let bbox = segment.bbox();
|
||||
let segment_id = SegmentId::new(self.segments.push(segment));
|
||||
|
||||
self.joints
|
||||
.modify(segment.spec.endjoints[0].index(), |joint| {
|
||||
joint.segments.push(segment_id)
|
||||
});
|
||||
self.joints
|
||||
.modify(segment.spec.endjoints[1].index(), |joint| {
|
||||
joint.segments.push(segment_id)
|
||||
});
|
||||
|
||||
self.segments_rtree
|
||||
.insert(GeomWithData::new(bbox, segment_id), ());
|
||||
|
||||
|
|
@ -165,16 +202,52 @@ impl Layout {
|
|||
segment_id
|
||||
}
|
||||
|
||||
pub fn modify_segment<F>(&mut self, id: SegmentId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut SegmentSpec),
|
||||
{
|
||||
let old_segment = self.segments.get(&id.index()).unwrap();
|
||||
self.segments_rtree
|
||||
.remove(&GeomWithData::new(old_segment.bbox(), id));
|
||||
|
||||
self.segments
|
||||
.modify(id.index(), |segment| f(&mut segment.spec));
|
||||
|
||||
let new_segment = self.segments.get(&id.index()).unwrap();
|
||||
self.segments_rtree
|
||||
.insert(GeomWithData::new(new_segment.bbox(), id), ());
|
||||
}
|
||||
|
||||
fn update_segment(&mut self, id: SegmentId) {
|
||||
let old_segment = self.segments.get(&id.index()).unwrap();
|
||||
self.segments_rtree
|
||||
.remove(&GeomWithData::new(old_segment.bbox(), id));
|
||||
|
||||
let endjoint_ids = old_segment.spec.endjoints;
|
||||
let endjoint_specs = [
|
||||
self.joints.get(&endjoint_ids[0].index()).unwrap().spec,
|
||||
self.joints.get(&endjoint_ids[1].index()).unwrap().spec,
|
||||
];
|
||||
self.segments.modify(id.index(), |segment| {
|
||||
segment.endpoints = [endjoint_specs[0].position, endjoint_specs[1].position];
|
||||
segment.layer = endjoint_specs[0].layer;
|
||||
segment.net = endjoint_specs[0].net;
|
||||
});
|
||||
|
||||
let new_segment = self.segments.get(&id.index()).unwrap();
|
||||
self.segments_rtree
|
||||
.insert(GeomWithData::new(new_segment.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub fn add_via(&mut self, spec: ViaSpec) -> ViaId {
|
||||
let joint0 = self.joint(spec.endjoints[0]);
|
||||
let joint1 = self.joint(spec.endjoints[1]);
|
||||
let joints = [self.joint(spec.endjoints[0]), self.joint(spec.endjoints[1])];
|
||||
|
||||
self.add_via_raw(Via {
|
||||
spec,
|
||||
min_layer: std::cmp::min(joint0.layer, joint1.layer),
|
||||
max_layer: std::cmp::max(joint0.layer, joint1.layer),
|
||||
net: joint0.net,
|
||||
position: (joint0.position + joint1.position) / 2,
|
||||
position: joints[0].spec.position,
|
||||
min_layer: std::cmp::min(joints[0].spec.layer, joints[1].spec.layer),
|
||||
max_layer: std::cmp::max(joints[0].spec.layer, joints[1].spec.layer),
|
||||
net: joints[0].spec.net,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -183,6 +256,13 @@ impl Layout {
|
|||
let pin_id = via.spec.pin;
|
||||
let via_id = ViaId::new(self.vias.push(via));
|
||||
|
||||
self.joints.modify(via.spec.endjoints[0].index(), |joint| {
|
||||
joint.vias.push(via_id)
|
||||
});
|
||||
self.joints.modify(via.spec.endjoints[1].index(), |joint| {
|
||||
joint.vias.push(via_id)
|
||||
});
|
||||
|
||||
self.vias_rtree.insert(GeomWithData::new(bbox, via_id), ());
|
||||
|
||||
if let Some(pin_id) = pin_id {
|
||||
|
|
@ -192,6 +272,43 @@ impl Layout {
|
|||
via_id
|
||||
}
|
||||
|
||||
pub fn modify_via<F>(&mut self, id: ViaId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut ViaSpec),
|
||||
{
|
||||
let old_via = self.vias.get(&id.index()).unwrap();
|
||||
self.vias_rtree
|
||||
.remove(&GeomWithData::new(old_via.bbox(), id));
|
||||
|
||||
self.vias.modify(id.index(), |via| f(&mut via.spec));
|
||||
|
||||
let new_via = self.vias.get(&id.index()).unwrap();
|
||||
self.vias_rtree
|
||||
.insert(GeomWithData::new(new_via.bbox(), id), ());
|
||||
}
|
||||
|
||||
fn update_via(&mut self, id: ViaId) {
|
||||
let old_via = self.vias.get(&id.index()).unwrap();
|
||||
self.vias_rtree
|
||||
.remove(&GeomWithData::new(old_via.bbox(), id));
|
||||
|
||||
let endjoint_ids = old_via.spec.endjoints;
|
||||
let endjoint_specs = [
|
||||
self.joints.get(&endjoint_ids[0].index()).unwrap().spec,
|
||||
self.joints.get(&endjoint_ids[1].index()).unwrap().spec,
|
||||
];
|
||||
self.vias.modify(id.index(), |via| {
|
||||
via.position = endjoint_specs[0].position;
|
||||
via.min_layer = std::cmp::min(endjoint_specs[0].layer, endjoint_specs[1].layer);
|
||||
via.max_layer = std::cmp::max(endjoint_specs[0].layer, endjoint_specs[1].layer);
|
||||
via.net = endjoint_specs[0].net;
|
||||
});
|
||||
|
||||
let new_via = self.vias.get(&id.index()).unwrap();
|
||||
self.vias_rtree
|
||||
.insert(GeomWithData::new(new_via.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||
let bbox = polygon.bbox();
|
||||
let pin_id = polygon.pin;
|
||||
|
|
@ -207,6 +324,21 @@ impl Layout {
|
|||
polygon_id
|
||||
}
|
||||
|
||||
pub fn modify_polygon<F>(&mut self, id: PolygonId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut Polygon),
|
||||
{
|
||||
let old_polygon = self.polygons.get(&id.index()).unwrap();
|
||||
self.polygons_rtree
|
||||
.remove(&GeomWithData::new(old_polygon.bbox(), id));
|
||||
|
||||
self.polygons.modify(id.index(), |polygon| f(polygon));
|
||||
|
||||
let new_polygon = self.polygons.get(&id.index()).unwrap();
|
||||
self.polygons_rtree
|
||||
.insert(GeomWithData::new(new_polygon.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub fn locate_joints_at_point(
|
||||
&self,
|
||||
layer: usize,
|
||||
|
|
@ -261,7 +393,7 @@ impl Layout {
|
|||
.as_ref()
|
||||
.locate_in_envelope_intersecting(&envelope)
|
||||
.map(|geom_with_data| geom_with_data.data)
|
||||
.filter(move |&id| self.joint(id).layer == layer)
|
||||
.filter(move |&id| self.joint(id).spec.layer == layer)
|
||||
}
|
||||
|
||||
pub fn layer_segments(&self, layer: usize) -> impl Iterator<Item = SegmentId> + '_ {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ use serde::{Deserialize, Serialize};
|
|||
use stable_vec::StableVec;
|
||||
use undoredo::Recorder;
|
||||
|
||||
use crate::{Board, Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Vector2};
|
||||
use crate::{
|
||||
Board, Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Vector2, primitives::JointSpec,
|
||||
};
|
||||
|
||||
#[derive(
|
||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
||||
|
|
@ -204,7 +206,7 @@ impl NavmesherBoard {
|
|||
this.joint_multiobstacles.insert(
|
||||
i,
|
||||
this.navmesher
|
||||
.insert_multiobstacle(joint.layer, Self::joint_bounding_octagon(*joint)),
|
||||
.insert_multiobstacle(joint.spec.layer, Self::joint_bounding_octagon(joint)),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -227,21 +229,26 @@ impl NavmesherBoard {
|
|||
this
|
||||
}
|
||||
|
||||
pub fn insert_joint(&mut self, joint: Joint) -> JointId {
|
||||
let joint_id = self.board.add_joint(joint);
|
||||
pub fn insert_joint(&mut self, spec: JointSpec) -> JointId {
|
||||
let layer = spec.layer;
|
||||
let obstacle = Self::joint_bounding_octagon(&Joint {
|
||||
spec,
|
||||
segments: Vec::new(),
|
||||
vias: Vec::new(),
|
||||
});
|
||||
let joint_id = self.board.add_joint(spec);
|
||||
self.joint_multiobstacles.insert(
|
||||
joint_id.index(),
|
||||
self.navmesher
|
||||
.insert_multiobstacle(joint.layer, Self::joint_bounding_octagon(joint)),
|
||||
self.navmesher.insert_multiobstacle(layer, obstacle),
|
||||
);
|
||||
|
||||
joint_id
|
||||
}
|
||||
|
||||
fn joint_bounding_octagon(joint: Joint) -> [Vector2<i64>; 8] {
|
||||
let cx = joint.position.x;
|
||||
let cy = joint.position.y;
|
||||
let r = joint.radius as i64;
|
||||
fn joint_bounding_octagon(joint: &Joint) -> [Vector2<i64>; 8] {
|
||||
let cx = joint.spec.position.x;
|
||||
let cy = joint.spec.position.y;
|
||||
let r = joint.spec.radius as i64;
|
||||
|
||||
[
|
||||
Vector2::new(cx + r, cy + r / 2),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::layout::{NetId, PinId};
|
||||
use crate::math::Vector2;
|
||||
use crate::primitives::{SegmentId, ViaId};
|
||||
|
||||
#[derive(
|
||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
||||
|
|
@ -23,7 +24,7 @@ impl JointId {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Joint {
|
||||
pub struct JointSpec {
|
||||
pub position: Vector2<i64>,
|
||||
pub layer: usize,
|
||||
pub radius: u64,
|
||||
|
|
@ -31,28 +32,36 @@ pub struct Joint {
|
|||
pub pin: Option<PinId>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Joint {
|
||||
pub spec: JointSpec,
|
||||
pub segments: Vec<SegmentId>,
|
||||
pub vias: Vec<ViaId>,
|
||||
}
|
||||
|
||||
impl Joint {
|
||||
pub fn center(&self) -> Vector2<i64> {
|
||||
self.spec.position
|
||||
}
|
||||
|
||||
pub fn bbox(&self) -> Rectangle<[i64; 3]> {
|
||||
Rectangle::from_aabb(AABB::from_corners(
|
||||
[
|
||||
self.position.x - self.radius as i64,
|
||||
self.position.y - self.radius as i64,
|
||||
self.layer as i64,
|
||||
self.spec.position.x - self.spec.radius as i64,
|
||||
self.spec.position.y - self.spec.radius as i64,
|
||||
self.spec.layer as i64,
|
||||
],
|
||||
[
|
||||
self.position.x + self.radius as i64,
|
||||
self.position.y + self.radius as i64,
|
||||
self.layer as i64,
|
||||
self.spec.position.x + self.spec.radius as i64,
|
||||
self.spec.position.y + self.spec.radius as i64,
|
||||
self.spec.layer as i64,
|
||||
],
|
||||
))
|
||||
}
|
||||
|
||||
pub fn center(&self) -> Vector2<i64> {
|
||||
self.position
|
||||
}
|
||||
|
||||
pub fn contains_point(&self, point: Vector2<i64>) -> bool {
|
||||
(point.x - self.position.x).pow(2) as u64 + (point.y - self.position.y).pow(2) as u64
|
||||
<= self.radius.pow(2)
|
||||
(point.x - self.spec.position.x).pow(2) as u64
|
||||
+ (point.y - self.spec.position.y).pow(2) as u64
|
||||
<= self.spec.radius.pow(2)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ mod polygon;
|
|||
mod segment;
|
||||
mod via;
|
||||
|
||||
pub use joint::{Joint, JointId};
|
||||
pub use joint::{Joint, JointId, JointSpec};
|
||||
pub use polygon::{Polygon, PolygonId};
|
||||
pub use segment::{Segment, SegmentId, SegmentSpec};
|
||||
pub use via::{Via, ViaId, ViaSpec};
|
||||
|
|
|
|||
|
|
@ -48,10 +48,10 @@ impl Ratsnest {
|
|||
|
||||
for (i, joint) in board.layout().joints().container().iter() {
|
||||
let _ = triangulations
|
||||
.entry((joint.net, joint.layer))
|
||||
.entry((joint.spec.net, joint.spec.layer))
|
||||
.or_insert_with(DelaunayTriangulation::new)
|
||||
.insert(DelaunayVertex {
|
||||
layer: joint.layer,
|
||||
layer: joint.spec.layer,
|
||||
center: joint.center(),
|
||||
position: spade::Point2::new(joint.center().x as f64, joint.center().y as f64),
|
||||
primitive_id: PrimitiveId::Joint(JointId::new(i)),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use crate::{
|
|||
Segment, Vector2,
|
||||
board::Board,
|
||||
layout::{NetId, PinId},
|
||||
primitives::{Joint, Polygon, SegmentSpec},
|
||||
primitives::{JointSpec, Polygon, SegmentSpec},
|
||||
};
|
||||
|
||||
impl Board {
|
||||
|
|
@ -278,7 +278,7 @@ impl Board {
|
|||
pin: Option<PinId>,
|
||||
flip: bool,
|
||||
) {
|
||||
board.add_joint(Joint {
|
||||
board.add_joint(JointSpec {
|
||||
position: Self::pos(place, pin_pos, 0.0, 0.0, flip),
|
||||
layer,
|
||||
net,
|
||||
|
|
@ -326,7 +326,7 @@ impl Board {
|
|||
) {
|
||||
// Add the first coordinate in the wire path as a dot and save its index.
|
||||
let mut prev_pos: Vector2<i64> = Self::pos(place, pin_pos, coords[0].x, coords[0].y, flip);
|
||||
let mut prev_joint = board.add_joint(Joint {
|
||||
let mut prev_joint = board.add_joint(JointSpec {
|
||||
position: prev_pos,
|
||||
layer,
|
||||
radius: (width / 2.0) as u64,
|
||||
|
|
@ -342,7 +342,7 @@ impl Board {
|
|||
continue;
|
||||
}
|
||||
|
||||
let joint = board.add_joint(Joint {
|
||||
let joint = board.add_joint(JointSpec {
|
||||
position: pos,
|
||||
layer,
|
||||
radius: (width / 2.0) as u64,
|
||||
|
|
|
|||
Loading…
Reference in New Issue