mirror of https://codeberg.org/topola/topola.git
feat(topola-egui): Display guide-circles on debug overlay
This commit is contained in:
parent
fac52f9d8b
commit
9819879617
|
|
@ -166,6 +166,7 @@ pub struct ViewActions {
|
||||||
pub zoom_to_fit: Switch,
|
pub zoom_to_fit: Switch,
|
||||||
pub show_ratsnest: Switch,
|
pub show_ratsnest: Switch,
|
||||||
pub show_navmesh: Switch,
|
pub show_navmesh: Switch,
|
||||||
|
pub show_guide_circles: Switch,
|
||||||
pub show_triangulation: Switch,
|
pub show_triangulation: Switch,
|
||||||
pub show_triangulation_constraints: Switch,
|
pub show_triangulation_constraints: Switch,
|
||||||
pub show_pathfinding_scores: Switch,
|
pub show_pathfinding_scores: Switch,
|
||||||
|
|
@ -181,6 +182,8 @@ impl ViewActions {
|
||||||
zoom_to_fit: Action::new_keyless(tr.text("tr-menu-view-zoom-to-fit")).into_switch(),
|
zoom_to_fit: Action::new_keyless(tr.text("tr-menu-view-zoom-to-fit")).into_switch(),
|
||||||
show_ratsnest: Action::new_keyless(tr.text("tr-menu-view-show-ratsnest")).into_switch(),
|
show_ratsnest: Action::new_keyless(tr.text("tr-menu-view-show-ratsnest")).into_switch(),
|
||||||
show_navmesh: Action::new_keyless(tr.text("tr-menu-view-show-navmesh")).into_switch(),
|
show_navmesh: Action::new_keyless(tr.text("tr-menu-view-show-navmesh")).into_switch(),
|
||||||
|
show_guide_circles: Action::new_keyless(tr.text("tr-menu-view-show-guide-circles"))
|
||||||
|
.into_switch(),
|
||||||
show_triangulation: Action::new_keyless(tr.text("tr-menu-view-show-triangulation"))
|
show_triangulation: Action::new_keyless(tr.text("tr-menu-view-show-triangulation"))
|
||||||
.into_switch(),
|
.into_switch(),
|
||||||
show_triangulation_constraints: Action::new_keyless(
|
show_triangulation_constraints: Action::new_keyless(
|
||||||
|
|
@ -219,6 +222,8 @@ impl ViewActions {
|
||||||
ui.add_enabled_ui(have_workspace, |ui| {
|
ui.add_enabled_ui(have_workspace, |ui| {
|
||||||
self.show_ratsnest.checkbox(ui, &mut menu_bar.show_ratsnest);
|
self.show_ratsnest.checkbox(ui, &mut menu_bar.show_ratsnest);
|
||||||
self.show_navmesh.checkbox(ui, &mut menu_bar.show_navmesh);
|
self.show_navmesh.checkbox(ui, &mut menu_bar.show_navmesh);
|
||||||
|
self.show_guide_circles
|
||||||
|
.checkbox(ui, &mut menu_bar.show_guide_circles);
|
||||||
self.show_triangulation
|
self.show_triangulation
|
||||||
.checkbox(ui, &mut menu_bar.show_triangulation);
|
.checkbox(ui, &mut menu_bar.show_triangulation);
|
||||||
self.show_triangulation_constraints
|
self.show_triangulation_constraints
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,11 @@ use topola::{
|
||||||
autorouter::invoker::GetDebugOverlayData,
|
autorouter::invoker::GetDebugOverlayData,
|
||||||
board::AccessMesadata,
|
board::AccessMesadata,
|
||||||
drawing::{
|
drawing::{
|
||||||
|
bend::BendIndex,
|
||||||
|
dot::DotIndex,
|
||||||
graph::{MakePrimitive, PrimitiveIndex},
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
|
guide::Guide,
|
||||||
|
head::GetFace,
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
},
|
},
|
||||||
geometry::{shape::AccessShape, GenericNode},
|
geometry::{shape::AccessShape, GenericNode},
|
||||||
|
|
@ -50,8 +54,8 @@ impl<'a> Displayer<'a> {
|
||||||
self.display_ratsnest();
|
self.display_ratsnest();
|
||||||
}
|
}
|
||||||
|
|
||||||
if menu_bar.show_navmesh {
|
if menu_bar.show_navmesh || menu_bar.show_guide_circles {
|
||||||
self.display_navmesh(menu_bar);
|
self.display_navmesh_or_guides(menu_bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if menu_bar.show_triangulation {
|
if menu_bar.show_triangulation {
|
||||||
|
|
@ -158,7 +162,7 @@ impl<'a> Displayer<'a> {
|
||||||
let from = graph.node_weight(edge.source()).unwrap().pos;
|
let from = graph.node_weight(edge.source()).unwrap().pos;
|
||||||
let to = graph.node_weight(edge.target()).unwrap().pos;
|
let to = graph.node_weight(edge.target()).unwrap().pos;
|
||||||
|
|
||||||
self.painter.paint_edge(
|
self.painter.paint_line_segment(
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
egui::Stroke::new(1.0, egui::Color32::from_rgb(90, 90, 200)),
|
egui::Stroke::new(1.0, egui::Color32::from_rgb(90, 90, 200)),
|
||||||
|
|
@ -166,7 +170,7 @@ impl<'a> Displayer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_navmesh(&mut self, menu_bar: &MenuBar) {
|
fn display_navmesh_or_guides(&mut self, menu_bar: &MenuBar) {
|
||||||
let board = self.workspace.interactor.invoker().autorouter().board();
|
let board = self.workspace.interactor.invoker().autorouter().board();
|
||||||
|
|
||||||
if let Some(activity) = self.workspace.interactor.maybe_activity() {
|
if let Some(activity) = self.workspace.interactor.maybe_activity() {
|
||||||
|
|
@ -220,7 +224,9 @@ impl<'a> Displayer<'a> {
|
||||||
egui::Stroke::new(1.0, egui::Color32::from_rgb(125, 125, 125))
|
egui::Stroke::new(1.0, egui::Color32::from_rgb(125, 125, 125))
|
||||||
};
|
};
|
||||||
|
|
||||||
self.painter.paint_edge(from, to, stroke);
|
if menu_bar.show_navmesh {
|
||||||
|
self.painter.paint_line_segment(from, to, stroke);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(text) = activity.navedge_debug_text((edge.source(), edge.target()))
|
if let Some(text) = activity.navedge_debug_text((edge.source(), edge.target()))
|
||||||
{
|
{
|
||||||
|
|
@ -235,11 +241,43 @@ impl<'a> Displayer<'a> {
|
||||||
|
|
||||||
for index in navmesh.graph().node_indices() {
|
for index in navmesh.graph().node_indices() {
|
||||||
let navnode = NavnodeIndex(index);
|
let navnode = NavnodeIndex(index);
|
||||||
let mut pos = PrimitiveIndex::from(navmesh.node_weight(navnode).unwrap().node)
|
let primitive =
|
||||||
|
PrimitiveIndex::from(navmesh.node_weight(navnode).unwrap().node);
|
||||||
|
let mut pos = primitive
|
||||||
.primitive(board.layout().drawing())
|
.primitive(board.layout().drawing())
|
||||||
.shape()
|
.shape()
|
||||||
.center();
|
.center();
|
||||||
|
|
||||||
|
if menu_bar.show_guide_circles {
|
||||||
|
if let Some(navcord) = activity.maybe_navcord() {
|
||||||
|
if let Ok(dot) = DotIndex::try_from(primitive) {
|
||||||
|
let drawing = board.layout().drawing();
|
||||||
|
|
||||||
|
self.painter.paint_hollow_circle(
|
||||||
|
drawing.dot_circle(
|
||||||
|
dot,
|
||||||
|
navcord.width,
|
||||||
|
drawing.conditions(navcord.head.face().into()).as_ref(),
|
||||||
|
),
|
||||||
|
1.0,
|
||||||
|
egui::epaint::Color32::WHITE,
|
||||||
|
);
|
||||||
|
} else if let Ok(bend) = BendIndex::try_from(primitive) {
|
||||||
|
let drawing = board.layout().drawing();
|
||||||
|
|
||||||
|
self.painter.paint_hollow_circle(
|
||||||
|
drawing.bend_circle(
|
||||||
|
bend,
|
||||||
|
navcord.width,
|
||||||
|
drawing.conditions(navcord.head.face().into()).as_ref(),
|
||||||
|
),
|
||||||
|
1.0,
|
||||||
|
egui::epaint::Color32::WHITE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pos += match navmesh.node_weight(navnode).unwrap().maybe_sense {
|
pos += match navmesh.node_weight(navnode).unwrap().maybe_sense {
|
||||||
Some(RotationSense::Counterclockwise) => [0.0, 150.0].into(),
|
Some(RotationSense::Counterclockwise) => [0.0, 150.0].into(),
|
||||||
Some(RotationSense::Clockwise) => [-0.0, -150.0].into(),
|
Some(RotationSense::Clockwise) => [-0.0, -150.0].into(),
|
||||||
|
|
@ -286,7 +324,7 @@ impl<'a> Displayer<'a> {
|
||||||
.shape()
|
.shape()
|
||||||
.center();
|
.center();
|
||||||
|
|
||||||
self.painter.paint_edge(
|
self.painter.paint_line_segment(
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
egui::Stroke::new(1.0, egui::Color32::from_rgb(255, 255, 255)),
|
egui::Stroke::new(1.0, egui::Color32::from_rgb(255, 255, 255)),
|
||||||
|
|
@ -307,7 +345,7 @@ impl<'a> Displayer<'a> {
|
||||||
let from = from_weight.pos + [100.0, 100.0].into();
|
let from = from_weight.pos + [100.0, 100.0].into();
|
||||||
let to = to_weight.pos + [100.0, 100.0].into();
|
let to = to_weight.pos + [100.0, 100.0].into();
|
||||||
|
|
||||||
self.painter.paint_edge(
|
self.painter.paint_line_segment(
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
egui::Stroke::new(1.0, egui::Color32::from_rgb(255, 255, 0)),
|
egui::Stroke::new(1.0, egui::Color32::from_rgb(255, 255, 0)),
|
||||||
|
|
@ -399,14 +437,14 @@ impl<'a> Displayer<'a> {
|
||||||
offset_lhs /= offset_lhs.dot(offset_lhs).sqrt() / 50.0;
|
offset_lhs /= offset_lhs.dot(offset_lhs).sqrt() / 50.0;
|
||||||
let mut offset_rhs = rhs - middle;
|
let mut offset_rhs = rhs - middle;
|
||||||
offset_rhs /= offset_rhs.dot(offset_rhs).sqrt() / 50.0;
|
offset_rhs /= offset_rhs.dot(offset_rhs).sqrt() / 50.0;
|
||||||
self.painter.paint_edge(
|
self.painter.paint_line_segment(
|
||||||
a_pos + offset_lhs,
|
a_pos + offset_lhs,
|
||||||
b_pos + offset_lhs,
|
b_pos + offset_lhs,
|
||||||
make_stroke(edge_lens[0].len()),
|
make_stroke(edge_lens[0].len()),
|
||||||
);
|
);
|
||||||
self.painter
|
self.painter
|
||||||
.paint_edge(a_pos, b_pos, make_stroke(edge_lens[1].len()));
|
.paint_line_segment(a_pos, b_pos, make_stroke(edge_lens[1].len()));
|
||||||
self.painter.paint_edge(
|
self.painter.paint_line_segment(
|
||||||
a_pos + offset_rhs,
|
a_pos + offset_rhs,
|
||||||
b_pos + offset_rhs,
|
b_pos + offset_rhs,
|
||||||
make_stroke(edge_lens[2].len()),
|
make_stroke(edge_lens[2].len()),
|
||||||
|
|
@ -416,7 +454,8 @@ impl<'a> Displayer<'a> {
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|i| matches!(i, pie::RelaxedPath::Normal(_)))
|
.filter(|i| matches!(i, pie::RelaxedPath::Normal(_)))
|
||||||
.count();
|
.count();
|
||||||
self.painter.paint_edge(a_pos, b_pos, make_stroke(edge_len));
|
self.painter
|
||||||
|
.paint_line_segment(a_pos, b_pos, make_stroke(edge_len));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -447,25 +486,25 @@ impl<'a> Displayer<'a> {
|
||||||
activity.activity()
|
activity.activity()
|
||||||
{
|
{
|
||||||
self.painter
|
self.painter
|
||||||
.paint_linestring(&rp.lines, egui::Color32::from_rgb(245, 182, 66));
|
.paint_polyline(&rp.lines, egui::Color32::from_rgb(245, 182, 66));
|
||||||
}
|
}
|
||||||
|
|
||||||
for linestring in activity.polygonal_blockers() {
|
for linestring in activity.polygonal_blockers() {
|
||||||
self.painter
|
self.painter
|
||||||
.paint_linestring(linestring, egui::Color32::from_rgb(115, 0, 255));
|
.paint_polyline(linestring, egui::Color32::from_rgb(115, 0, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref navmesh) = activity.maybe_thetastar().map(|astar| astar.graph()) {
|
if let Some(ref navmesh) = activity.maybe_thetastar().map(|astar| astar.graph()) {
|
||||||
if menu_bar.show_origin_destination {
|
if menu_bar.show_origin_destination {
|
||||||
let (origin, destination) = (navmesh.origin(), navmesh.destination());
|
let (origin, destination) = (navmesh.origin(), navmesh.destination());
|
||||||
self.painter.paint_dot(
|
self.painter.paint_solid_circle(
|
||||||
Circle {
|
Circle {
|
||||||
pos: board.layout().drawing().primitive(origin).shape().center(),
|
pos: board.layout().drawing().primitive(origin).shape().center(),
|
||||||
r: 150.0,
|
r: 150.0,
|
||||||
},
|
},
|
||||||
egui::Color32::from_rgb(255, 255, 100),
|
egui::Color32::from_rgb(255, 255, 100),
|
||||||
);
|
);
|
||||||
self.painter.paint_dot(
|
self.painter.paint_solid_circle(
|
||||||
Circle {
|
Circle {
|
||||||
pos: board
|
pos: board
|
||||||
.layout()
|
.layout()
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ pub struct MenuBar {
|
||||||
pub is_placing_via: bool,
|
pub is_placing_via: bool,
|
||||||
pub show_ratsnest: bool,
|
pub show_ratsnest: bool,
|
||||||
pub show_navmesh: bool,
|
pub show_navmesh: bool,
|
||||||
|
pub show_guide_circles: bool,
|
||||||
pub show_triangulation: bool,
|
pub show_triangulation: bool,
|
||||||
pub show_triangulation_constraints: bool,
|
pub show_triangulation_constraints: bool,
|
||||||
pub show_pathfinding_scores: bool,
|
pub show_pathfinding_scores: bool,
|
||||||
|
|
@ -54,6 +55,7 @@ impl MenuBar {
|
||||||
is_placing_via: false,
|
is_placing_via: false,
|
||||||
show_ratsnest: true,
|
show_ratsnest: true,
|
||||||
show_navmesh: false,
|
show_navmesh: false,
|
||||||
|
show_guide_circles: false,
|
||||||
show_triangulation: false,
|
show_triangulation: false,
|
||||||
show_triangulation_constraints: false,
|
show_triangulation_constraints: false,
|
||||||
show_pathfinding_scores: false,
|
show_pathfinding_scores: false,
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ impl<'a> Painter<'a> {
|
||||||
|
|
||||||
pub fn paint_primitive(&mut self, shape: &PrimitiveShape, color: egui::epaint::Color32) {
|
pub fn paint_primitive(&mut self, shape: &PrimitiveShape, color: egui::epaint::Color32) {
|
||||||
let epaint_shape = match shape {
|
let epaint_shape = match shape {
|
||||||
PrimitiveShape::Dot(dot) => self.dot_shape(dot.circle, color),
|
PrimitiveShape::Dot(dot) => self.solid_circle_shape(dot.circle, color),
|
||||||
PrimitiveShape::Seg(seg) => egui::Shape::line_segment(
|
PrimitiveShape::Seg(seg) => egui::Shape::line_segment(
|
||||||
[
|
[
|
||||||
self.transform
|
self.transform
|
||||||
|
|
@ -75,12 +75,26 @@ impl<'a> Painter<'a> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint_dot(&mut self, circle: Circle, color: egui::epaint::Color32) {
|
pub fn paint_hollow_circle(
|
||||||
let shape = self.dot_shape(circle, color);
|
&mut self,
|
||||||
|
circle: Circle,
|
||||||
|
width: f32,
|
||||||
|
color: egui::epaint::Color32,
|
||||||
|
) {
|
||||||
|
self.ui.painter().add(egui::Shape::circle_stroke(
|
||||||
|
self.transform
|
||||||
|
.mul_pos([circle.pos.x() as f32, -circle.pos.y() as f32].into()),
|
||||||
|
circle.r as f32 * self.transform.scaling,
|
||||||
|
egui::Stroke { width, color },
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn paint_solid_circle(&mut self, circle: Circle, color: egui::epaint::Color32) {
|
||||||
|
let shape = self.solid_circle_shape(circle, color);
|
||||||
self.ui.painter().add(shape);
|
self.ui.painter().add(shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dot_shape(&mut self, circle: Circle, color: egui::epaint::Color32) -> egui::Shape {
|
fn solid_circle_shape(&mut self, circle: Circle, color: egui::epaint::Color32) -> egui::Shape {
|
||||||
egui::Shape::circle_filled(
|
egui::Shape::circle_filled(
|
||||||
self.transform
|
self.transform
|
||||||
.mul_pos([circle.pos.x() as f32, -circle.pos.y() as f32].into()),
|
.mul_pos([circle.pos.x() as f32, -circle.pos.y() as f32].into()),
|
||||||
|
|
@ -89,7 +103,7 @@ impl<'a> Painter<'a> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint_linestring(&mut self, linestring: &LineString, color: egui::epaint::Color32) {
|
pub fn paint_polyline(&mut self, linestring: &LineString, color: egui::epaint::Color32) {
|
||||||
self.ui.painter().add(egui::Shape::line(
|
self.ui.painter().add(egui::Shape::line(
|
||||||
linestring
|
linestring
|
||||||
.exterior_coords_iter()
|
.exterior_coords_iter()
|
||||||
|
|
@ -120,7 +134,7 @@ impl<'a> Painter<'a> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint_edge(&mut self, from: Point, to: Point, stroke: egui::Stroke) {
|
pub fn paint_line_segment(&mut self, from: Point, to: Point, stroke: egui::Stroke) {
|
||||||
self.ui.painter().add(egui::Shape::line_segment(
|
self.ui.painter().add(egui::Shape::line_segment(
|
||||||
[
|
[
|
||||||
self.transform
|
self.transform
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ tr-menu-view = View
|
||||||
tr-menu-view-zoom-to-fit = Zoom to Fit
|
tr-menu-view-zoom-to-fit = Zoom to Fit
|
||||||
tr-menu-view-show-ratsnest = Show Ratsnest
|
tr-menu-view-show-ratsnest = Show Ratsnest
|
||||||
tr-menu-view-show-navmesh = Show Navmesh
|
tr-menu-view-show-navmesh = Show Navmesh
|
||||||
|
tr-menu-view-show-guide-circles = Show Guide-Circles
|
||||||
tr-menu-view-show-triangulation = Show Triangulation
|
tr-menu-view-show-triangulation = Show Triangulation
|
||||||
tr-menu-view-show-triangulation-constraints = Show Triangulation Constraints
|
tr-menu-view-show-triangulation-constraints = Show Triangulation Constraints
|
||||||
tr-menu-view-show-pathfinding-scores = Show Pathfinding Scores
|
tr-menu-view-show-pathfinding-scores = Show Pathfinding Scores
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,8 @@ use crate::{
|
||||||
AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel,
|
AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel,
|
||||||
GetLayer, GetOffset, GetSetPos, GetWidth,
|
GetLayer, GetOffset, GetSetPos, GetWidth,
|
||||||
},
|
},
|
||||||
graph::MakeRef,
|
graph::{GenericIndex, GetPetgraphIndex, MakeRef},
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
math::{NoTangents, RotationSense},
|
||||||
math::NoTangents,
|
|
||||||
math::RotationSense,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::gear::{GetOuterGears, WalkOutwards};
|
use super::gear::{GetOuterGears, WalkOutwards};
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,22 @@ pub trait Guide {
|
||||||
fn rear_head(&self, face: LooseDotIndex) -> Head;
|
fn rear_head(&self, face: LooseDotIndex) -> Head;
|
||||||
|
|
||||||
fn head(&self, face: DotIndex) -> Head;
|
fn head(&self, face: DotIndex) -> Head;
|
||||||
|
|
||||||
|
fn bend_circle(
|
||||||
|
&self,
|
||||||
|
bend: BendIndex,
|
||||||
|
width: f64,
|
||||||
|
guide_conditions: Option<&Conditions<'_>>,
|
||||||
|
) -> Circle;
|
||||||
|
|
||||||
|
fn dot_circle(
|
||||||
|
&self,
|
||||||
|
dot: DotIndex,
|
||||||
|
width: f64,
|
||||||
|
guide_conditions: Option<&Conditions<'_>>,
|
||||||
|
) -> Circle;
|
||||||
|
|
||||||
|
fn conditions(&self, node: PrimitiveIndex) -> Option<Conditions<'_>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CW: Clone, Cel: Copy, R: AccessRules> Guide for Drawing<CW, Cel, R> {
|
impl<CW: Clone, Cel: Copy, R: AccessRules> Guide for Drawing<CW, Cel, R> {
|
||||||
|
|
@ -200,6 +216,44 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Guide for Drawing<CW, Cel, R> {
|
||||||
DotIndex::Loose(dot) => self.cane_head(dot).into(),
|
DotIndex::Loose(dot) => self.cane_head(dot).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dot_circle(
|
||||||
|
&self,
|
||||||
|
dot: DotIndex,
|
||||||
|
width: f64,
|
||||||
|
guide_conditions: Option<&Conditions<'_>>,
|
||||||
|
) -> Circle {
|
||||||
|
let shape = dot.primitive(self).shape();
|
||||||
|
Circle {
|
||||||
|
pos: shape.center(),
|
||||||
|
r: shape.width() / 2.0
|
||||||
|
+ width / 2.0
|
||||||
|
+ self.clearance(self.conditions(dot.into()).as_ref(), guide_conditions),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bend_circle(
|
||||||
|
&self,
|
||||||
|
bend: BendIndex,
|
||||||
|
width: f64,
|
||||||
|
guide_conditions: Option<&Conditions<'_>>,
|
||||||
|
) -> Circle {
|
||||||
|
let outer_circle = match bend.primitive(self).shape() {
|
||||||
|
PrimitiveShape::Bend(shape) => shape.outer_circle(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Circle {
|
||||||
|
pos: outer_circle.pos,
|
||||||
|
r: outer_circle.r
|
||||||
|
+ width / 2.0
|
||||||
|
+ self.clearance(self.conditions(bend.into()).as_ref(), guide_conditions),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn conditions(&self, node: PrimitiveIndex) -> Option<Conditions<'_>> {
|
||||||
|
node.primitive(self).conditions()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait GuidePrivate {
|
trait GuidePrivate {
|
||||||
|
|
@ -207,23 +261,7 @@ trait GuidePrivate {
|
||||||
|
|
||||||
fn head_circle(&self, head: &Head, width: f64) -> Circle;
|
fn head_circle(&self, head: &Head, width: f64) -> Circle;
|
||||||
|
|
||||||
fn bend_circle(
|
|
||||||
&self,
|
|
||||||
bend: BendIndex,
|
|
||||||
width: f64,
|
|
||||||
guide_conditions: Option<&Conditions<'_>>,
|
|
||||||
) -> Circle;
|
|
||||||
|
|
||||||
fn dot_circle(
|
|
||||||
&self,
|
|
||||||
dot: DotIndex,
|
|
||||||
width: f64,
|
|
||||||
guide_conditions: Option<&Conditions<'_>>,
|
|
||||||
) -> Circle;
|
|
||||||
|
|
||||||
fn rear(&self, head: CaneHead) -> DotIndex;
|
fn rear(&self, head: CaneHead) -> DotIndex;
|
||||||
|
|
||||||
fn conditions(&self, node: PrimitiveIndex) -> Option<Conditions<'_>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CW: Clone, Cel: Copy, R: AccessRules> GuidePrivate for Drawing<CW, Cel, R> {
|
impl<CW: Clone, Cel: Copy, R: AccessRules> GuidePrivate for Drawing<CW, Cel, R> {
|
||||||
|
|
@ -258,46 +296,8 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> GuidePrivate for Drawing<CW, Cel, R>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bend_circle(
|
|
||||||
&self,
|
|
||||||
bend: BendIndex,
|
|
||||||
width: f64,
|
|
||||||
guide_conditions: Option<&Conditions<'_>>,
|
|
||||||
) -> Circle {
|
|
||||||
let outer_circle = match bend.primitive(self).shape() {
|
|
||||||
PrimitiveShape::Bend(shape) => shape.outer_circle(),
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Circle {
|
|
||||||
pos: outer_circle.pos,
|
|
||||||
r: outer_circle.r
|
|
||||||
+ width / 2.0
|
|
||||||
+ self.clearance(self.conditions(bend.into()).as_ref(), guide_conditions),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dot_circle(
|
|
||||||
&self,
|
|
||||||
dot: DotIndex,
|
|
||||||
width: f64,
|
|
||||||
guide_conditions: Option<&Conditions<'_>>,
|
|
||||||
) -> Circle {
|
|
||||||
let shape = dot.primitive(self).shape();
|
|
||||||
Circle {
|
|
||||||
pos: shape.center(),
|
|
||||||
r: shape.width() / 2.0
|
|
||||||
+ width / 2.0
|
|
||||||
+ self.clearance(self.conditions(dot.into()).as_ref(), guide_conditions),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rear(&self, head: CaneHead) -> DotIndex {
|
fn rear(&self, head: CaneHead) -> DotIndex {
|
||||||
self.primitive(head.cane.seg)
|
self.primitive(head.cane.seg)
|
||||||
.other_joint(head.cane.dot.into())
|
.other_joint(head.cane.dot.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn conditions(&self, node: PrimitiveIndex) -> Option<Conditions<'_>> {
|
|
||||||
node.primitive(self).conditions()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ mod collect;
|
||||||
pub mod dot;
|
pub mod dot;
|
||||||
mod drawing;
|
mod drawing;
|
||||||
pub mod gear;
|
pub mod gear;
|
||||||
mod guide;
|
pub mod guide;
|
||||||
pub mod head;
|
pub mod head;
|
||||||
pub mod loose;
|
pub mod loose;
|
||||||
pub mod primitive;
|
pub mod primitive;
|
||||||
|
|
@ -21,4 +21,3 @@ pub mod seg;
|
||||||
pub use cane::Cane;
|
pub use cane::Cane;
|
||||||
pub use collect::Collect;
|
pub use collect::Collect;
|
||||||
pub use drawing::*;
|
pub use drawing::*;
|
||||||
pub use guide::Guide;
|
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,12 @@ use crate::{
|
||||||
dot::{DotIndex, FixedDotIndex, GeneralDotWeight, LooseDotIndex, LooseDotWeight},
|
dot::{DotIndex, FixedDotIndex, GeneralDotWeight, LooseDotIndex, LooseDotWeight},
|
||||||
gear::GearIndex,
|
gear::GearIndex,
|
||||||
graph::{GetMaybeNet, MakePrimitive},
|
graph::{GetMaybeNet, MakePrimitive},
|
||||||
|
guide::Guide,
|
||||||
head::{CaneHead, GetFace, Head},
|
head::{CaneHead, GetFace, Head},
|
||||||
primitive::GetOtherJoint,
|
primitive::GetOtherJoint,
|
||||||
rules::AccessRules,
|
rules::AccessRules,
|
||||||
seg::{GeneralSegWeight, LoneLooseSegWeight, SeqLooseSegWeight},
|
seg::{GeneralSegWeight, LoneLooseSegWeight, SeqLooseSegWeight},
|
||||||
DrawingException, Guide, Infringement,
|
DrawingException, Infringement,
|
||||||
},
|
},
|
||||||
geometry::{GetLayer, GetSetPos},
|
geometry::{GetLayer, GetSetPos},
|
||||||
layout::{Layout, LayoutEdit},
|
layout::{Layout, LayoutEdit},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue