Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion iOverlay/src/bind/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pub(crate) mod segment;
pub(crate) mod solver;
pub(crate) mod segment;
4 changes: 2 additions & 2 deletions iOverlay/src/bind/segment.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use alloc::vec::Vec;
use crate::geom::v_segment::VSegment;
use crate::vector::edge::{VectorEdge, VectorPath};
use alloc::vec::Vec;
use i_float::int::point::IntPoint;
use i_shape::int::path::IntPath;

Expand Down Expand Up @@ -139,4 +139,4 @@ impl IdSegments for VectorPath {
inner(self.iter().rev().copied(), buffer, id_data, x_min, x_max);
}
}
}
}
92 changes: 63 additions & 29 deletions iOverlay/src/build/boolean.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,48 @@
use alloc::vec::Vec;
use i_shape::util::reserve::Reserve;
use crate::segm::boolean::ShapeCountBoolean;
use crate::core::link::OverlayLinkFilter;
use crate::core::graph::OverlayNode;
use crate::core::fill_rule::FillRule;
use crate::core::solver::Solver;
use crate::build::builder::{FillStrategy, GraphBuilder, InclusionFilterStrategy};
use crate::core::extract::VisitState;
use crate::core::fill_rule::FillRule;
use crate::core::graph::OverlayGraph;
use crate::core::graph::OverlayNode;
use crate::core::link::OverlayLink;
use crate::core::link::OverlayLinkFilter;
use crate::core::overlay::IntOverlayOptions;
use crate::core::overlay_rule::OverlayRule;
use crate::segm::segment::{Segment, SegmentFill, ALL, BOTH_BOTTOM, BOTH_TOP, CLIP_BOTH, CLIP_BOTTOM, CLIP_TOP, SUBJ_BOTH, SUBJ_BOTTOM, SUBJ_TOP};
use crate::core::solver::Solver;
use crate::segm::boolean::ShapeCountBoolean;
use crate::segm::segment::{
ALL, BOTH_BOTTOM, BOTH_TOP, CLIP_BOTH, CLIP_BOTTOM, CLIP_TOP, SUBJ_BOTH, SUBJ_BOTTOM, SUBJ_TOP,
Segment, SegmentFill,
};
use crate::segm::winding::WindingCount;
use alloc::vec::Vec;
use i_shape::util::reserve::Reserve;

