mirror of https://codeberg.org/topola/topola.git
feat: use topola-rules / put 'AccessRules' into separate crate
This commit is contained in:
parent
67c4933b09
commit
910ab5b76a
|
|
@ -28,6 +28,7 @@ fp-info-cache
|
||||||
|
|
||||||
# Lockfiles
|
# Lockfiles
|
||||||
*.lck
|
*.lck
|
||||||
|
.#*
|
||||||
|
|
||||||
# ---> Topola
|
# ---> Topola
|
||||||
*.ses
|
*.ses
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ geo-types.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
specctra_derive.path = "../specctra_derive"
|
specctra_derive.path = "../specctra_derive"
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
|
topola-rules.path = "../topola-rules"
|
||||||
utf8-chars = "3.0"
|
utf8-chars = "3.0"
|
||||||
|
|
||||||
[dependencies.rstar]
|
[dependencies.rstar]
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ pub mod error;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
pub mod mesadata;
|
pub mod mesadata;
|
||||||
pub mod read;
|
pub mod read;
|
||||||
pub mod rules;
|
pub use topola_rules as rules;
|
||||||
pub mod structure;
|
pub mod structure;
|
||||||
pub mod write;
|
pub mod write;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use bimap::BiBTreeMap;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
rules::{AccessRules, Conditions},
|
rules::{AccessRules, Conditions, OrderedPair},
|
||||||
structure::Pcb,
|
structure::Pcb,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@ use crate::{
|
||||||
///
|
///
|
||||||
/// This trait implements generic function for accessing or modifying different
|
/// This trait implements generic function for accessing or modifying different
|
||||||
/// compounds of board parts like nets or layers
|
/// compounds of board parts like nets or layers
|
||||||
pub trait AccessMesadata: AccessRules {
|
pub trait AccessMesadata: AccessRules<Scalar = f64, ObjectKind = ()> {
|
||||||
/// Renames a layer based on its index.
|
/// Renames a layer based on its index.
|
||||||
fn bename_layer(&mut self, layer: usize, layername: String);
|
fn bename_layer(&mut self, layer: usize, layername: String);
|
||||||
|
|
||||||
|
|
@ -178,19 +178,16 @@ impl SpecctraMesadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AccessRules for SpecctraMesadata {
|
impl AccessRules for SpecctraMesadata {
|
||||||
fn clearance(&self, conditions1: &Conditions, conditions2: &Conditions) -> f64 {
|
type Scalar = f64;
|
||||||
let (Some(net1), Some(net2)) = (conditions1.maybe_net, conditions2.maybe_net) else {
|
type ObjectKind = ();
|
||||||
return 0.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
let clr1 = self.get_rule(net1).clearance;
|
fn clearance(&self, conditions: OrderedPair<&Conditions<'_, ()>>) -> f64 {
|
||||||
let clr2 = self.get_rule(net2).clearance;
|
let (conditions1, conditions2) = conditions.into();
|
||||||
|
|
||||||
if clr1 > clr2 {
|
let clr1 = self.get_rule(conditions1.net).clearance;
|
||||||
clr1
|
let clr2 = self.get_rule(conditions2.net).clearance;
|
||||||
} else {
|
|
||||||
clr2
|
f64::max(clr1, clr2)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn largest_clearance(&self, _maybe_net: Option<usize>) -> f64 {
|
fn largest_clearance(&self, _maybe_net: Option<usize>) -> f64 {
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2024 Topola contributors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pub trait GetConditions {
|
|
||||||
fn conditions(&self) -> Conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct Conditions {
|
|
||||||
pub maybe_net: Option<usize>,
|
|
||||||
pub maybe_region: Option<String>,
|
|
||||||
pub maybe_layer: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait AccessRules {
|
|
||||||
fn clearance(&self, conditions1: &Conditions, conditions2: &Conditions) -> f64;
|
|
||||||
fn largest_clearance(&self, net: Option<usize>) -> f64;
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
# SPDX-FileCopyrightText: 2024 Topola contributors
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "topola-rules"
|
||||||
|
version = "0.1.1"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
repository = "https://codeberg.org/topola/topola"
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
features = ["serde"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
[dependencies.serde]
|
||||||
|
version = "1.0"
|
||||||
|
features = ["derive", "alloc"]
|
||||||
|
default-features = false
|
||||||
|
optional = true
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# topola-rules
|
||||||
|
|
||||||
|
Generic design rules/clearance handling.
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Topola contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
//
|
||||||
|
//! Generic design rules/clearance handling.
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use alloc::borrow::Cow;
|
||||||
|
use core::ops;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
|
#[cfg_attr(feature = "serde", serde(from = "(T, T)", into = "(T, T)"))]
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "serde",
|
||||||
|
serde(bound(
|
||||||
|
deserialize = "T: serde::Deserialize<'de> + Ord",
|
||||||
|
serialize = "T: serde::Serialize + Clone"
|
||||||
|
))
|
||||||
|
)]
|
||||||
|
pub struct OrderedPair<T>(T, T);
|
||||||
|
|
||||||
|
impl<T> ops::Index<bool> for OrderedPair<T> {
|
||||||
|
type Output = T;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index(&self, index: bool) -> &T {
|
||||||
|
if index { &self.1 } else { &self.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Ord> From<(T, T)> for OrderedPair<T> {
|
||||||
|
fn from(mut x: (T, T)) -> Self {
|
||||||
|
if x.0 > x.1 {
|
||||||
|
core::mem::swap(&mut x.0, &mut x.1);
|
||||||
|
}
|
||||||
|
let (a, b) = x;
|
||||||
|
Self(a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<OrderedPair<T>> for (T, T) {
|
||||||
|
#[inline(always)]
|
||||||
|
fn from(OrderedPair(a, b): OrderedPair<T>) -> (T, T) {
|
||||||
|
(a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
|
pub struct Conditions<'a, K> {
|
||||||
|
pub net: usize,
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "serde", serde(borrow))]
|
||||||
|
pub maybe_region: Option<Cow<'a, str>>,
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "serde", serde(borrow))]
|
||||||
|
pub maybe_layer: Option<Cow<'a, str>>,
|
||||||
|
|
||||||
|
pub kind: K,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K: Copy> Conditions<'_, K> {
|
||||||
|
#[inline]
|
||||||
|
pub fn ref_(&self) -> Conditions<'_, K> {
|
||||||
|
Conditions {
|
||||||
|
net: self.net,
|
||||||
|
maybe_region: self.maybe_region.as_ref().map(|i| Cow::Borrowed(&**i)),
|
||||||
|
maybe_layer: self.maybe_layer.as_ref().map(|i| Cow::Borrowed(&**i)),
|
||||||
|
kind: self.kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GetConditions<'a>: Sized {
|
||||||
|
type ObjectKind: Copy + Eq;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn conditions(self) -> Option<Conditions<'a, Self::ObjectKind>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, K: Copy + Eq> GetConditions<'a> for &'a Conditions<'_, K> {
|
||||||
|
type ObjectKind = K;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn conditions(self) -> Option<Conditions<'a, K>> {
|
||||||
|
Some(self.ref_())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Copy + GetConditions<'a>> GetConditions<'a> for &T {
|
||||||
|
type ObjectKind = <T as GetConditions<'a>>::ObjectKind;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn conditions(self) -> Option<Conditions<'a, <T as GetConditions<'a>>::ObjectKind>> {
|
||||||
|
T::conditions(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GetWidth {
|
||||||
|
type Scalar: Copy;
|
||||||
|
|
||||||
|
fn width(&self) -> Self::Scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: GetWidth> GetWidth for &T {
|
||||||
|
type Scalar = <T as GetWidth>::Scalar;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn width(&self) -> <T as GetWidth>::Scalar {
|
||||||
|
T::width(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait AccessRules {
|
||||||
|
type Scalar: Copy + core::ops::Add<Output = Self::Scalar> + core::iter::Sum;
|
||||||
|
type ObjectKind: Copy + Eq;
|
||||||
|
|
||||||
|
fn clearance(&self, conditions: OrderedPair<&Conditions<'_, Self::ObjectKind>>)
|
||||||
|
-> Self::Scalar;
|
||||||
|
fn largest_clearance(&self, maybe_net: Option<usize>) -> Self::Scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AccessRules + Copy> AccessRules for &T {
|
||||||
|
type Scalar = <T as AccessRules>::Scalar;
|
||||||
|
type ObjectKind = <T as AccessRules>::ObjectKind;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn clearance(
|
||||||
|
&self,
|
||||||
|
conditions: OrderedPair<&Conditions<'_, <T as AccessRules>::ObjectKind>>,
|
||||||
|
) -> <T as AccessRules>::Scalar {
|
||||||
|
T::clearance(*self, conditions)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn largest_clearance(&self, maybe_net: Option<usize>) -> <T as AccessRules>::Scalar {
|
||||||
|
T::largest_clearance(*self, maybe_net)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AccessRules + ?Sized> AccessRules for alloc::sync::Arc<T> {
|
||||||
|
type Scalar = <T as AccessRules>::Scalar;
|
||||||
|
type ObjectKind = <T as AccessRules>::ObjectKind;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn clearance(
|
||||||
|
&self,
|
||||||
|
conditions: OrderedPair<&Conditions<'_, <T as AccessRules>::ObjectKind>>,
|
||||||
|
) -> <T as AccessRules>::Scalar {
|
||||||
|
T::clearance(self, conditions)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn largest_clearance(&self, maybe_net: Option<usize>) -> <T as AccessRules>::Scalar {
|
||||||
|
T::largest_clearance(self, maybe_net)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ use crate::{
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
graph::{GetMaybeNet, MakePrimitive, PrimitiveIndex},
|
graph::{GetMaybeNet, MakePrimitive, PrimitiveIndex},
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
rules::AccessRules,
|
AccessRules,
|
||||||
},
|
},
|
||||||
geometry::shape::AccessShape,
|
geometry::shape::AccessShape,
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,8 @@ use super::{
|
||||||
graph::MakePrimitive,
|
graph::MakePrimitive,
|
||||||
loose::{GetPrevNextLoose, LooseIndex},
|
loose::{GetPrevNextLoose, LooseIndex},
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
rules::AccessRules,
|
|
||||||
seg::{LoneLooseSegIndex, SeqLooseSegIndex},
|
seg::{LoneLooseSegIndex, SeqLooseSegIndex},
|
||||||
Drawing,
|
AccessRules, Drawing,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@ use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight, Retag},
|
graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight, Retag},
|
||||||
primitive::{GenericPrimitive, Primitive},
|
primitive::{GenericPrimitive, Primitive},
|
||||||
rules::AccessRules,
|
AccessRules, Drawing,
|
||||||
Drawing,
|
|
||||||
},
|
},
|
||||||
geometry::{GetOffset, GetWidth, SetOffset},
|
geometry::{GetOffset, GetWidth, SetOffset},
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,8 @@ use super::{
|
||||||
dot::LooseDotIndex,
|
dot::LooseDotIndex,
|
||||||
graph::PrimitiveIndex,
|
graph::PrimitiveIndex,
|
||||||
primitive::{GetInterior, GetJoints, GetOtherJoint, LooseBend, LooseDot},
|
primitive::{GetInterior, GetJoints, GetOtherJoint, LooseBend, LooseDot},
|
||||||
rules::AccessRules,
|
|
||||||
seg::SeqLooseSegIndex,
|
seg::SeqLooseSegIndex,
|
||||||
Drawing,
|
AccessRules, Drawing,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A cane is a sequence consisting of a seg followed by a dot followed by a
|
/// A cane is a sequence consisting of a seg followed by a dot followed by a
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ use super::{
|
||||||
graph::PrimitiveIndex,
|
graph::PrimitiveIndex,
|
||||||
loose::{GetPrevNextLoose, LooseIndex},
|
loose::{GetPrevNextLoose, LooseIndex},
|
||||||
primitive::{GetInnerOuter, GetJoints},
|
primitive::{GetInnerOuter, GetJoints},
|
||||||
rules::AccessRules,
|
AccessRules, Drawing,
|
||||||
Drawing,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Collect {
|
pub trait Collect {
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight, Retag},
|
graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight, Retag},
|
||||||
primitive::{GenericPrimitive, Primitive},
|
primitive::{GenericPrimitive, Primitive},
|
||||||
rules::AccessRules,
|
AccessRules, Drawing,
|
||||||
Drawing,
|
|
||||||
},
|
},
|
||||||
geometry::{GetSetPos, GetWidth},
|
geometry::{GetSetPos, GetWidth},
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,12 @@ use crate::{
|
||||||
GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetLimbs, GetOtherJoint,
|
GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetLimbs, GetOtherJoint,
|
||||||
MakePrimitiveShape,
|
MakePrimitiveShape,
|
||||||
},
|
},
|
||||||
rules::{AccessRules, GetConditions},
|
rules::GetConditions,
|
||||||
seg::{
|
seg::{
|
||||||
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
||||||
SegWeight, SeqLooseSegIndex, SeqLooseSegWeight,
|
SegWeight, SeqLooseSegIndex, SeqLooseSegWeight,
|
||||||
},
|
},
|
||||||
|
AccessRules,
|
||||||
},
|
},
|
||||||
graph::MakeRef,
|
graph::MakeRef,
|
||||||
};
|
};
|
||||||
|
|
@ -982,8 +983,12 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
|
|
||||||
let epsilon = 1.0;
|
let epsilon = 1.0;
|
||||||
inflated_shape = node.primitive(self).shape().inflate(
|
inflated_shape = node.primitive(self).shape().inflate(
|
||||||
(self.rules.clearance(&conditions, &infringee_conditions) - epsilon)
|
match (&conditions, infringee_conditions) {
|
||||||
|
(None, _) | (_, None) => 0.0,
|
||||||
|
(Some(lhs), Some(rhs)) => (self.rules.clearance((lhs, &rhs).into())
|
||||||
|
- epsilon)
|
||||||
.clamp(0.0, f64::INFINITY),
|
.clamp(0.0, f64::INFINITY),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
inflated_shape
|
inflated_shape
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ use crate::{
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
graph::{MakePrimitive, PrimitiveIndex},
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
primitive::{FixedBend, FixedDot, GetFirstGear, GetInnerOuter, LooseBend, Primitive},
|
primitive::{FixedBend, FixedDot, GetFirstGear, GetInnerOuter, LooseBend, Primitive},
|
||||||
rules::AccessRules,
|
AccessRules, Drawing,
|
||||||
Drawing,
|
|
||||||
},
|
},
|
||||||
graph::{GetPetgraphIndex, MakeRef},
|
graph::{GetPetgraphIndex, MakeRef},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@ use super::{
|
||||||
bend::{FixedBendIndex, FixedBendWeight, LooseBendIndex, LooseBendWeight},
|
bend::{FixedBendIndex, FixedBendWeight, LooseBendIndex, LooseBendWeight},
|
||||||
dot::{FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
dot::{FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
||||||
primitive::Primitive,
|
primitive::Primitive,
|
||||||
rules::AccessRules,
|
|
||||||
seg::{
|
seg::{
|
||||||
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex,
|
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex,
|
||||||
SeqLooseSegWeight,
|
SeqLooseSegWeight,
|
||||||
},
|
},
|
||||||
|
AccessRules,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@ use super::{
|
||||||
graph::{MakePrimitive, PrimitiveIndex},
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
head::{BareHead, CaneHead, GetFace, Head},
|
head::{BareHead, CaneHead, GetFace, Head},
|
||||||
primitive::{GetCore, GetInnerOuter, GetJoints, GetOtherJoint, GetWeight, MakePrimitiveShape},
|
primitive::{GetCore, GetInnerOuter, GetJoints, GetOtherJoint, GetWeight, MakePrimitiveShape},
|
||||||
rules::{AccessRules, Conditions, GetConditions},
|
rules::{Conditions, GetConditions},
|
||||||
Drawing,
|
AccessRules, Drawing,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Guide {
|
pub trait Guide {
|
||||||
|
|
@ -97,7 +97,8 @@ impl<CW: Copy, R: AccessRules> Guide for Drawing<CW, R> {
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<(Line, Line), NoTangents> {
|
) -> Result<(Line, Line), NoTangents> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
let to_circle = self.dot_circle(around, width, &self.conditions(head.face().into()));
|
let to_circle =
|
||||||
|
self.dot_circle(around, width, self.conditions(head.face().into()).as_ref());
|
||||||
|
|
||||||
let from_cw = self.head_cw(head);
|
let from_cw = self.head_cw(head);
|
||||||
let tangents: Vec<Line> =
|
let tangents: Vec<Line> =
|
||||||
|
|
@ -113,16 +114,17 @@ impl<CW: Copy, R: AccessRules> Guide for Drawing<CW, R> {
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<Line, NoTangents> {
|
) -> Result<Line, NoTangents> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
let to_circle = self.dot_circle(around, width, &self.conditions(head.face().into()));
|
let to_circle =
|
||||||
|
self.dot_circle(around, width, self.conditions(head.face().into()).as_ref());
|
||||||
|
|
||||||
let from_cw = self.head_cw(head);
|
let from_cw = self.head_cw(head);
|
||||||
math::tangent_segment(from_circle, from_cw, to_circle, Some(cw))
|
math::tangent_segment(from_circle, from_cw, to_circle, Some(cw))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn head_around_dot_offset(&self, head: &Head, around: DotIndex, _width: f64) -> f64 {
|
fn head_around_dot_offset(&self, head: &Head, around: DotIndex, _width: f64) -> f64 {
|
||||||
self.rules().clearance(
|
self.clearance(
|
||||||
&self.conditions(around.into()),
|
self.conditions(around.into()).as_ref(),
|
||||||
&self.conditions(head.face().into()),
|
self.conditions(head.face().into()).as_ref(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,7 +135,8 @@ impl<CW: Copy, R: AccessRules> Guide for Drawing<CW, R> {
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<(Line, Line), NoTangents> {
|
) -> Result<(Line, Line), NoTangents> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
let to_circle = self.bend_circle(around, width, &self.conditions(head.face().into()));
|
let to_circle =
|
||||||
|
self.bend_circle(around, width, self.conditions(head.face().into()).as_ref());
|
||||||
|
|
||||||
let from_cw = self.head_cw(head);
|
let from_cw = self.head_cw(head);
|
||||||
let tangents: Vec<Line> =
|
let tangents: Vec<Line> =
|
||||||
|
|
@ -149,16 +152,17 @@ impl<CW: Copy, R: AccessRules> Guide for Drawing<CW, R> {
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<Line, NoTangents> {
|
) -> Result<Line, NoTangents> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
let to_circle = self.bend_circle(around, width, &self.conditions(head.face().into()));
|
let to_circle =
|
||||||
|
self.bend_circle(around, width, self.conditions(head.face().into()).as_ref());
|
||||||
|
|
||||||
let from_cw = self.head_cw(head);
|
let from_cw = self.head_cw(head);
|
||||||
math::tangent_segment(from_circle, from_cw, to_circle, Some(cw))
|
math::tangent_segment(from_circle, from_cw, to_circle, Some(cw))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn head_around_bend_offset(&self, head: &Head, around: BendIndex, _width: f64) -> f64 {
|
fn head_around_bend_offset(&self, head: &Head, around: BendIndex, _width: f64) -> f64 {
|
||||||
self.rules().clearance(
|
self.clearance(
|
||||||
&self.conditions(head.face().into()),
|
self.conditions(head.face().into()).as_ref(),
|
||||||
&self.conditions(around.into()),
|
self.conditions(around.into()).as_ref(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,18 +200,37 @@ impl<CW: Copy, R: AccessRules> Guide for Drawing<CW, R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait GuidePrivate {
|
trait GuidePrivate {
|
||||||
|
fn clearance(&self, lhs: Option<&Conditions<'_, ()>>, rhs: Option<&Conditions<'_, ()>>) -> f64;
|
||||||
|
|
||||||
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: &Conditions) -> Circle;
|
fn bend_circle(
|
||||||
|
&self,
|
||||||
|
bend: BendIndex,
|
||||||
|
width: f64,
|
||||||
|
guide_conditions: Option<&Conditions<'_, ()>>,
|
||||||
|
) -> Circle;
|
||||||
|
|
||||||
fn dot_circle(&self, dot: DotIndex, width: f64, guide_conditions: &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) -> Conditions;
|
fn conditions(&self, node: PrimitiveIndex) -> Option<Conditions<'_, ()>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CW: Copy, R: AccessRules> GuidePrivate for Drawing<CW, R> {
|
impl<CW: Copy, R: AccessRules> GuidePrivate for Drawing<CW, R> {
|
||||||
|
fn clearance(&self, lhs: Option<&Conditions<'_, ()>>, rhs: Option<&Conditions<'_, ()>>) -> f64 {
|
||||||
|
match (lhs, rhs) {
|
||||||
|
(None, _) | (_, None) => 0.0,
|
||||||
|
(Some(lhs), Some(rhs)) => self.rules().clearance((lhs, rhs).into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn head_circle(&self, head: &Head, width: f64) -> Circle {
|
fn head_circle(&self, head: &Head, width: f64) -> Circle {
|
||||||
match *head {
|
match *head {
|
||||||
Head::Bare(head) => Circle {
|
Head::Bare(head) => Circle {
|
||||||
|
|
@ -216,19 +239,28 @@ impl<CW: Copy, R: AccessRules> GuidePrivate for Drawing<CW, R> {
|
||||||
},
|
},
|
||||||
Head::Cane(head) => {
|
Head::Cane(head) => {
|
||||||
if let Some(inner) = self.primitive(head.cane.bend).inner() {
|
if let Some(inner) = self.primitive(head.cane.bend).inner() {
|
||||||
self.bend_circle(inner.into(), width, &self.conditions(head.face().into()))
|
self.bend_circle(
|
||||||
|
inner.into(),
|
||||||
|
width,
|
||||||
|
self.conditions(head.face().into()).as_ref(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
self.dot_circle(
|
self.dot_circle(
|
||||||
self.primitive(head.cane.bend).core().into(),
|
self.primitive(head.cane.bend).core().into(),
|
||||||
width,
|
width,
|
||||||
&self.conditions(head.face().into()),
|
self.conditions(head.face().into()).as_ref(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bend_circle(&self, bend: BendIndex, width: f64, guide_conditions: &Conditions) -> Circle {
|
fn bend_circle(
|
||||||
|
&self,
|
||||||
|
bend: BendIndex,
|
||||||
|
width: f64,
|
||||||
|
guide_conditions: Option<&Conditions<'_, ()>>,
|
||||||
|
) -> Circle {
|
||||||
let outer_circle = match bend.primitive(self).shape() {
|
let outer_circle = match bend.primitive(self).shape() {
|
||||||
PrimitiveShape::Bend(shape) => shape.outer_circle(),
|
PrimitiveShape::Bend(shape) => shape.outer_circle(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|
@ -238,21 +270,22 @@ impl<CW: Copy, R: AccessRules> GuidePrivate for Drawing<CW, R> {
|
||||||
pos: outer_circle.pos,
|
pos: outer_circle.pos,
|
||||||
r: outer_circle.r
|
r: outer_circle.r
|
||||||
+ width / 2.0
|
+ width / 2.0
|
||||||
+ self
|
+ self.clearance(self.conditions(bend.into()).as_ref(), guide_conditions),
|
||||||
.rules()
|
|
||||||
.clearance(&self.conditions(bend.into()), guide_conditions),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dot_circle(&self, dot: DotIndex, width: f64, guide_conditions: &Conditions) -> Circle {
|
fn dot_circle(
|
||||||
|
&self,
|
||||||
|
dot: DotIndex,
|
||||||
|
width: f64,
|
||||||
|
guide_conditions: Option<&Conditions<'_, ()>>,
|
||||||
|
) -> Circle {
|
||||||
let shape = dot.primitive(self).shape();
|
let shape = dot.primitive(self).shape();
|
||||||
Circle {
|
Circle {
|
||||||
pos: shape.center(),
|
pos: shape.center(),
|
||||||
r: shape.width() / 2.0
|
r: shape.width() / 2.0
|
||||||
+ width / 2.0
|
+ width / 2.0
|
||||||
+ self
|
+ self.clearance(self.conditions(dot.into()).as_ref(), guide_conditions),
|
||||||
.rules()
|
|
||||||
.clearance(&self.conditions(dot.into()), guide_conditions),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -261,7 +294,7 @@ impl<CW: Copy, R: AccessRules> GuidePrivate for Drawing<CW, R> {
|
||||||
.other_joint(head.cane.dot.into())
|
.other_joint(head.cane.dot.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn conditions(&self, node: PrimitiveIndex) -> Conditions {
|
fn conditions(&self, node: PrimitiveIndex) -> Option<Conditions<'_, ()>> {
|
||||||
node.primitive(self).conditions()
|
node.primitive(self).conditions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ use super::{
|
||||||
cane::Cane,
|
cane::Cane,
|
||||||
dot::{DotIndex, FixedDotIndex, LooseDotIndex},
|
dot::{DotIndex, FixedDotIndex, LooseDotIndex},
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
rules::AccessRules,
|
AccessRules, Drawing,
|
||||||
Drawing,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,11 @@ use crate::{
|
||||||
graph::{MakePrimitive, PrimitiveIndex},
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
primitive::{GetJoints, LoneLooseSeg, LooseBend, LooseDot, Primitive, SeqLooseSeg},
|
primitive::{GetJoints, LoneLooseSeg, LooseBend, LooseDot, Primitive, SeqLooseSeg},
|
||||||
seg::{LoneLooseSegIndex, SeqLooseSegIndex},
|
seg::{LoneLooseSegIndex, SeqLooseSegIndex},
|
||||||
|
AccessRules,
|
||||||
},
|
},
|
||||||
graph::GetPetgraphIndex,
|
graph::GetPetgraphIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::rules::AccessRules;
|
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait GetPrevNextLoose {
|
pub trait GetPrevNextLoose {
|
||||||
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex>;
|
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex>;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ mod guide;
|
||||||
pub mod head;
|
pub mod head;
|
||||||
pub mod loose;
|
pub mod loose;
|
||||||
pub mod primitive;
|
pub mod primitive;
|
||||||
|
pub use crate::specctra::AccessRules;
|
||||||
pub use specctra_core::rules;
|
pub use specctra_core::rules;
|
||||||
pub mod seg;
|
pub mod seg;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@ use crate::{
|
||||||
dot::{DotIndex, DotWeight, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
dot::{DotIndex, DotWeight, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
||||||
graph::{GetLayer, GetMaybeNet, PrimitiveIndex, PrimitiveWeight, Retag},
|
graph::{GetLayer, GetMaybeNet, PrimitiveIndex, PrimitiveWeight, Retag},
|
||||||
seg::{FixedSegWeight, LoneLooseSegWeight, SegIndex, SeqLooseSegIndex, SeqLooseSegWeight},
|
seg::{FixedSegWeight, LoneLooseSegWeight, SegIndex, SeqLooseSegIndex, SeqLooseSegWeight},
|
||||||
Drawing,
|
AccessRules, Drawing,
|
||||||
},
|
},
|
||||||
geometry::{primitive::PrimitiveShape, GenericNode, GetOffset, GetWidth},
|
geometry::{primitive::PrimitiveShape, GenericNode, GetOffset, GetWidth},
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use specctra_core::rules::{AccessRules, Conditions, GetConditions};
|
use specctra_core::rules::{Conditions, GetConditions};
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait GetDrawing<'a, R: AccessRules> {
|
pub trait GetDrawing<'a, R: AccessRules> {
|
||||||
|
|
@ -171,16 +171,20 @@ pub enum Primitive<'a, CW: Copy, R: AccessRules> {
|
||||||
LooseBend(LooseBend<'a, CW, R>),
|
LooseBend(LooseBend<'a, CW, R>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, CW: Copy, R: AccessRules> specctra_core::rules::GetConditions for Primitive<'a, CW, R> {
|
impl<'a, CW: Copy, R: AccessRules> specctra_core::rules::GetConditions<'a>
|
||||||
fn conditions(&self) -> specctra_core::rules::Conditions {
|
for &Primitive<'a, CW, R>
|
||||||
|
{
|
||||||
|
type ObjectKind = ();
|
||||||
|
|
||||||
|
fn conditions(self) -> Option<specctra_core::rules::Conditions<'a, ()>> {
|
||||||
match self {
|
match self {
|
||||||
Self::FixedDot(x) => x.conditions(),
|
Primitive::FixedDot(x) => x.conditions(),
|
||||||
Self::LooseDot(x) => x.conditions(),
|
Primitive::LooseDot(x) => x.conditions(),
|
||||||
Self::FixedSeg(x) => x.conditions(),
|
Primitive::FixedSeg(x) => x.conditions(),
|
||||||
Self::LoneLooseSeg(x) => x.conditions(),
|
Primitive::LoneLooseSeg(x) => x.conditions(),
|
||||||
Self::SeqLooseSeg(x) => x.conditions(),
|
Primitive::SeqLooseSeg(x) => x.conditions(),
|
||||||
Self::FixedBend(x) => x.conditions(),
|
Primitive::FixedBend(x) => x.conditions(),
|
||||||
Self::LooseBend(x) => x.conditions(),
|
Primitive::LooseBend(x) => x.conditions(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -244,16 +248,19 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W, CW: Copy, R: AccessRules> GetConditions for GenericPrimitive<'a, W, CW, R>
|
impl<'a, W, CW: Copy, R: AccessRules> GetConditions<'a> for &GenericPrimitive<'a, W, CW, R>
|
||||||
where
|
where
|
||||||
GenericPrimitive<'a, W, CW, R>: GetMaybeNet,
|
GenericPrimitive<'a, W, CW, R>: GetMaybeNet,
|
||||||
{
|
{
|
||||||
fn conditions(&self) -> Conditions {
|
type ObjectKind = ();
|
||||||
Conditions {
|
|
||||||
maybe_net: self.maybe_net(),
|
fn conditions(self) -> Option<Conditions<'a, ()>> {
|
||||||
maybe_region: Some("A".to_string()),
|
self.maybe_net().map(|net| Conditions {
|
||||||
maybe_layer: Some("F.Cu".to_string()),
|
net,
|
||||||
}
|
maybe_region: Some("A".into()),
|
||||||
|
maybe_layer: Some("F.Cu".into()),
|
||||||
|
kind: (),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@ use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight, Retag},
|
graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight, Retag},
|
||||||
primitive::{GenericPrimitive, Primitive},
|
primitive::{GenericPrimitive, Primitive},
|
||||||
rules::AccessRules,
|
AccessRules, Drawing,
|
||||||
Drawing,
|
|
||||||
},
|
},
|
||||||
geometry::GetWidth,
|
geometry::GetWidth,
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@ use crate::{
|
||||||
dot::DotWeight,
|
dot::DotWeight,
|
||||||
graph::{PrimitiveWeight, Retag},
|
graph::{PrimitiveWeight, Retag},
|
||||||
primitive::Primitive,
|
primitive::Primitive,
|
||||||
rules::AccessRules,
|
|
||||||
seg::SegWeight,
|
seg::SegWeight,
|
||||||
|
AccessRules,
|
||||||
},
|
},
|
||||||
geometry::{
|
geometry::{
|
||||||
compound::ManageCompounds,
|
compound::ManageCompounds,
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,11 @@ use crate::{
|
||||||
gear::GearIndex,
|
gear::GearIndex,
|
||||||
graph::{GetMaybeNet, IsInLayer, MakePrimitive, PrimitiveIndex, PrimitiveWeight},
|
graph::{GetMaybeNet, IsInLayer, MakePrimitive, PrimitiveIndex, PrimitiveWeight},
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
rules::AccessRules,
|
|
||||||
seg::{
|
seg::{
|
||||||
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
||||||
SegWeight, SeqLooseSegIndex, SeqLooseSegWeight,
|
SegWeight, SeqLooseSegIndex, SeqLooseSegWeight,
|
||||||
},
|
},
|
||||||
Cane, Drawing, DrawingEdit, DrawingException, Infringement,
|
AccessRules, Cane, Drawing, DrawingEdit, DrawingException, Infringement,
|
||||||
},
|
},
|
||||||
geometry::{edit::ApplyGeometryEdit, shape::Shape, GenericNode},
|
geometry::{edit::ApplyGeometryEdit, shape::Shape, GenericNode},
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,8 @@ use crate::{
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
graph::{GetLayer, GetMaybeNet, PrimitiveIndex},
|
graph::{GetLayer, GetMaybeNet, PrimitiveIndex},
|
||||||
primitive::GetLimbs,
|
primitive::GetLimbs,
|
||||||
rules::AccessRules,
|
|
||||||
seg::SegIndex,
|
seg::SegIndex,
|
||||||
Drawing,
|
AccessRules, Drawing,
|
||||||
},
|
},
|
||||||
geometry::GetSetPos,
|
geometry::GetSetPos,
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
graph::{GetMaybeNet, IsInLayer},
|
graph::{GetMaybeNet, IsInLayer},
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
rules::AccessRules,
|
AccessRules, Drawing,
|
||||||
Drawing,
|
|
||||||
},
|
},
|
||||||
geometry::primitive::{DotShape, PrimitiveShape},
|
geometry::primitive::{DotShape, PrimitiveShape},
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,8 @@ use crate::{
|
||||||
graph::{GetLayer, GetMaybeNet, MakePrimitive},
|
graph::{GetLayer, GetMaybeNet, MakePrimitive},
|
||||||
head::{CaneHead, GetFace, Head},
|
head::{CaneHead, GetFace, Head},
|
||||||
primitive::GetOtherJoint,
|
primitive::GetOtherJoint,
|
||||||
rules::AccessRules,
|
|
||||||
seg::{LoneLooseSegWeight, SeqLooseSegWeight},
|
seg::{LoneLooseSegWeight, SeqLooseSegWeight},
|
||||||
DrawingException, Guide, Infringement,
|
AccessRules, DrawingException, Guide, Infringement,
|
||||||
},
|
},
|
||||||
layout::{Layout, LayoutEdit},
|
layout::{Layout, LayoutEdit},
|
||||||
math::{Circle, NoTangents},
|
math::{Circle, NoTangents},
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
graph::PrimitiveIndex,
|
graph::PrimitiveIndex,
|
||||||
head::{BareHead, CaneHead, Head},
|
head::{BareHead, CaneHead, Head},
|
||||||
rules::AccessRules,
|
AccessRules,
|
||||||
},
|
},
|
||||||
layout::{Layout, LayoutEdit},
|
layout::{Layout, LayoutEdit},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use contracts_try::{debug_ensures, debug_requires};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{band::BandTermsegIndex, dot::FixedDotIndex, rules::AccessRules},
|
drawing::{band::BandTermsegIndex, dot::FixedDotIndex, AccessRules},
|
||||||
layout::{Layout, LayoutEdit},
|
layout::{Layout, LayoutEdit},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,7 @@ use crate::{
|
||||||
gear::{GearIndex, GetNextGear},
|
gear::{GearIndex, GetNextGear},
|
||||||
graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex},
|
graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex},
|
||||||
primitive::{MakePrimitiveShape, Primitive},
|
primitive::{MakePrimitiveShape, Primitive},
|
||||||
rules::AccessRules,
|
AccessRules, Drawing,
|
||||||
Drawing,
|
|
||||||
},
|
},
|
||||||
geometry::shape::AccessShape,
|
geometry::shape::AccessShape,
|
||||||
graph::{GetPetgraphIndex, MakeRef},
|
graph::{GetPetgraphIndex, MakeRef},
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@ use std::ops::ControlFlow;
|
||||||
use derive_getters::{Dissolve, Getters};
|
use derive_getters::{Dissolve, Getters};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{
|
drawing::{band::BandTermsegIndex, dot::FixedDotIndex, graph::PrimitiveIndex, AccessRules},
|
||||||
band::BandTermsegIndex, dot::FixedDotIndex, graph::PrimitiveIndex, rules::AccessRules,
|
|
||||||
},
|
|
||||||
geometry::primitive::PrimitiveShape,
|
geometry::primitive::PrimitiveShape,
|
||||||
layout::LayoutEdit,
|
layout::LayoutEdit,
|
||||||
router::{
|
router::{
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,7 @@ use crate::{
|
||||||
graph::{MakePrimitive, PrimitiveIndex},
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
head::GetFace,
|
head::GetFace,
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
rules::AccessRules,
|
AccessRules, Collision, DrawingException, Guide, Infringement,
|
||||||
Collision, DrawingException, Guide, Infringement,
|
|
||||||
},
|
},
|
||||||
geometry::{
|
geometry::{
|
||||||
primitive::PrimitiveShape,
|
primitive::PrimitiveShape,
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,7 @@ pub use specctra_core::error::{ParseError, ParseErrorContext};
|
||||||
pub use specctra_core::mesadata;
|
pub use specctra_core::mesadata;
|
||||||
use specctra_core::*;
|
use specctra_core::*;
|
||||||
|
|
||||||
|
pub trait AccessRules: specctra_core::rules::AccessRules<Scalar = f64, ObjectKind = ()> {}
|
||||||
|
impl<T> AccessRules for T where T: specctra_core::rules::AccessRules<Scalar = f64, ObjectKind = ()> {}
|
||||||
|
|
||||||
pub mod design;
|
pub mod design;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue