Introduce a new mesh library abstraction for holding meshes.

Simplifies the server code and allows avoiding copying indices all the time.

Closes #29.
This commit is contained in:
Patrick Walton 2017-10-02 14:03:56 -07:00
parent 8c6110a388
commit 475f5dca71
5 changed files with 354 additions and 335 deletions

View File

@ -25,6 +25,7 @@ use app_units::Au;
use bincode::Infinite;
use euclid::{Point2D, Size2D, Transform2D};
use pathfinder_font_renderer::{FontContext, FontInstanceKey, FontKey, GlyphKey};
use pathfinder_partitioner::mesh_library::{MeshLibrary, MeshLibraryIndexRanges};
use pathfinder_partitioner::partitioner::Partitioner;
use pathfinder_path_utils::cubic::CubicCurve;
use pathfinder_path_utils::monotonic::MonotonicPathSegmentStream;
@ -38,6 +39,7 @@ use serde::Serialize;
use std::fs::File;
use std::io::{self, Read};
use std::mem;
use std::ops::Range;
use std::path::{Path, PathBuf};
use std::time::{Duration, Instant};
use std::u32;
@ -82,26 +84,6 @@ struct SubpathRange {
end: u32,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
struct IndexRange {
start: usize,
end: usize,
}
impl IndexRange {
fn from_data<T>(dest: &mut Vec<u8>, src: &[T]) -> Result<IndexRange, ()> where T: Serialize {
let byte_len_before = dest.len();
for src_value in src {
try!(bincode::serialize_into(dest, src_value, Infinite).map_err(drop))
}
let byte_len_after = dest.len();
Ok(IndexRange {
start: byte_len_before / mem::size_of::<T>(),
end: byte_len_after / mem::size_of::<T>(),
})
}
}
#[derive(Clone, Serialize, Deserialize)]
struct PartitionFontRequest {
face: PartitionFontRequestFace,
@ -143,7 +125,7 @@ impl PartitionGlyphDimensions {
}
}
#[derive(Clone, Copy, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize)]
struct PartitionGlyphInfo {
id: u32,
dimensions: PartitionGlyphDimensions,
@ -160,24 +142,39 @@ struct PartitionFontResponse {
time: f64,
}
#[derive(Clone, Copy, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize)]
struct PartitionPathIndices {
#[serde(rename = "bQuadIndices")]
b_quad_indices: IndexRange,
b_quad_indices: Range<usize>,
#[serde(rename = "bVertexIndices")]
b_vertex_indices: IndexRange,
b_vertex_indices: Range<usize>,
#[serde(rename = "coverInteriorIndices")]
cover_interior_indices: IndexRange,
cover_interior_indices: Range<usize>,
#[serde(rename = "coverCurveIndices")]
cover_curve_indices: IndexRange,
cover_curve_indices: Range<usize>,
#[serde(rename = "coverUpperLineIndices")]
edge_upper_line_indices: IndexRange,
edge_upper_line_indices: Range<usize>,
#[serde(rename = "coverUpperCurveIndices")]
edge_upper_curve_indices: IndexRange,
edge_upper_curve_indices: Range<usize>,
#[serde(rename = "coverLowerLineIndices")]
edge_lower_line_indices: IndexRange,
edge_lower_line_indices: Range<usize>,
#[serde(rename = "coverLowerCurveIndices")]
edge_lower_curve_indices: IndexRange,
edge_lower_curve_indices: Range<usize>,
}
impl PartitionPathIndices {
fn new(index_ranges: MeshLibraryIndexRanges) -> PartitionPathIndices {
PartitionPathIndices {
b_quad_indices: index_ranges.b_quads,
b_vertex_indices: index_ranges.b_vertices,
cover_interior_indices: index_ranges.cover_interior_indices,
cover_curve_indices: index_ranges.cover_curve_indices,
edge_upper_line_indices: index_ranges.edge_upper_line_indices,
edge_upper_curve_indices: index_ranges.edge_upper_curve_indices,
edge_lower_line_indices: index_ranges.edge_lower_line_indices,
edge_lower_curve_indices: index_ranges.edge_lower_curve_indices,
}
}
}
#[derive(Clone, Serialize, Deserialize)]
@ -272,82 +269,20 @@ impl PathPartitioningResult {
-> PathPartitioningResult {
let timestamp_before = Instant::now();
let (mut b_quads, mut b_vertex_positions) = (vec![], vec![]);
let (mut b_vertex_path_ids, mut b_vertex_loop_blinn_data) = (vec![], vec![]);
let (mut cover_interior_indices, mut cover_curve_indices) = (vec![], vec![]);
let (mut edge_upper_line_indices, mut edge_upper_curve_indices) = (vec![], vec![]);
let (mut edge_lower_line_indices, mut edge_lower_curve_indices) = (vec![], vec![]);
partitioner.library_mut().clear();
let mut path_indices = vec![];
for (path_index, subpath_range) in subpath_indices.iter().enumerate() {
partitioner.partition((path_index + 1) as u16, subpath_range.start, subpath_range.end);
let index_ranges = partitioner.partition((path_index + 1) as u16,
subpath_range.start,
subpath_range.end);
let path_b_vertex_positions = partitioner.b_vertex_positions();
let path_b_vertex_path_ids = partitioner.b_vertex_path_ids();
let path_b_vertex_loop_blinn_data = partitioner.b_vertex_loop_blinn_data();
let cover_indices = partitioner.cover_indices();
let edge_indices = partitioner.edge_indices();
let positions_start =
IndexRange::from_data(&mut b_vertex_positions,
path_b_vertex_positions).unwrap().start as u32;
IndexRange::from_data(&mut b_vertex_path_ids, path_b_vertex_path_ids).unwrap();
let mut path_b_quads = partitioner.b_quads().to_vec();
let mut path_cover_interior_indices = cover_indices.interior_indices.to_vec();
let mut path_cover_curve_indices = cover_indices.curve_indices.to_vec();
let mut path_edge_upper_line_indices = edge_indices.upper_line_indices.to_vec();
let mut path_edge_upper_curve_indices = edge_indices.upper_curve_indices.to_vec();
let mut path_edge_lower_line_indices = edge_indices.lower_line_indices.to_vec();
let mut path_edge_lower_curve_indices = edge_indices.lower_curve_indices.to_vec();
for path_b_quad in &mut path_b_quads {
path_b_quad.offset(positions_start);
}
for path_cover_interior_index in &mut path_cover_interior_indices {
*path_cover_interior_index += positions_start
}
for path_cover_curve_index in &mut path_cover_curve_indices {
*path_cover_curve_index += positions_start
}
for path_edge_upper_line_indices in &mut path_edge_upper_line_indices {
path_edge_upper_line_indices.offset(positions_start);
}
for path_edge_upper_curve_indices in &mut path_edge_upper_curve_indices {
path_edge_upper_curve_indices.offset(positions_start);
}
for path_edge_lower_line_indices in &mut path_edge_lower_line_indices {
path_edge_lower_line_indices.offset(positions_start);
}
for path_edge_lower_curve_indices in &mut path_edge_lower_curve_indices {
path_edge_lower_curve_indices.offset(positions_start);
}
path_indices.push(PartitionPathIndices {
b_quad_indices: IndexRange::from_data(&mut b_quads, &path_b_quads).unwrap(),
b_vertex_indices: IndexRange::from_data(&mut b_vertex_loop_blinn_data,
path_b_vertex_loop_blinn_data).unwrap(),
cover_interior_indices: IndexRange::from_data(&mut cover_interior_indices,
&path_cover_interior_indices).unwrap(),
cover_curve_indices: IndexRange::from_data(&mut cover_curve_indices,
&path_cover_curve_indices).unwrap(),
edge_upper_line_indices:
IndexRange::from_data(&mut edge_upper_line_indices,
&path_edge_upper_line_indices).unwrap(),
edge_upper_curve_indices:
IndexRange::from_data(&mut edge_upper_curve_indices,
&path_edge_upper_curve_indices).unwrap(),
edge_lower_line_indices: IndexRange::from_data(&mut edge_lower_line_indices,
&path_edge_lower_line_indices).unwrap(),
edge_lower_curve_indices:
IndexRange::from_data(&mut edge_lower_curve_indices,
&path_edge_lower_curve_indices).unwrap(),
})
path_indices.push(PartitionPathIndices::new(index_ranges));
}
// Reverse interior indices for early Z optimizations.
let mut new_cover_interior_indices = Vec::with_capacity(cover_interior_indices.len());
/*let mut new_cover_interior_indices = Vec::with_capacity(cover_interior_indices.len());
for path_indices in path_indices.iter_mut().rev() {
let old_byte_start = path_indices.cover_interior_indices.start * mem::size_of::<u32>();
let old_byte_end = path_indices.cover_interior_indices.end * mem::size_of::<u32>();
@ -358,21 +293,34 @@ impl PathPartitioningResult {
path_indices.cover_interior_indices.start = new_start_index;
path_indices.cover_interior_indices.end = new_end_index;
}
cover_interior_indices = new_cover_interior_indices;
cover_interior_indices = new_cover_interior_indices;*/
let time_elapsed = timestamp_before.elapsed();
let library = mem::replace(partitioner.library_mut(), MeshLibrary::new());
let b_quads_buffer = serialize(&library.b_quads);
let b_vertex_positions_buffer = serialize(&library.b_vertex_positions);
let b_vertex_path_ids_buffer = serialize(&library.b_vertex_path_ids);
let b_vertex_loop_blinn_data_buffer = serialize(&library.b_vertex_loop_blinn_data);
let cover_interior_indices_buffer = serialize(&library.cover_indices.interior_indices);
let cover_curve_indices_buffer = serialize(&library.cover_indices.curve_indices);
let edge_upper_line_indices_buffer = serialize(&library.edge_indices.upper_line_indices);
let edge_upper_curve_indices_buffer = serialize(&library.edge_indices.upper_curve_indices);
let edge_lower_line_indices_buffer = serialize(&library.edge_indices.lower_line_indices);
let edge_lower_curve_indices_buffer = serialize(&library.edge_indices.lower_curve_indices);
let encoded_path_data = PartitionEncodedPathData {
b_quads: base64::encode(&b_quads),
b_vertex_positions: base64::encode(&b_vertex_positions),
b_vertex_path_ids: base64::encode(&b_vertex_path_ids),
b_vertex_loop_blinn_data: base64::encode(&b_vertex_loop_blinn_data),
cover_interior_indices: base64::encode(&cover_interior_indices),
cover_curve_indices: base64::encode(&cover_curve_indices),
edge_upper_line_indices: base64::encode(&edge_upper_line_indices),
edge_upper_curve_indices: base64::encode(&edge_upper_curve_indices),
edge_lower_line_indices: base64::encode(&edge_lower_line_indices),
edge_lower_curve_indices: base64::encode(&edge_lower_curve_indices),
b_quads: b_quads_buffer,
b_vertex_positions: b_vertex_positions_buffer,
b_vertex_path_ids: b_vertex_path_ids_buffer,
b_vertex_loop_blinn_data: b_vertex_loop_blinn_data_buffer,
cover_interior_indices: cover_interior_indices_buffer,
cover_curve_indices: cover_curve_indices_buffer,
edge_upper_line_indices: edge_upper_line_indices_buffer,
edge_upper_curve_indices: edge_upper_curve_indices_buffer,
edge_lower_line_indices: edge_lower_line_indices_buffer,
edge_lower_curve_indices: edge_lower_curve_indices_buffer,
};
PathPartitioningResult {
@ -383,6 +331,14 @@ impl PathPartitioningResult {
}
}
fn serialize<T>(data: &[T]) -> String where T: Serialize {
let mut dest = vec![];
for datum in data {
drop(bincode::serialize_into(&mut dest, datum, Infinite));
}
base64::encode(&dest)
}
#[post("/partition-font", format = "application/json", data = "<request>")]
fn partition_font(request: Json<PartitionFontRequest>)
-> Json<Result<PartitionFontResponse, PartitionFontError>> {
@ -450,7 +406,7 @@ fn partition_font(request: Json<PartitionFontRequest>)
}).collect();
// Partition the decoded glyph outlines.
let mut partitioner = Partitioner::new();
let mut partitioner = Partitioner::new(MeshLibrary::new());
partitioner.init_with_path_buffer(&path_buffer);
let path_partitioning_result = PathPartitioningResult::compute(&mut partitioner,
&subpath_indices);
@ -476,7 +432,7 @@ fn partition_font(request: Json<PartitionFontRequest>)
glyph_info.push(PartitionGlyphInfo {
id: glyph.id,
dimensions: dimensions,
path_indices: *glyph_path_indices,
path_indices: (*glyph_path_indices).clone(),
})
}
@ -561,7 +517,7 @@ fn partition_svg_paths(request: Json<PartitionSvgPathsRequest>)
}
// Partition the paths.
let mut partitioner = Partitioner::new();
let mut partitioner = Partitioner::new(MeshLibrary::new());
partitioner.init_with_path_buffer(&path_buffer);
let path_partitioning_result = PathPartitioningResult::compute(&mut partitioner, &paths);

View File

@ -2,9 +2,11 @@
use env_logger;
use euclid::Point2D;
use partitioner::Partitioner;
use std::mem;
use std::slice;
use mesh_library::MeshLibrary;
use partitioner::Partitioner;
use {BQuad, BVertexLoopBlinnData, CurveIndices, Endpoint, LineIndices, Subpath};
#[derive(Clone, Copy)]
@ -56,7 +58,7 @@ pub struct EdgeIndices {
#[no_mangle]
pub unsafe extern fn pf_partitioner_new() -> *mut Partitioner<'static> {
let mut partitioner = Box::new(Partitioner::new());
let mut partitioner = Box::new(Partitioner::new(MeshLibrary::new()));
let partitioner_ptr: *mut Partitioner<'static> = &mut *partitioner;
mem::forget(partitioner);
partitioner_ptr
@ -86,14 +88,14 @@ pub unsafe extern fn pf_partitioner_partition<'a>(partitioner: *mut Partitioner<
path_id: u16,
first_subpath_index: u32,
last_subpath_index: u32) {
(*partitioner).partition(path_id, first_subpath_index, last_subpath_index)
(*partitioner).partition(path_id, first_subpath_index, last_subpath_index);
}
#[no_mangle]
pub unsafe extern fn pf_partitioner_b_quads<'a>(partitioner: *const Partitioner<'a>,
out_b_quad_count: *mut u32)
-> *const BQuad {
let b_quads = (*partitioner).b_quads();
let b_quads = &(*partitioner).library().b_quads;
if !out_b_quad_count.is_null() {
*out_b_quad_count = b_quads.len() as u32
}
@ -104,7 +106,7 @@ pub unsafe extern fn pf_partitioner_b_quads<'a>(partitioner: *const Partitioner<
pub unsafe extern fn pf_partitioner_b_vertex_positions<'a>(partitioner: *const Partitioner<'a>,
out_b_vertex_count: *mut u32)
-> *const Point2D<f32> {
let b_vertex_positions = (*partitioner).b_vertex_positions();
let b_vertex_positions = &(*partitioner).library().b_vertex_positions;
if !out_b_vertex_count.is_null() {
*out_b_vertex_count = b_vertex_positions.len() as u32
}
@ -115,7 +117,7 @@ pub unsafe extern fn pf_partitioner_b_vertex_positions<'a>(partitioner: *const P
pub unsafe extern fn pf_partitioner_b_vertex_path_ids<'a>(partitioner: *const Partitioner<'a>,
out_b_vertex_count: *mut u32)
-> *const u16 {
let b_vertex_path_ids = (*partitioner).b_vertex_path_ids();
let b_vertex_path_ids = &(*partitioner).library().b_vertex_path_ids;
if !out_b_vertex_count.is_null() {
*out_b_vertex_count = b_vertex_path_ids.len() as u32
}
@ -127,7 +129,7 @@ pub unsafe extern fn pf_partitioner_b_vertex_loop_blinn_data<'a>(
partitioner: *const Partitioner<'a>,
out_b_vertex_count: *mut u32)
-> *const BVertexLoopBlinnData {
let b_vertex_loop_blinn_data = (*partitioner).b_vertex_loop_blinn_data();
let b_vertex_loop_blinn_data = &(*partitioner).library().b_vertex_loop_blinn_data;
if !out_b_vertex_count.is_null() {
*out_b_vertex_count = b_vertex_loop_blinn_data.len() as u32
}
@ -137,7 +139,7 @@ pub unsafe extern fn pf_partitioner_b_vertex_loop_blinn_data<'a>(
#[no_mangle]
pub unsafe extern fn pf_partitioner_cover_indices<'a>(partitioner: *const Partitioner<'a>,
out_cover_indices: *mut CoverIndices) {
let cover_indices = (*partitioner).cover_indices();
let cover_indices = &(*partitioner).library().cover_indices;
(*out_cover_indices).interior_indices = cover_indices.interior_indices.as_ptr();
(*out_cover_indices).interior_indices_len = cover_indices.interior_indices.len() as u32;
(*out_cover_indices).curve_indices = cover_indices.curve_indices.as_ptr();
@ -147,7 +149,7 @@ pub unsafe extern fn pf_partitioner_cover_indices<'a>(partitioner: *const Partit
#[no_mangle]
pub unsafe extern fn pf_partitioner_edge_indices<'a>(partitioner: *const Partitioner<'a>,
out_edge_indices: *mut EdgeIndices) {
let edge_indices = (*partitioner).edge_indices();
let edge_indices = &(*partitioner).library().edge_indices;
(*out_edge_indices).upper_line_indices = edge_indices.upper_line_indices.as_ptr();
(*out_edge_indices).upper_line_indices_len = edge_indices.upper_line_indices.len() as u32;
(*out_edge_indices).upper_curve_indices = edge_indices.upper_curve_indices.as_ptr();

View File

@ -26,6 +26,7 @@ use pathfinder_path_utils::{Endpoint, Subpath};
use std::u32;
pub mod capi;
pub mod mesh_library;
pub mod partitioner;
#[repr(C)]

View File

@ -0,0 +1,146 @@
// pathfinder/partitioner/src/mesh_library.rs
//
// Copyright © 2017 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use euclid::Point2D;
use std::ops::Range;
use {BQuad, BVertexLoopBlinnData, CurveIndices, LineIndices};
#[derive(Debug, Clone)]
pub struct MeshLibrary {
pub b_quads: Vec<BQuad>,
pub b_vertex_positions: Vec<Point2D<f32>>,
pub b_vertex_path_ids: Vec<u16>,
pub b_vertex_loop_blinn_data: Vec<BVertexLoopBlinnData>,
pub cover_indices: MeshLibraryCoverIndices,
pub edge_indices: MeshLibraryEdgeIndices,
}
impl MeshLibrary {
#[inline]
pub fn new() -> MeshLibrary {
MeshLibrary {
b_quads: vec![],
b_vertex_positions: vec![],
b_vertex_path_ids: vec![],
b_vertex_loop_blinn_data: vec![],
cover_indices: MeshLibraryCoverIndices::new(),
edge_indices: MeshLibraryEdgeIndices::new(),
}
}
pub fn clear(&mut self) {
self.b_quads.clear();
self.b_vertex_positions.clear();
self.b_vertex_path_ids.clear();
self.b_vertex_loop_blinn_data.clear();
self.cover_indices.clear();
self.edge_indices.clear();
}
pub(crate) fn snapshot_lengths(&self) -> MeshLibraryLengths {
MeshLibraryLengths {
b_quads: self.b_quads.len(),
b_vertices: self.b_vertex_positions.len(),
cover_interior_indices: self.cover_indices.interior_indices.len(),
cover_curve_indices: self.cover_indices.curve_indices.len(),
edge_upper_line_indices: self.edge_indices.upper_line_indices.len(),
edge_upper_curve_indices: self.edge_indices.upper_curve_indices.len(),
edge_lower_line_indices: self.edge_indices.lower_line_indices.len(),
edge_lower_curve_indices: self.edge_indices.lower_curve_indices.len(),
}
}
}
#[derive(Debug, Clone)]
pub struct MeshLibraryCoverIndices {
pub interior_indices: Vec<u32>,
pub curve_indices: Vec<u32>,
}
impl MeshLibraryCoverIndices {
#[inline]
fn new() -> MeshLibraryCoverIndices {
MeshLibraryCoverIndices {
interior_indices: vec![],
curve_indices: vec![],
}
}
fn clear(&mut self) {
self.interior_indices.clear();
self.curve_indices.clear();
}
}
#[derive(Debug, Clone)]
pub struct MeshLibraryEdgeIndices {
pub upper_line_indices: Vec<LineIndices>,
pub upper_curve_indices: Vec<CurveIndices>,
pub lower_line_indices: Vec<LineIndices>,
pub lower_curve_indices: Vec<CurveIndices>,
}
impl MeshLibraryEdgeIndices {
#[inline]
fn new() -> MeshLibraryEdgeIndices {
MeshLibraryEdgeIndices {
upper_line_indices: vec![],
upper_curve_indices: vec![],
lower_line_indices: vec![],
lower_curve_indices: vec![],
}
}
fn clear(&mut self) {
self.upper_line_indices.clear();
self.upper_curve_indices.clear();
self.lower_line_indices.clear();
self.lower_curve_indices.clear();
}
}
pub(crate) struct MeshLibraryLengths {
b_quads: usize,
b_vertices: usize,
cover_interior_indices: usize,
cover_curve_indices: usize,
edge_upper_line_indices: usize,
edge_upper_curve_indices: usize,
edge_lower_line_indices: usize,
edge_lower_curve_indices: usize,
}
pub struct MeshLibraryIndexRanges {
pub b_quads: Range<usize>,
pub b_vertices: Range<usize>,
pub cover_interior_indices: Range<usize>,
pub cover_curve_indices: Range<usize>,
pub edge_upper_line_indices: Range<usize>,
pub edge_upper_curve_indices: Range<usize>,
pub edge_lower_line_indices: Range<usize>,
pub edge_lower_curve_indices: Range<usize>,
}
impl MeshLibraryIndexRanges {
pub(crate) fn new(start: &MeshLibraryLengths, end: &MeshLibraryLengths)
-> MeshLibraryIndexRanges {
MeshLibraryIndexRanges {
b_quads: start.b_quads..end.b_quads,
b_vertices: start.b_vertices..end.b_vertices,
cover_interior_indices: start.cover_interior_indices..end.cover_interior_indices,
cover_curve_indices: start.cover_curve_indices..end.cover_curve_indices,
edge_upper_line_indices: start.edge_upper_line_indices..end.edge_upper_line_indices,
edge_upper_curve_indices: start.edge_upper_curve_indices..end.edge_upper_curve_indices,
edge_lower_line_indices: start.edge_lower_line_indices..end.edge_lower_line_indices,
edge_lower_curve_indices: start.edge_lower_curve_indices..end.edge_lower_curve_indices,
}
}
}

View File

@ -21,6 +21,7 @@ use std::f32;
use std::iter;
use std::u32;
use mesh_library::{MeshLibrary, MeshLibraryIndexRanges};
use {BQuad, BVertexLoopBlinnData, BVertexKind, CurveIndices, Endpoint, FillRule};
use {LineIndices, Subpath};
@ -31,14 +32,9 @@ pub struct Partitioner<'a> {
control_points: &'a [Point2D<f32>],
subpaths: &'a [Subpath],
fill_rule: FillRule,
library: MeshLibrary,
b_quads: Vec<BQuad>,
b_vertex_positions: Vec<Point2D<f32>>,
b_vertex_path_ids: Vec<u16>,
b_vertex_loop_blinn_data: Vec<BVertexLoopBlinnData>,
cover_indices: CoverIndicesBuffer,
edge_indices: EdgeIndicesBuffer,
fill_rule: FillRule,
heap: BinaryHeap<Point>,
visited_points: BitVec,
@ -48,7 +44,7 @@ pub struct Partitioner<'a> {
impl<'a> Partitioner<'a> {
#[inline]
pub fn new<'b>() -> Partitioner<'b> {
pub fn new<'b>(library: MeshLibrary) -> Partitioner<'b> {
Partitioner {
endpoints: &[],
control_points: &[],
@ -56,12 +52,7 @@ impl<'a> Partitioner<'a> {
fill_rule: FillRule::Winding,
b_quads: vec![],
b_vertex_positions: vec![],
b_vertex_path_ids: vec![],
b_vertex_loop_blinn_data: vec![],
cover_indices: CoverIndicesBuffer::new(),
edge_indices: EdgeIndicesBuffer::new(),
library: library,
heap: BinaryHeap::new(),
visited_points: BitVec::new(),
@ -70,6 +61,21 @@ impl<'a> Partitioner<'a> {
}
}
#[inline]
pub fn library(&self) -> &MeshLibrary {
&self.library
}
#[inline]
pub fn library_mut(&mut self) -> &mut MeshLibrary {
&mut self.library
}
#[inline]
pub fn into_library(self) -> MeshLibrary {
self.library
}
pub fn init_with_raw_data(&mut self,
new_endpoints: &'a [Endpoint],
new_control_points: &'a [Point2D<f32>],
@ -94,54 +100,26 @@ impl<'a> Partitioner<'a> {
self.fill_rule = new_fill_rule
}
pub fn partition(&mut self, path_id: u16, first_subpath_index: u32, last_subpath_index: u32) {
self.b_quads.clear();
self.b_vertex_loop_blinn_data.clear();
self.b_vertex_path_ids.clear();
self.b_vertex_positions.clear();
self.cover_indices.clear();
self.edge_indices.clear();
pub fn partition(&mut self, path_id: u16, first_subpath_index: u32, last_subpath_index: u32)
-> MeshLibraryIndexRanges {
self.heap.clear();
self.active_edges.clear();
let start_lengths = self.library.snapshot_lengths();
self.path_id = path_id;
self.init_heap(first_subpath_index, last_subpath_index);
while self.process_next_point() {}
debug_assert!(self.b_vertex_loop_blinn_data.len() == self.b_vertex_path_ids.len());
debug_assert!(self.b_vertex_loop_blinn_data.len() == self.b_vertex_positions.len());
}
debug_assert!(self.library.b_vertex_loop_blinn_data.len() ==
self.library.b_vertex_path_ids.len());
debug_assert!(self.library.b_vertex_loop_blinn_data.len() ==
self.library.b_vertex_positions.len());
#[inline]
pub fn b_quads(&self) -> &[BQuad] {
&self.b_quads
}
#[inline]
pub fn b_vertex_positions(&self) -> &[Point2D<f32>] {
&self.b_vertex_positions
}
#[inline]
pub fn b_vertex_path_ids(&self) -> &[u16] {
&self.b_vertex_path_ids
}
#[inline]
pub fn b_vertex_loop_blinn_data(&self) -> &[BVertexLoopBlinnData] {
&self.b_vertex_loop_blinn_data
}
#[inline]
pub fn cover_indices(&self) -> CoverIndices {
self.cover_indices.as_ref()
}
#[inline]
pub fn edge_indices(&self) -> EdgeIndices {
self.edge_indices.as_ref()
let end_lengths = self.library.snapshot_lengths();
MeshLibraryIndexRanges::new(&start_lengths, &end_lengths)
}
fn process_next_point(&mut self) -> bool {
@ -225,16 +203,16 @@ impl<'a> Partitioner<'a> {
// If we already made a B-vertex point for this endpoint, reuse it instead of making a
// new one.
let old_left_position =
self.b_vertex_positions[active_edge.left_vertex_index as usize];
self.library.b_vertex_positions[active_edge.left_vertex_index as usize];
let should_update = (endpoint_position - old_left_position).square_length() >
f32::approx_epsilon();
if should_update {
active_edge.left_vertex_index = self.b_vertex_loop_blinn_data.len() as u32;
active_edge.left_vertex_index = self.library.b_vertex_loop_blinn_data.len() as u32;
active_edge.control_point_vertex_index = active_edge.left_vertex_index + 1;
self.b_vertex_positions.push(endpoint_position);
self.b_vertex_path_ids.push(self.path_id);
self.b_vertex_loop_blinn_data.push(BVertexLoopBlinnData::new(
self.library.b_vertex_positions.push(endpoint_position);
self.library.b_vertex_path_ids.push(self.path_id);
self.library.b_vertex_loop_blinn_data.push(BVertexLoopBlinnData::new(
active_edge.endpoint_kind()));
active_edge.toggle_parity();
@ -264,19 +242,19 @@ impl<'a> Partitioner<'a> {
}
control_point_index => {
self.active_edges[active_edge_index as usize].control_point_vertex_index =
self.b_vertex_loop_blinn_data.len() as u32;
self.library.b_vertex_loop_blinn_data.len() as u32;
let left_vertex_index = self.active_edges[active_edge_index as usize]
.left_vertex_index;
let control_point_position = &self.control_points[control_point_index as usize];
let control_point_b_vertex_loop_blinn_data = BVertexLoopBlinnData::control_point(
&self.b_vertex_positions[left_vertex_index as usize],
&self.library.b_vertex_positions[left_vertex_index as usize],
&control_point_position,
&new_point.position,
bottom);
self.b_vertex_positions.push(*control_point_position);
self.b_vertex_path_ids.push(self.path_id);
self.b_vertex_loop_blinn_data.push(control_point_b_vertex_loop_blinn_data);
self.library.b_vertex_positions.push(*control_point_position);
self.library.b_vertex_path_ids.push(self.path_id);
self.library.b_vertex_loop_blinn_data.push(control_point_b_vertex_loop_blinn_data);
}
}
}
@ -349,14 +327,15 @@ impl<'a> Partitioner<'a> {
let new_active_edges = &mut self.active_edges[next_active_edge_index as usize..
next_active_edge_index as usize + 2];
let left_vertex_index = self.b_vertex_loop_blinn_data.len() as u32;
let left_vertex_index = self.library.b_vertex_loop_blinn_data.len() as u32;
new_active_edges[0].left_vertex_index = left_vertex_index;
new_active_edges[1].left_vertex_index = left_vertex_index;
let position = self.endpoints[endpoint_index as usize].position;
self.b_vertex_positions.push(position);
self.b_vertex_path_ids.push(self.path_id);
self.b_vertex_loop_blinn_data.push(BVertexLoopBlinnData::new(BVertexKind::Endpoint0));
self.library.b_vertex_positions.push(position);
self.library.b_vertex_path_ids.push(self.path_id);
self.library.b_vertex_loop_blinn_data
.push(BVertexLoopBlinnData::new(BVertexKind::Endpoint0));
new_active_edges[0].toggle_parity();
new_active_edges[1].toggle_parity();
@ -393,7 +372,7 @@ impl<'a> Partitioner<'a> {
u32::MAX => new_active_edges[0].control_point_vertex_index = u32::MAX,
upper_control_point_index => {
new_active_edges[0].control_point_vertex_index =
self.b_vertex_loop_blinn_data.len() as u32;
self.library.b_vertex_loop_blinn_data.len() as u32;
let control_point_position =
self.control_points[upper_control_point_index as usize];
@ -404,9 +383,9 @@ impl<'a> Partitioner<'a> {
&control_point_position,
&right_vertex_position,
false);
self.b_vertex_positions.push(control_point_position);
self.b_vertex_path_ids.push(self.path_id);
self.b_vertex_loop_blinn_data.push(control_point_b_vertex_loop_blinn_data);
self.library.b_vertex_positions.push(control_point_position);
self.library.b_vertex_path_ids.push(self.path_id);
self.library.b_vertex_loop_blinn_data.push(control_point_b_vertex_loop_blinn_data);
}
}
@ -414,7 +393,7 @@ impl<'a> Partitioner<'a> {
u32::MAX => new_active_edges[1].control_point_vertex_index = u32::MAX,
lower_control_point_index => {
new_active_edges[1].control_point_vertex_index =
self.b_vertex_loop_blinn_data.len() as u32;
self.library.b_vertex_loop_blinn_data.len() as u32;
let control_point_position =
self.control_points[lower_control_point_index as usize];
@ -425,9 +404,9 @@ impl<'a> Partitioner<'a> {
&control_point_position,
&right_vertex_position,
true);
self.b_vertex_positions.push(control_point_position);
self.b_vertex_path_ids.push(self.path_id);
self.b_vertex_loop_blinn_data.push(control_point_b_vertex_loop_blinn_data);
self.library.b_vertex_positions.push(control_point_position);
self.library.b_vertex_path_ids.push(self.path_id);
self.library.b_vertex_loop_blinn_data.push(control_point_b_vertex_loop_blinn_data);
}
}
}
@ -562,16 +541,16 @@ impl<'a> Partitioner<'a> {
upper_subdivision: &SubdividedActiveEdge,
lower_subdivision: &SubdividedActiveEdge,
iteration: u8) {
let upper_shape = upper_subdivision.shape(&self.b_vertex_loop_blinn_data);
let lower_shape = lower_subdivision.shape(&self.b_vertex_loop_blinn_data);
let upper_shape = upper_subdivision.shape(&self.library.b_vertex_loop_blinn_data);
let lower_shape = lower_subdivision.shape(&self.library.b_vertex_loop_blinn_data);
// Make sure the convex hulls of the two curves do not intersect. If they do, subdivide and
// recurse.
if iteration < MAX_B_QUAD_SUBDIVISIONS {
// TODO(pcwalton): Handle concave-line convex hull intersections.
if let (Some(upper_curve), Some(lower_curve)) =
(upper_subdivision.to_curve(&self.b_vertex_positions),
lower_subdivision.to_curve(&self.b_vertex_positions)) {
(upper_subdivision.to_curve(&self.library.b_vertex_positions),
lower_subdivision.to_curve(&self.library.b_vertex_positions)) {
// TODO(pcwalton): Handle concave-concave convex hull intersections.
if upper_shape == Shape::Concave &&
lower_curve.baseline().side(&upper_curve.control_point) >
@ -580,8 +559,9 @@ impl<'a> Partitioner<'a> {
self.subdivide_active_edge_again_at_t(&upper_subdivision,
0.5,
false);
let midpoint_x = self.b_vertex_positions[upper_left_subsubdivision.middle_point
as usize].x;
let midpoint_x =
self.library
.b_vertex_positions[upper_left_subsubdivision.middle_point as usize].x;
let (lower_left_subsubdivision, lower_right_subsubdivision) =
self.subdivide_active_edge_again_at_x(&lower_subdivision,
midpoint_x,
@ -607,8 +587,9 @@ impl<'a> Partitioner<'a> {
self.subdivide_active_edge_again_at_t(&lower_subdivision,
0.5,
true);
let midpoint_x = self.b_vertex_positions[lower_left_subsubdivision.middle_point
as usize].x;
let midpoint_x =
self.library
.b_vertex_positions[lower_left_subsubdivision.middle_point as usize].x;
let (upper_left_subsubdivision, upper_right_subsubdivision) =
self.subdivide_active_edge_again_at_x(&upper_subdivision,
midpoint_x,
@ -631,13 +612,15 @@ impl<'a> Partitioner<'a> {
match upper_shape {
Shape::Flat => {
self.edge_indices
self.library
.edge_indices
.upper_line_indices
.push(LineIndices::new(upper_subdivision.left_curve_left,
upper_subdivision.middle_point))
}
Shape::Convex | Shape::Concave => {
self.edge_indices
self.library
.edge_indices
.upper_curve_indices
.push(CurveIndices::new(upper_subdivision.left_curve_left,
upper_subdivision.left_curve_control_point,
@ -646,13 +629,15 @@ impl<'a> Partitioner<'a> {
}
match lower_shape {
Shape::Flat => {
self.edge_indices
self.library
.edge_indices
.lower_line_indices
.push(LineIndices::new(lower_subdivision.left_curve_left,
lower_subdivision.middle_point))
}
Shape::Convex | Shape::Concave => {
self.edge_indices
self.library
.edge_indices
.lower_curve_indices
.push(CurveIndices::new(lower_subdivision.left_curve_left,
lower_subdivision.left_curve_control_point,
@ -668,13 +653,13 @@ impl<'a> Partitioner<'a> {
{
let upper_active_edge = &mut self.active_edges[upper_active_edge_index as usize];
self.b_vertex_loop_blinn_data[upper_subdivision.middle_point as usize] =
self.library.b_vertex_loop_blinn_data[upper_subdivision.middle_point as usize] =
BVertexLoopBlinnData::new(upper_active_edge.endpoint_kind());
upper_active_edge.toggle_parity();
}
{
let lower_active_edge = &mut self.active_edges[lower_active_edge_index as usize];
self.b_vertex_loop_blinn_data[lower_subdivision.middle_point as usize] =
self.library.b_vertex_loop_blinn_data[lower_subdivision.middle_point as usize] =
BVertexLoopBlinnData::new(lower_active_edge.endpoint_kind());
lower_active_edge.toggle_parity();
}
@ -684,7 +669,7 @@ impl<'a> Partitioner<'a> {
(Shape::Flat, Shape::Convex) |
(Shape::Convex, Shape::Flat) |
(Shape::Convex, Shape::Convex) => {
self.cover_indices.interior_indices.extend([
self.library.cover_indices.interior_indices.extend([
upper_subdivision.left_curve_left,
upper_subdivision.middle_point,
lower_subdivision.left_curve_left,
@ -693,14 +678,14 @@ impl<'a> Partitioner<'a> {
upper_subdivision.middle_point,
].into_iter());
if upper_shape != Shape::Flat {
self.cover_indices.curve_indices.extend([
self.library.cover_indices.curve_indices.extend([
upper_subdivision.left_curve_control_point,
upper_subdivision.middle_point,
upper_subdivision.left_curve_left,
].into_iter())
}
if lower_shape != Shape::Flat {
self.cover_indices.curve_indices.extend([
self.library.cover_indices.curve_indices.extend([
lower_subdivision.left_curve_control_point,
lower_subdivision.left_curve_left,
lower_subdivision.middle_point,
@ -710,7 +695,7 @@ impl<'a> Partitioner<'a> {
(Shape::Concave, Shape::Flat) |
(Shape::Concave, Shape::Convex) => {
self.cover_indices.interior_indices.extend([
self.library.cover_indices.interior_indices.extend([
upper_subdivision.left_curve_left,
upper_subdivision.left_curve_control_point,
lower_subdivision.left_curve_left,
@ -721,13 +706,13 @@ impl<'a> Partitioner<'a> {
lower_subdivision.left_curve_left,
upper_subdivision.left_curve_control_point,
].into_iter());
self.cover_indices.curve_indices.extend([
self.library.cover_indices.curve_indices.extend([
upper_subdivision.left_curve_control_point,
upper_subdivision.left_curve_left,
upper_subdivision.middle_point,
].into_iter());
if lower_shape != Shape::Flat {
self.cover_indices.curve_indices.extend([
self.library.cover_indices.curve_indices.extend([
lower_subdivision.left_curve_control_point,
lower_subdivision.left_curve_left,
lower_subdivision.middle_point,
@ -737,7 +722,7 @@ impl<'a> Partitioner<'a> {
(Shape::Flat, Shape::Concave) |
(Shape::Convex, Shape::Concave) => {
self.cover_indices.interior_indices.extend([
self.library.cover_indices.interior_indices.extend([
upper_subdivision.left_curve_left,
upper_subdivision.middle_point,
lower_subdivision.left_curve_control_point,
@ -748,13 +733,13 @@ impl<'a> Partitioner<'a> {
lower_subdivision.left_curve_control_point,
lower_subdivision.left_curve_left,
].into_iter());
self.cover_indices.curve_indices.extend([
self.library.cover_indices.curve_indices.extend([
lower_subdivision.left_curve_control_point,
lower_subdivision.middle_point,
lower_subdivision.left_curve_left,
].into_iter());
if upper_shape != Shape::Flat {
self.cover_indices.curve_indices.extend([
self.library.cover_indices.curve_indices.extend([
upper_subdivision.left_curve_control_point,
upper_subdivision.middle_point,
upper_subdivision.left_curve_left,
@ -763,7 +748,7 @@ impl<'a> Partitioner<'a> {
}
(Shape::Concave, Shape::Concave) => {
self.cover_indices.interior_indices.extend([
self.library.cover_indices.interior_indices.extend([
upper_subdivision.left_curve_left,
upper_subdivision.left_curve_control_point,
lower_subdivision.left_curve_left,
@ -777,7 +762,7 @@ impl<'a> Partitioner<'a> {
lower_subdivision.middle_point,
lower_subdivision.left_curve_control_point,
].into_iter());
self.cover_indices.curve_indices.extend([
self.library.cover_indices.curve_indices.extend([
upper_subdivision.left_curve_control_point,
upper_subdivision.left_curve_left,
upper_subdivision.middle_point,
@ -788,7 +773,7 @@ impl<'a> Partitioner<'a> {
}
}
self.b_quads.push(BQuad::new(upper_subdivision.left_curve_left,
self.library.b_quads.push(BQuad::new(upper_subdivision.left_curve_left,
upper_subdivision.left_curve_control_point,
upper_subdivision.middle_point,
lower_subdivision.left_curve_left,
@ -801,24 +786,24 @@ impl<'a> Partitioner<'a> {
t: f32,
bottom: bool)
-> (SubdividedActiveEdge, SubdividedActiveEdge) {
let curve = subdivision.to_curve(&self.b_vertex_positions)
let curve = subdivision.to_curve(&self.library.b_vertex_positions)
.expect("subdivide_active_edge_again_at_t(): not a curve!");
let (left_curve, right_curve) = curve.subdivide(t);
let left_control_point_index = self.b_vertex_positions.len() as u32;
let left_control_point_index = self.library.b_vertex_positions.len() as u32;
let midpoint_index = left_control_point_index + 1;
let right_control_point_index = midpoint_index + 1;
self.b_vertex_positions.extend([
self.library.b_vertex_positions.extend([
left_curve.control_point,
left_curve.endpoints[1],
right_curve.control_point,
].into_iter());
self.b_vertex_path_ids.extend(iter::repeat(self.path_id).take(3));
self.library.b_vertex_path_ids.extend(iter::repeat(self.path_id).take(3));
// Initially, assume that the parity is false. We will modify the Loop-Blinn data later if
// that is incorrect.
self.b_vertex_loop_blinn_data.extend([
self.library.b_vertex_loop_blinn_data.extend([
BVertexLoopBlinnData::control_point(&left_curve.endpoints[0],
&left_curve.control_point,
&left_curve.endpoints[1],
@ -846,7 +831,7 @@ impl<'a> Partitioner<'a> {
x: f32,
bottom: bool)
-> (SubdividedActiveEdge, SubdividedActiveEdge) {
let curve = subdivision.to_curve(&self.b_vertex_positions)
let curve = subdivision.to_curve(&self.library.b_vertex_positions)
.expect("subdivide_active_edge_again_at_x(): not a curve!");
let t = curve.solve_t_for_x(x);
self.subdivide_active_edge_again_at_t(subdivision, t, bottom)
@ -911,14 +896,15 @@ impl<'a> Partitioner<'a> {
}
fn solve_active_edge_t_for_x(&self, x: f32, active_edge: &ActiveEdge) -> f32 {
let left_vertex_position = &self.b_vertex_positions[active_edge.left_vertex_index as
usize];
let left_vertex_position =
&self.library.b_vertex_positions[active_edge.left_vertex_index as usize];
let right_endpoint_position = &self.endpoints[active_edge.right_endpoint_index as usize]
.position;
match active_edge.control_point_vertex_index {
u32::MAX => Line::new(left_vertex_position, right_endpoint_position).solve_t_for_x(x),
control_point_vertex_index => {
let control_point = &self.b_vertex_positions[control_point_vertex_index as usize];
let control_point = &self.library
.b_vertex_positions[control_point_vertex_index as usize];
Curve::new(left_vertex_position,
control_point,
right_endpoint_position).solve_t_for_x(x)
@ -931,10 +917,10 @@ impl<'a> Partitioner<'a> {
}
fn sample_active_edge(&self, t: f32, active_edge: &ActiveEdge) -> Point2D<f32> {
let left_vertex_position = &self.b_vertex_positions[active_edge.left_vertex_index as
usize];
let right_endpoint_position = &self.endpoints[active_edge.right_endpoint_index as usize]
.position;
let left_vertex_position =
&self.library.b_vertex_positions[active_edge.left_vertex_index as usize];
let right_endpoint_position =
&self.endpoints[active_edge.right_endpoint_index as usize].position;
match active_edge.control_point_vertex_index {
u32::MAX => {
left_vertex_position.to_vector()
@ -942,7 +928,8 @@ impl<'a> Partitioner<'a> {
.to_point()
}
control_point_vertex_index => {
let control_point = &self.b_vertex_positions[control_point_vertex_index as usize];
let control_point = &self.library
.b_vertex_positions[control_point_vertex_index as usize];
Curve::new(left_vertex_position, control_point, right_endpoint_position).sample(t)
}
}
@ -960,11 +947,11 @@ impl<'a> Partitioner<'a> {
}
let upper_left_vertex_position =
&self.b_vertex_positions[upper_active_edge.left_vertex_index as usize];
&self.library.b_vertex_positions[upper_active_edge.left_vertex_index as usize];
let upper_right_endpoint_position =
&self.endpoints[upper_active_edge.right_endpoint_index as usize].position;
let lower_left_vertex_position =
&self.b_vertex_positions[lower_active_edge.left_vertex_index as usize];
&self.library.b_vertex_positions[lower_active_edge.left_vertex_index as usize];
let lower_right_endpoint_position =
&self.endpoints[lower_active_edge.right_endpoint_index as usize].position;
@ -982,7 +969,7 @@ impl<'a> Partitioner<'a> {
(upper_control_point_vertex_index, u32::MAX) => {
let upper_control_point =
&self.b_vertex_positions[upper_control_point_vertex_index as usize];
&self.library.b_vertex_positions[upper_control_point_vertex_index as usize];
let (upper_curve, _) =
Curve::new(&upper_left_vertex_position,
&upper_control_point,
@ -995,7 +982,7 @@ impl<'a> Partitioner<'a> {
(u32::MAX, lower_control_point_vertex_index) => {
let lower_control_point =
&self.b_vertex_positions[lower_control_point_vertex_index as usize];
&self.library.b_vertex_positions[lower_control_point_vertex_index as usize];
let (lower_curve, _) =
Curve::new(&lower_left_vertex_position,
&lower_control_point,
@ -1008,9 +995,9 @@ impl<'a> Partitioner<'a> {
(upper_control_point_vertex_index, lower_control_point_vertex_index) => {
let upper_control_point =
&self.b_vertex_positions[upper_control_point_vertex_index as usize];
&self.library.b_vertex_positions[upper_control_point_vertex_index as usize];
let lower_control_point =
&self.b_vertex_positions[lower_control_point_vertex_index as usize];
&self.library.b_vertex_positions[lower_control_point_vertex_index as usize];
let (upper_curve, _) =
Curve::new(&upper_left_vertex_position,
&upper_control_point,
@ -1026,7 +1013,7 @@ impl<'a> Partitioner<'a> {
fn should_subdivide_active_edge_at(&self, active_edge_index: u32, x: f32) -> bool {
let left_curve_left = self.active_edges[active_edge_index as usize].left_vertex_index;
let left_point_position = self.b_vertex_positions[left_curve_left as usize];
let left_point_position = self.library.b_vertex_positions[left_curve_left as usize];
x - left_point_position.x >= f32::approx_epsilon()
}
@ -1037,7 +1024,7 @@ impl<'a> Partitioner<'a> {
subdivision_type: SubdivisionType)
-> SubdividedActiveEdge {
let left_curve_left = self.active_edges[active_edge_index as usize].left_vertex_index;
let left_point_position = self.b_vertex_positions[left_curve_left as usize];
let left_point_position = self.library.b_vertex_positions[left_curve_left as usize];
let t = self.solve_active_edge_t_for_x(x, &self.active_edges[active_edge_index as usize]);
@ -1047,24 +1034,26 @@ impl<'a> Partitioner<'a> {
let left_curve_control_point_vertex_index;
match active_edge.control_point_vertex_index {
u32::MAX => {
let path_id = self.b_vertex_path_ids[left_curve_left as usize];
let path_id = self.library.b_vertex_path_ids[left_curve_left as usize];
let right_point = self.endpoints[active_edge.right_endpoint_index as usize]
.position;
let middle_point = left_point_position.to_vector().lerp(right_point.to_vector(), t);
active_edge.left_vertex_index = self.b_vertex_loop_blinn_data.len() as u32;
self.b_vertex_positions.push(middle_point.to_point());
self.b_vertex_path_ids.push(path_id);
self.b_vertex_loop_blinn_data
active_edge.left_vertex_index = self.library.b_vertex_loop_blinn_data.len() as u32;
self.library.b_vertex_positions.push(middle_point.to_point());
self.library.b_vertex_path_ids.push(path_id);
self.library
.b_vertex_loop_blinn_data
.push(BVertexLoopBlinnData::new(active_edge.endpoint_kind()));
left_curve_control_point_vertex_index = u32::MAX;
}
_ => {
let left_endpoint_position =
self.b_vertex_positions[active_edge.left_vertex_index as usize];
self.library.b_vertex_positions[active_edge.left_vertex_index as usize];
let control_point_position =
self.b_vertex_positions[active_edge.control_point_vertex_index as usize];
self.library
.b_vertex_positions[active_edge.control_point_vertex_index as usize];
let right_endpoint_position =
self.endpoints[active_edge.right_endpoint_index as usize].position;
let original_curve = Curve::new(&left_endpoint_position,
@ -1072,17 +1061,18 @@ impl<'a> Partitioner<'a> {
&right_endpoint_position);
let (left_curve, right_curve) = original_curve.subdivide(t);
left_curve_control_point_vertex_index = self.b_vertex_loop_blinn_data.len() as u32;
left_curve_control_point_vertex_index =
self.library.b_vertex_loop_blinn_data.len() as u32;
active_edge.left_vertex_index = left_curve_control_point_vertex_index + 1;
active_edge.control_point_vertex_index = left_curve_control_point_vertex_index + 2;
self.b_vertex_positions.extend([
self.library.b_vertex_positions.extend([
left_curve.control_point,
left_curve.endpoints[1],
right_curve.control_point,
].into_iter());
self.b_vertex_path_ids.extend(iter::repeat(self.path_id).take(3));
self.b_vertex_loop_blinn_data.extend([
self.library.b_vertex_path_ids.extend(iter::repeat(self.path_id).take(3));
self.library.b_vertex_loop_blinn_data.extend([
BVertexLoopBlinnData::control_point(&left_curve.endpoints[0],
&left_curve.control_point,
&left_curve.endpoints[1],
@ -1139,82 +1129,6 @@ impl<'a> Partitioner<'a> {
}
}
#[derive(Debug, Clone)]
struct CoverIndicesBuffer {
interior_indices: Vec<u32>,
curve_indices: Vec<u32>,
}
impl CoverIndicesBuffer {
fn new() -> CoverIndicesBuffer {
CoverIndicesBuffer {
interior_indices: vec![],
curve_indices: vec![],
}
}
fn clear(&mut self) {
self.interior_indices.clear();
self.curve_indices.clear();
}
fn as_ref(&self) -> CoverIndices {
CoverIndices {
interior_indices: &self.interior_indices,
curve_indices: &self.curve_indices,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct CoverIndices<'a> {
pub interior_indices: &'a [u32],
pub curve_indices: &'a [u32],
}
#[derive(Debug, Clone)]
struct EdgeIndicesBuffer {
upper_line_indices: Vec<LineIndices>,
upper_curve_indices: Vec<CurveIndices>,
lower_line_indices: Vec<LineIndices>,
lower_curve_indices: Vec<CurveIndices>,
}
impl EdgeIndicesBuffer {
fn new() -> EdgeIndicesBuffer {
EdgeIndicesBuffer {
upper_line_indices: vec![],
upper_curve_indices: vec![],
lower_line_indices: vec![],
lower_curve_indices: vec![],
}
}
fn clear(&mut self) {
self.upper_line_indices.clear();
self.upper_curve_indices.clear();
self.lower_line_indices.clear();
self.lower_curve_indices.clear();
}
fn as_ref(&self) -> EdgeIndices {
EdgeIndices {
upper_line_indices: &self.upper_line_indices,
upper_curve_indices: &self.upper_curve_indices,
lower_line_indices: &self.lower_line_indices,
lower_curve_indices: &self.lower_curve_indices,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct EdgeIndices<'a> {
pub upper_line_indices: &'a [LineIndices],
pub upper_curve_indices: &'a [CurveIndices],
pub lower_line_indices: &'a [LineIndices],
pub lower_curve_indices: &'a [CurveIndices],
}
#[derive(Debug, Clone, Copy)]
struct Point {
position: Point2D<f32>,