impl GraphBuilder<ShapeCountBoolean, OverlayNode> {
#[inline]
pub(crate) fn build_boolean_all(&mut self,
fill_rule: FillRule,
options: IntOverlayOptions,
solver: &Solver,
segments: &[Segment<ShapeCountBoolean>],
pub(crate) fn build_boolean_all(
&mut self,
fill_rule: FillRule,
options: IntOverlayOptions,
solver: &Solver,
segments: &[Segment<ShapeCountBoolean>],
) -> OverlayGraph<'_> {
self.build_boolean_fills(fill_rule, solver, segments);
self.build_links_all(segments);
self.boolean_graph(options, solver)
}

#[inline]
pub(crate) fn build_boolean_overlay(&mut self,
fill_rule: FillRule,
overlay_rule: OverlayRule,
options: IntOverlayOptions,
solver: &Solver,
segments: &[Segment<ShapeCountBoolean>],
#[rustfmt::skip]
pub(crate) fn build_boolean_overlay(
&mut self,
fill_rule: FillRule,
overlay_rule: OverlayRule,
options: IntOverlayOptions,
solver: &Solver,
segments: &[Segment<ShapeCountBoolean>],
) -> OverlayGraph<'_> {
self.build_boolean_fills(fill_rule, solver, segments);

match overlay_rule {
OverlayRule::Subject => self.build_links_by_filter::<SubjectFilter>(segments),
OverlayRule::Clip => self.build_links_by_filter::<ClipFilter>(segments),
Expand All @@ -49,7 +56,13 @@ impl GraphBuilder<ShapeCountBoolean, OverlayNode> {
}

#[inline]
fn build_boolean_fills(&mut self, fill_rule: FillRule, solver: &Solver, segments: &[Segment<ShapeCountBoolean>]) {
#[rustfmt::skip]
fn build_boolean_fills(
&mut self,
fill_rule: FillRule,
solver: &Solver,
segments: &[Segment<ShapeCountBoolean>],
) {
match fill_rule {
FillRule::EvenOdd => self.build_fills_with_strategy::<EvenOddStrategy>(solver, segments),
FillRule::NonZero => self.build_fills_with_strategy::<NonZeroStrategy>(solver, segments),
Expand All @@ -64,7 +77,7 @@ impl GraphBuilder<ShapeCountBoolean, OverlayNode> {
OverlayGraph {
nodes: &self.nodes,
links: &self.links,
options
options,
}
}
}
Expand Down Expand Up @@ -307,37 +320,58 @@ impl OverlayLinkFilter for [OverlayLink] {

#[inline]
fn filter_subject(links: &[OverlayLink]) -> Vec<VisitState> {
links.iter().map(|link| VisitState::new(!link.fill.is_subject())).collect()
links
.iter()
.map(|link| VisitState::new(!link.fill.is_subject()))
.collect()
}

#[inline]
fn filter_clip(links: &[OverlayLink]) -> Vec<VisitState> {
links.iter().map(|link| VisitState::new(!link.fill.is_clip())).collect()
links
.iter()
.map(|link| VisitState::new(!link.fill.is_clip()))
.collect()
}

#[inline]
fn filter_intersect(links: &[OverlayLink]) -> Vec<VisitState> {
links.iter().map(|link| VisitState::new(!link.fill.is_intersect())).collect()
links
.iter()
.map(|link| VisitState::new(!link.fill.is_intersect()))
.collect()
}

#[inline]
fn filter_union(links: &[OverlayLink]) -> Vec<VisitState> {
links.iter().map(|link| VisitState::new(!link.fill.is_union())).collect()
links
.iter()
.map(|link| VisitState::new(!link.fill.is_union()))
.collect()
}

#[inline]
fn filter_difference(links: &[OverlayLink]) -> Vec<VisitState> {
links.iter().map(|link| VisitState::new(!link.fill.is_difference())).collect()
links
.iter()
.map(|link| VisitState::new(!link.fill.is_difference()))
.collect()
}

#[inline]
fn filter_inverse_difference(links: &[OverlayLink]) -> Vec<VisitState> {
links.iter().map(|link| VisitState::new(!link.fill.is_inverse_difference())).collect()
links
.iter()
.map(|link| VisitState::new(!link.fill.is_inverse_difference()))
.collect()
}

#[inline]
fn filter_xor(links: &[OverlayLink]) -> Vec<VisitState> {
links.iter().map(|link| VisitState::new(!link.fill.is_xor())).collect()
links
.iter()
.map(|link| VisitState::new(!link.fill.is_xor()))
.collect()
}

#[inline]
Expand Down Expand Up @@ -401,4 +435,4 @@ fn filter_xor_into(links: &[OverlayLink], buffer: &mut Vec<VisitState>) {
for link in links.iter() {
buffer.push(VisitState::new(!link.fill.is_xor()));
}
}
}
24 changes: 17 additions & 7 deletions iOverlay/src/build/builder.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use alloc::vec::Vec;
use crate::core::link::OverlayLink;
use crate::core::solver::Solver;
use crate::geom::end::End;
use crate::geom::id_point::IdPoint;
use crate::geom::v_segment::VSegment;
use crate::segm::segment::{NONE, Segment, SegmentFill};
use crate::segm::winding::WindingCount;
use crate::util::log::Int;
use alloc::vec::Vec;
use i_float::triangle::Triangle;
use i_shape::util::reserve::Reserve;
use i_tree::key::exp::KeyExpCollection;
use i_tree::key::list::KeyExpList;
use i_tree::key::tree::KeyExpTree;
use crate::core::link::OverlayLink;
use crate::geom::id_point::IdPoint;

pub(super) trait FillStrategy<C> {
fn add_and_fill(this: C, bot: C) -> (C, SegmentFill);
Expand All @@ -35,7 +35,6 @@ pub(crate) struct GraphBuilder<C, N> {
}

impl<C: WindingCount, N: GraphNode> GraphBuilder<C, N> {

#[inline]
pub(crate) fn new() -> Self {
Self {
Expand All @@ -49,7 +48,11 @@ impl<C: WindingCount, N: GraphNode> GraphBuilder<C, N> {
}

#[inline]
pub(super) fn build_fills_with_strategy<F: FillStrategy<C>>(&mut self, solver: &Solver, segments: &[Segment<C>]) {
pub(super) fn build_fills_with_strategy<F: FillStrategy<C>>(
&mut self,
solver: &Solver,
segments: &[Segment<C>],
) {
let count = segments.len();
if solver.is_list_fill(segments) {
let capacity = count.log2_sqrt().max(4) * 2;
Expand All @@ -65,7 +68,11 @@ impl<C: WindingCount, N: GraphNode> GraphBuilder<C, N> {
}

#[inline]
fn build_fills<F: FillStrategy<C>, S: KeyExpCollection<VSegment, i32, C>>(&mut self, scan_list: &mut S, segments: &[Segment<C>]) {
fn build_fills<F: FillStrategy<C>, S: KeyExpCollection<VSegment, i32, C>>(
&mut self,
scan_list: &mut S,
segments: &[Segment<C>],
) {
let mut node = Vec::with_capacity(4);

let n = segments.len();
Expand Down Expand Up @@ -119,7 +126,10 @@ impl<C: WindingCount, N: GraphNode> GraphBuilder<C, N> {
}

#[inline]
pub(super) fn build_links_by_filter<F: InclusionFilterStrategy>(&mut self, segments: &[Segment<C>]) {
pub(super) fn build_links_by_filter<F: InclusionFilterStrategy>(
&mut self,
segments: &[Segment<C>],
) {
self.links.clear();
self.links.reserve_capacity(segments.len());

Expand Down
12 changes: 7 additions & 5 deletions iOverlay/src/build/graph.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use i_key_sort::sort::two_keys::TwoKeysSort;
use crate::build::builder::{GraphBuilder, GraphNode};
use crate::core::solver::Solver;
use crate::geom::end::End;
use crate::segm::winding::WindingCount;
use alloc::vec::Vec;
use i_key_sort::sort::two_keys::TwoKeysSort;

impl<C: WindingCount, N: GraphNode> GraphBuilder<C, N> {

pub(super) fn build_nodes_and_connect_links(&mut self, solver: &Solver) {
let n = self.links.len();
if n == 0 {
Expand Down Expand Up @@ -93,7 +92,10 @@ impl<C: WindingCount, N: GraphNode> GraphBuilder<C, N> {
point: link.b.point,
});
}
self.ends
.sort_by_two_keys(solver.is_parallel_sort_allowed(), |e| e.point.x, |e| e.point.y);
self.ends.sort_by_two_keys(
solver.is_parallel_sort_allowed(),
|e| e.point.x,
|e| e.point.y,
);
}
}
}
6 changes: 3 additions & 3 deletions iOverlay/src/build/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub(crate) mod builder;
pub(crate) mod boolean;
pub(crate) mod string;
pub(crate) mod builder;
mod graph;
mod offset;
mod util;
pub(crate) mod string;
mod util;
21 changes: 13 additions & 8 deletions iOverlay/src/build/offset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ use crate::segm::segment::{Segment, SegmentFill};

impl GraphBuilder<ShapeCountOffset, OverlayNode> {
#[inline]
pub(crate) fn build_offset(&mut self,
solver: &Solver,
segments: &[Segment<ShapeCountOffset>],
pub(crate) fn build_offset(
&mut self,
solver: &Solver,
segments: &[Segment<ShapeCountOffset>],
) -> OffsetGraph<'_> {
self.build_fills_with_strategy::<SubjectOffsetStrategy>(solver, segments);
self.build_links_all(segments);
Expand All @@ -31,9 +32,11 @@ struct SubjectOffsetStrategy;
const BOLD_BIT: usize = 2;

impl FillStrategy<ShapeCountOffset> for SubjectOffsetStrategy {

#[inline(always)]
fn add_and_fill(this: ShapeCountOffset, bot: ShapeCountOffset) -> (ShapeCountOffset, SegmentFill) {
fn add_and_fill(
this: ShapeCountOffset,
bot: ShapeCountOffset,
) -> (ShapeCountOffset, SegmentFill) {
let top_subj = bot.subj + this.subj;
let bot_subj = bot.subj;

Expand All @@ -43,16 +46,18 @@ impl FillStrategy<ShapeCountOffset> for SubjectOffsetStrategy {
let bold = this.bold as SegmentFill;

let fill = subj_top | (subj_bot << 1) | (bold << BOLD_BIT);
let top = ShapeCountOffset { subj: top_subj, bold: false }; // bold not need
let top = ShapeCountOffset {
subj: top_subj,
bold: false, // bold not need
};

(top, fill)
}
}


impl OverlayLink {
#[inline(always)]
pub(crate) fn is_bold(&self) -> bool {
self.fill & (1 << BOLD_BIT) != 0
}
}
}
Loading