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:
parent
8c6110a388
commit
475f5dca71
|
@ -25,6 +25,7 @@ use app_units::Au;
|
||||||
use bincode::Infinite;
|
use bincode::Infinite;
|
||||||
use euclid::{Point2D, Size2D, Transform2D};
|
use euclid::{Point2D, Size2D, Transform2D};
|
||||||
use pathfinder_font_renderer::{FontContext, FontInstanceKey, FontKey, GlyphKey};
|
use pathfinder_font_renderer::{FontContext, FontInstanceKey, FontKey, GlyphKey};
|
||||||
|
use pathfinder_partitioner::mesh_library::{MeshLibrary, MeshLibraryIndexRanges};
|
||||||
use pathfinder_partitioner::partitioner::Partitioner;
|
use pathfinder_partitioner::partitioner::Partitioner;
|
||||||
use pathfinder_path_utils::cubic::CubicCurve;
|
use pathfinder_path_utils::cubic::CubicCurve;
|
||||||
use pathfinder_path_utils::monotonic::MonotonicPathSegmentStream;
|
use pathfinder_path_utils::monotonic::MonotonicPathSegmentStream;
|
||||||
|
@ -38,6 +39,7 @@ use serde::Serialize;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::ops::Range;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
@ -82,26 +84,6 @@ struct SubpathRange {
|
||||||
end: u32,
|
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)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
struct PartitionFontRequest {
|
struct PartitionFontRequest {
|
||||||
face: PartitionFontRequestFace,
|
face: PartitionFontRequestFace,
|
||||||
|
@ -143,7 +125,7 @@ impl PartitionGlyphDimensions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
struct PartitionGlyphInfo {
|
struct PartitionGlyphInfo {
|
||||||
id: u32,
|
id: u32,
|
||||||
dimensions: PartitionGlyphDimensions,
|
dimensions: PartitionGlyphDimensions,
|
||||||
|
@ -160,24 +142,39 @@ struct PartitionFontResponse {
|
||||||
time: f64,
|
time: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
struct PartitionPathIndices {
|
struct PartitionPathIndices {
|
||||||
#[serde(rename = "bQuadIndices")]
|
#[serde(rename = "bQuadIndices")]
|
||||||
b_quad_indices: IndexRange,
|
b_quad_indices: Range<usize>,
|
||||||
#[serde(rename = "bVertexIndices")]
|
#[serde(rename = "bVertexIndices")]
|
||||||
b_vertex_indices: IndexRange,
|
b_vertex_indices: Range<usize>,
|
||||||
#[serde(rename = "coverInteriorIndices")]
|
#[serde(rename = "coverInteriorIndices")]
|
||||||
cover_interior_indices: IndexRange,
|
cover_interior_indices: Range<usize>,
|
||||||
#[serde(rename = "coverCurveIndices")]
|
#[serde(rename = "coverCurveIndices")]
|
||||||
cover_curve_indices: IndexRange,
|
cover_curve_indices: Range<usize>,
|
||||||
#[serde(rename = "coverUpperLineIndices")]
|
#[serde(rename = "coverUpperLineIndices")]
|
||||||
edge_upper_line_indices: IndexRange,
|
edge_upper_line_indices: Range<usize>,
|
||||||
#[serde(rename = "coverUpperCurveIndices")]
|
#[serde(rename = "coverUpperCurveIndices")]
|
||||||
edge_upper_curve_indices: IndexRange,
|
edge_upper_curve_indices: Range<usize>,
|
||||||
#[serde(rename = "coverLowerLineIndices")]
|
#[serde(rename = "coverLowerLineIndices")]
|
||||||
edge_lower_line_indices: IndexRange,
|
edge_lower_line_indices: Range<usize>,
|
||||||
#[serde(rename = "coverLowerCurveIndices")]
|
#[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)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
@ -272,82 +269,20 @@ impl PathPartitioningResult {
|
||||||
-> PathPartitioningResult {
|
-> PathPartitioningResult {
|
||||||
let timestamp_before = Instant::now();
|
let timestamp_before = Instant::now();
|
||||||
|
|
||||||
let (mut b_quads, mut b_vertex_positions) = (vec![], vec![]);
|
partitioner.library_mut().clear();
|
||||||
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![]);
|
|
||||||
|
|
||||||
let mut path_indices = vec![];
|
let mut path_indices = vec![];
|
||||||
|
|
||||||
for (path_index, subpath_range) in subpath_indices.iter().enumerate() {
|
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();
|
path_indices.push(PartitionPathIndices::new(index_ranges));
|
||||||
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(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse interior indices for early Z optimizations.
|
// 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() {
|
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_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>();
|
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.start = new_start_index;
|
||||||
path_indices.cover_interior_indices.end = new_end_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 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 {
|
let encoded_path_data = PartitionEncodedPathData {
|
||||||
b_quads: base64::encode(&b_quads),
|
b_quads: b_quads_buffer,
|
||||||
b_vertex_positions: base64::encode(&b_vertex_positions),
|
b_vertex_positions: b_vertex_positions_buffer,
|
||||||
b_vertex_path_ids: base64::encode(&b_vertex_path_ids),
|
b_vertex_path_ids: b_vertex_path_ids_buffer,
|
||||||
b_vertex_loop_blinn_data: base64::encode(&b_vertex_loop_blinn_data),
|
b_vertex_loop_blinn_data: b_vertex_loop_blinn_data_buffer,
|
||||||
cover_interior_indices: base64::encode(&cover_interior_indices),
|
cover_interior_indices: cover_interior_indices_buffer,
|
||||||
cover_curve_indices: base64::encode(&cover_curve_indices),
|
cover_curve_indices: cover_curve_indices_buffer,
|
||||||
edge_upper_line_indices: base64::encode(&edge_upper_line_indices),
|
edge_upper_line_indices: edge_upper_line_indices_buffer,
|
||||||
edge_upper_curve_indices: base64::encode(&edge_upper_curve_indices),
|
edge_upper_curve_indices: edge_upper_curve_indices_buffer,
|
||||||
edge_lower_line_indices: base64::encode(&edge_lower_line_indices),
|
edge_lower_line_indices: edge_lower_line_indices_buffer,
|
||||||
edge_lower_curve_indices: base64::encode(&edge_lower_curve_indices),
|
edge_lower_curve_indices: edge_lower_curve_indices_buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
PathPartitioningResult {
|
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>")]
|
#[post("/partition-font", format = "application/json", data = "<request>")]
|
||||||
fn partition_font(request: Json<PartitionFontRequest>)
|
fn partition_font(request: Json<PartitionFontRequest>)
|
||||||
-> Json<Result<PartitionFontResponse, PartitionFontError>> {
|
-> Json<Result<PartitionFontResponse, PartitionFontError>> {
|
||||||
|
@ -450,7 +406,7 @@ fn partition_font(request: Json<PartitionFontRequest>)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
// Partition the decoded glyph outlines.
|
// Partition the decoded glyph outlines.
|
||||||
let mut partitioner = Partitioner::new();
|
let mut partitioner = Partitioner::new(MeshLibrary::new());
|
||||||
partitioner.init_with_path_buffer(&path_buffer);
|
partitioner.init_with_path_buffer(&path_buffer);
|
||||||
let path_partitioning_result = PathPartitioningResult::compute(&mut partitioner,
|
let path_partitioning_result = PathPartitioningResult::compute(&mut partitioner,
|
||||||
&subpath_indices);
|
&subpath_indices);
|
||||||
|
@ -476,7 +432,7 @@ fn partition_font(request: Json<PartitionFontRequest>)
|
||||||
glyph_info.push(PartitionGlyphInfo {
|
glyph_info.push(PartitionGlyphInfo {
|
||||||
id: glyph.id,
|
id: glyph.id,
|
||||||
dimensions: dimensions,
|
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.
|
// Partition the paths.
|
||||||
let mut partitioner = Partitioner::new();
|
let mut partitioner = Partitioner::new(MeshLibrary::new());
|
||||||
partitioner.init_with_path_buffer(&path_buffer);
|
partitioner.init_with_path_buffer(&path_buffer);
|
||||||
let path_partitioning_result = PathPartitioningResult::compute(&mut partitioner, &paths);
|
let path_partitioning_result = PathPartitioningResult::compute(&mut partitioner, &paths);
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
|
|
||||||
use env_logger;
|
use env_logger;
|
||||||
use euclid::Point2D;
|
use euclid::Point2D;
|
||||||
use partitioner::Partitioner;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
|
use mesh_library::MeshLibrary;
|
||||||
|
use partitioner::Partitioner;
|
||||||
use {BQuad, BVertexLoopBlinnData, CurveIndices, Endpoint, LineIndices, Subpath};
|
use {BQuad, BVertexLoopBlinnData, CurveIndices, Endpoint, LineIndices, Subpath};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
@ -56,7 +58,7 @@ pub struct EdgeIndices {
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn pf_partitioner_new() -> *mut Partitioner<'static> {
|
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;
|
let partitioner_ptr: *mut Partitioner<'static> = &mut *partitioner;
|
||||||
mem::forget(partitioner);
|
mem::forget(partitioner);
|
||||||
partitioner_ptr
|
partitioner_ptr
|
||||||
|
@ -86,14 +88,14 @@ pub unsafe extern fn pf_partitioner_partition<'a>(partitioner: *mut Partitioner<
|
||||||
path_id: u16,
|
path_id: u16,
|
||||||
first_subpath_index: u32,
|
first_subpath_index: u32,
|
||||||
last_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]
|
#[no_mangle]
|
||||||
pub unsafe extern fn pf_partitioner_b_quads<'a>(partitioner: *const Partitioner<'a>,
|
pub unsafe extern fn pf_partitioner_b_quads<'a>(partitioner: *const Partitioner<'a>,
|
||||||
out_b_quad_count: *mut u32)
|
out_b_quad_count: *mut u32)
|
||||||
-> *const BQuad {
|
-> *const BQuad {
|
||||||
let b_quads = (*partitioner).b_quads();
|
let b_quads = &(*partitioner).library().b_quads;
|
||||||
if !out_b_quad_count.is_null() {
|
if !out_b_quad_count.is_null() {
|
||||||
*out_b_quad_count = b_quads.len() as u32
|
*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>,
|
pub unsafe extern fn pf_partitioner_b_vertex_positions<'a>(partitioner: *const Partitioner<'a>,
|
||||||
out_b_vertex_count: *mut u32)
|
out_b_vertex_count: *mut u32)
|
||||||
-> *const Point2D<f32> {
|
-> *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() {
|
if !out_b_vertex_count.is_null() {
|
||||||
*out_b_vertex_count = b_vertex_positions.len() as u32
|
*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>,
|
pub unsafe extern fn pf_partitioner_b_vertex_path_ids<'a>(partitioner: *const Partitioner<'a>,
|
||||||
out_b_vertex_count: *mut u32)
|
out_b_vertex_count: *mut u32)
|
||||||
-> *const u16 {
|
-> *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() {
|
if !out_b_vertex_count.is_null() {
|
||||||
*out_b_vertex_count = b_vertex_path_ids.len() as u32
|
*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>,
|
partitioner: *const Partitioner<'a>,
|
||||||
out_b_vertex_count: *mut u32)
|
out_b_vertex_count: *mut u32)
|
||||||
-> *const BVertexLoopBlinnData {
|
-> *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() {
|
if !out_b_vertex_count.is_null() {
|
||||||
*out_b_vertex_count = b_vertex_loop_blinn_data.len() as u32
|
*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]
|
#[no_mangle]
|
||||||
pub unsafe extern fn pf_partitioner_cover_indices<'a>(partitioner: *const Partitioner<'a>,
|
pub unsafe extern fn pf_partitioner_cover_indices<'a>(partitioner: *const Partitioner<'a>,
|
||||||
out_cover_indices: *mut CoverIndices) {
|
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 = cover_indices.interior_indices.as_ptr();
|
||||||
(*out_cover_indices).interior_indices_len = cover_indices.interior_indices.len() as u32;
|
(*out_cover_indices).interior_indices_len = cover_indices.interior_indices.len() as u32;
|
||||||
(*out_cover_indices).curve_indices = cover_indices.curve_indices.as_ptr();
|
(*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]
|
#[no_mangle]
|
||||||
pub unsafe extern fn pf_partitioner_edge_indices<'a>(partitioner: *const Partitioner<'a>,
|
pub unsafe extern fn pf_partitioner_edge_indices<'a>(partitioner: *const Partitioner<'a>,
|
||||||
out_edge_indices: *mut EdgeIndices) {
|
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 = 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_line_indices_len = edge_indices.upper_line_indices.len() as u32;
|
||||||
(*out_edge_indices).upper_curve_indices = edge_indices.upper_curve_indices.as_ptr();
|
(*out_edge_indices).upper_curve_indices = edge_indices.upper_curve_indices.as_ptr();
|
||||||
|
|
|
@ -26,6 +26,7 @@ use pathfinder_path_utils::{Endpoint, Subpath};
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
|
||||||
pub mod capi;
|
pub mod capi;
|
||||||
|
pub mod mesh_library;
|
||||||
pub mod partitioner;
|
pub mod partitioner;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
|
@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ use std::f32;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
|
||||||
|
use mesh_library::{MeshLibrary, MeshLibraryIndexRanges};
|
||||||
use {BQuad, BVertexLoopBlinnData, BVertexKind, CurveIndices, Endpoint, FillRule};
|
use {BQuad, BVertexLoopBlinnData, BVertexKind, CurveIndices, Endpoint, FillRule};
|
||||||
use {LineIndices, Subpath};
|
use {LineIndices, Subpath};
|
||||||
|
|
||||||
|
@ -31,14 +32,9 @@ pub struct Partitioner<'a> {
|
||||||
control_points: &'a [Point2D<f32>],
|
control_points: &'a [Point2D<f32>],
|
||||||
subpaths: &'a [Subpath],
|
subpaths: &'a [Subpath],
|
||||||
|
|
||||||
fill_rule: FillRule,
|
library: MeshLibrary,
|
||||||
|
|
||||||
b_quads: Vec<BQuad>,
|
fill_rule: FillRule,
|
||||||
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,
|
|
||||||
|
|
||||||
heap: BinaryHeap<Point>,
|
heap: BinaryHeap<Point>,
|
||||||
visited_points: BitVec,
|
visited_points: BitVec,
|
||||||
|
@ -48,7 +44,7 @@ pub struct Partitioner<'a> {
|
||||||
|
|
||||||
impl<'a> Partitioner<'a> {
|
impl<'a> Partitioner<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<'b>() -> Partitioner<'b> {
|
pub fn new<'b>(library: MeshLibrary) -> Partitioner<'b> {
|
||||||
Partitioner {
|
Partitioner {
|
||||||
endpoints: &[],
|
endpoints: &[],
|
||||||
control_points: &[],
|
control_points: &[],
|
||||||
|
@ -56,12 +52,7 @@ impl<'a> Partitioner<'a> {
|
||||||
|
|
||||||
fill_rule: FillRule::Winding,
|
fill_rule: FillRule::Winding,
|
||||||
|
|
||||||
b_quads: vec![],
|
library: library,
|
||||||
b_vertex_positions: vec![],
|
|
||||||
b_vertex_path_ids: vec![],
|
|
||||||
b_vertex_loop_blinn_data: vec![],
|
|
||||||
cover_indices: CoverIndicesBuffer::new(),
|
|
||||||
edge_indices: EdgeIndicesBuffer::new(),
|
|
||||||
|
|
||||||
heap: BinaryHeap::new(),
|
heap: BinaryHeap::new(),
|
||||||
visited_points: BitVec::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,
|
pub fn init_with_raw_data(&mut self,
|
||||||
new_endpoints: &'a [Endpoint],
|
new_endpoints: &'a [Endpoint],
|
||||||
new_control_points: &'a [Point2D<f32>],
|
new_control_points: &'a [Point2D<f32>],
|
||||||
|
@ -94,54 +100,26 @@ impl<'a> Partitioner<'a> {
|
||||||
self.fill_rule = new_fill_rule
|
self.fill_rule = new_fill_rule
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn partition(&mut self, path_id: u16, first_subpath_index: u32, last_subpath_index: u32) {
|
pub fn partition(&mut self, path_id: u16, first_subpath_index: u32, last_subpath_index: u32)
|
||||||
self.b_quads.clear();
|
-> MeshLibraryIndexRanges {
|
||||||
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();
|
|
||||||
self.heap.clear();
|
self.heap.clear();
|
||||||
self.active_edges.clear();
|
self.active_edges.clear();
|
||||||
|
|
||||||
|
let start_lengths = self.library.snapshot_lengths();
|
||||||
|
|
||||||
self.path_id = path_id;
|
self.path_id = path_id;
|
||||||
|
|
||||||
self.init_heap(first_subpath_index, last_subpath_index);
|
self.init_heap(first_subpath_index, last_subpath_index);
|
||||||
|
|
||||||
while self.process_next_point() {}
|
while self.process_next_point() {}
|
||||||
|
|
||||||
debug_assert!(self.b_vertex_loop_blinn_data.len() == self.b_vertex_path_ids.len());
|
debug_assert!(self.library.b_vertex_loop_blinn_data.len() ==
|
||||||
debug_assert!(self.b_vertex_loop_blinn_data.len() == self.b_vertex_positions.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]
|
let end_lengths = self.library.snapshot_lengths();
|
||||||
pub fn b_quads(&self) -> &[BQuad] {
|
MeshLibraryIndexRanges::new(&start_lengths, &end_lengths)
|
||||||
&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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_next_point(&mut self) -> bool {
|
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
|
// If we already made a B-vertex point for this endpoint, reuse it instead of making a
|
||||||
// new one.
|
// new one.
|
||||||
let old_left_position =
|
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() >
|
let should_update = (endpoint_position - old_left_position).square_length() >
|
||||||
f32::approx_epsilon();
|
f32::approx_epsilon();
|
||||||
if should_update {
|
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;
|
active_edge.control_point_vertex_index = active_edge.left_vertex_index + 1;
|
||||||
|
|
||||||
self.b_vertex_positions.push(endpoint_position);
|
self.library.b_vertex_positions.push(endpoint_position);
|
||||||
self.b_vertex_path_ids.push(self.path_id);
|
self.library.b_vertex_path_ids.push(self.path_id);
|
||||||
self.b_vertex_loop_blinn_data.push(BVertexLoopBlinnData::new(
|
self.library.b_vertex_loop_blinn_data.push(BVertexLoopBlinnData::new(
|
||||||
active_edge.endpoint_kind()));
|
active_edge.endpoint_kind()));
|
||||||
|
|
||||||
active_edge.toggle_parity();
|
active_edge.toggle_parity();
|
||||||
|
@ -264,19 +242,19 @@ impl<'a> Partitioner<'a> {
|
||||||
}
|
}
|
||||||
control_point_index => {
|
control_point_index => {
|
||||||
self.active_edges[active_edge_index as usize].control_point_vertex_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]
|
let left_vertex_index = self.active_edges[active_edge_index as usize]
|
||||||
.left_vertex_index;
|
.left_vertex_index;
|
||||||
let control_point_position = &self.control_points[control_point_index as usize];
|
let control_point_position = &self.control_points[control_point_index as usize];
|
||||||
let control_point_b_vertex_loop_blinn_data = BVertexLoopBlinnData::control_point(
|
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,
|
&control_point_position,
|
||||||
&new_point.position,
|
&new_point.position,
|
||||||
bottom);
|
bottom);
|
||||||
self.b_vertex_positions.push(*control_point_position);
|
self.library.b_vertex_positions.push(*control_point_position);
|
||||||
self.b_vertex_path_ids.push(self.path_id);
|
self.library.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_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..
|
let new_active_edges = &mut self.active_edges[next_active_edge_index as usize..
|
||||||
next_active_edge_index as usize + 2];
|
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[0].left_vertex_index = left_vertex_index;
|
||||||
new_active_edges[1].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;
|
let position = self.endpoints[endpoint_index as usize].position;
|
||||||
self.b_vertex_positions.push(position);
|
self.library.b_vertex_positions.push(position);
|
||||||
self.b_vertex_path_ids.push(self.path_id);
|
self.library.b_vertex_path_ids.push(self.path_id);
|
||||||
self.b_vertex_loop_blinn_data.push(BVertexLoopBlinnData::new(BVertexKind::Endpoint0));
|
self.library.b_vertex_loop_blinn_data
|
||||||
|
.push(BVertexLoopBlinnData::new(BVertexKind::Endpoint0));
|
||||||
|
|
||||||
new_active_edges[0].toggle_parity();
|
new_active_edges[0].toggle_parity();
|
||||||
new_active_edges[1].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,
|
u32::MAX => new_active_edges[0].control_point_vertex_index = u32::MAX,
|
||||||
upper_control_point_index => {
|
upper_control_point_index => {
|
||||||
new_active_edges[0].control_point_vertex_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 =
|
let control_point_position =
|
||||||
self.control_points[upper_control_point_index as usize];
|
self.control_points[upper_control_point_index as usize];
|
||||||
|
@ -404,9 +383,9 @@ impl<'a> Partitioner<'a> {
|
||||||
&control_point_position,
|
&control_point_position,
|
||||||
&right_vertex_position,
|
&right_vertex_position,
|
||||||
false);
|
false);
|
||||||
self.b_vertex_positions.push(control_point_position);
|
self.library.b_vertex_positions.push(control_point_position);
|
||||||
self.b_vertex_path_ids.push(self.path_id);
|
self.library.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_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,
|
u32::MAX => new_active_edges[1].control_point_vertex_index = u32::MAX,
|
||||||
lower_control_point_index => {
|
lower_control_point_index => {
|
||||||
new_active_edges[1].control_point_vertex_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 =
|
let control_point_position =
|
||||||
self.control_points[lower_control_point_index as usize];
|
self.control_points[lower_control_point_index as usize];
|
||||||
|
@ -425,9 +404,9 @@ impl<'a> Partitioner<'a> {
|
||||||
&control_point_position,
|
&control_point_position,
|
||||||
&right_vertex_position,
|
&right_vertex_position,
|
||||||
true);
|
true);
|
||||||
self.b_vertex_positions.push(control_point_position);
|
self.library.b_vertex_positions.push(control_point_position);
|
||||||
self.b_vertex_path_ids.push(self.path_id);
|
self.library.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_loop_blinn_data.push(control_point_b_vertex_loop_blinn_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -562,16 +541,16 @@ impl<'a> Partitioner<'a> {
|
||||||
upper_subdivision: &SubdividedActiveEdge,
|
upper_subdivision: &SubdividedActiveEdge,
|
||||||
lower_subdivision: &SubdividedActiveEdge,
|
lower_subdivision: &SubdividedActiveEdge,
|
||||||
iteration: u8) {
|
iteration: u8) {
|
||||||
let upper_shape = upper_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.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
|
// Make sure the convex hulls of the two curves do not intersect. If they do, subdivide and
|
||||||
// recurse.
|
// recurse.
|
||||||
if iteration < MAX_B_QUAD_SUBDIVISIONS {
|
if iteration < MAX_B_QUAD_SUBDIVISIONS {
|
||||||
// TODO(pcwalton): Handle concave-line convex hull intersections.
|
// TODO(pcwalton): Handle concave-line convex hull intersections.
|
||||||
if let (Some(upper_curve), Some(lower_curve)) =
|
if let (Some(upper_curve), Some(lower_curve)) =
|
||||||
(upper_subdivision.to_curve(&self.b_vertex_positions),
|
(upper_subdivision.to_curve(&self.library.b_vertex_positions),
|
||||||
lower_subdivision.to_curve(&self.b_vertex_positions)) {
|
lower_subdivision.to_curve(&self.library.b_vertex_positions)) {
|
||||||
// TODO(pcwalton): Handle concave-concave convex hull intersections.
|
// TODO(pcwalton): Handle concave-concave convex hull intersections.
|
||||||
if upper_shape == Shape::Concave &&
|
if upper_shape == Shape::Concave &&
|
||||||
lower_curve.baseline().side(&upper_curve.control_point) >
|
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,
|
self.subdivide_active_edge_again_at_t(&upper_subdivision,
|
||||||
0.5,
|
0.5,
|
||||||
false);
|
false);
|
||||||
let midpoint_x = self.b_vertex_positions[upper_left_subsubdivision.middle_point
|
let midpoint_x =
|
||||||
as usize].x;
|
self.library
|
||||||
|
.b_vertex_positions[upper_left_subsubdivision.middle_point as usize].x;
|
||||||
let (lower_left_subsubdivision, lower_right_subsubdivision) =
|
let (lower_left_subsubdivision, lower_right_subsubdivision) =
|
||||||
self.subdivide_active_edge_again_at_x(&lower_subdivision,
|
self.subdivide_active_edge_again_at_x(&lower_subdivision,
|
||||||
midpoint_x,
|
midpoint_x,
|
||||||
|
@ -607,8 +587,9 @@ impl<'a> Partitioner<'a> {
|
||||||
self.subdivide_active_edge_again_at_t(&lower_subdivision,
|
self.subdivide_active_edge_again_at_t(&lower_subdivision,
|
||||||
0.5,
|
0.5,
|
||||||
true);
|
true);
|
||||||
let midpoint_x = self.b_vertex_positions[lower_left_subsubdivision.middle_point
|
let midpoint_x =
|
||||||
as usize].x;
|
self.library
|
||||||
|
.b_vertex_positions[lower_left_subsubdivision.middle_point as usize].x;
|
||||||
let (upper_left_subsubdivision, upper_right_subsubdivision) =
|
let (upper_left_subsubdivision, upper_right_subsubdivision) =
|
||||||
self.subdivide_active_edge_again_at_x(&upper_subdivision,
|
self.subdivide_active_edge_again_at_x(&upper_subdivision,
|
||||||
midpoint_x,
|
midpoint_x,
|
||||||
|
@ -631,13 +612,15 @@ impl<'a> Partitioner<'a> {
|
||||||
|
|
||||||
match upper_shape {
|
match upper_shape {
|
||||||
Shape::Flat => {
|
Shape::Flat => {
|
||||||
self.edge_indices
|
self.library
|
||||||
|
.edge_indices
|
||||||
.upper_line_indices
|
.upper_line_indices
|
||||||
.push(LineIndices::new(upper_subdivision.left_curve_left,
|
.push(LineIndices::new(upper_subdivision.left_curve_left,
|
||||||
upper_subdivision.middle_point))
|
upper_subdivision.middle_point))
|
||||||
}
|
}
|
||||||
Shape::Convex | Shape::Concave => {
|
Shape::Convex | Shape::Concave => {
|
||||||
self.edge_indices
|
self.library
|
||||||
|
.edge_indices
|
||||||
.upper_curve_indices
|
.upper_curve_indices
|
||||||
.push(CurveIndices::new(upper_subdivision.left_curve_left,
|
.push(CurveIndices::new(upper_subdivision.left_curve_left,
|
||||||
upper_subdivision.left_curve_control_point,
|
upper_subdivision.left_curve_control_point,
|
||||||
|
@ -646,13 +629,15 @@ impl<'a> Partitioner<'a> {
|
||||||
}
|
}
|
||||||
match lower_shape {
|
match lower_shape {
|
||||||
Shape::Flat => {
|
Shape::Flat => {
|
||||||
self.edge_indices
|
self.library
|
||||||
|
.edge_indices
|
||||||
.lower_line_indices
|
.lower_line_indices
|
||||||
.push(LineIndices::new(lower_subdivision.left_curve_left,
|
.push(LineIndices::new(lower_subdivision.left_curve_left,
|
||||||
lower_subdivision.middle_point))
|
lower_subdivision.middle_point))
|
||||||
}
|
}
|
||||||
Shape::Convex | Shape::Concave => {
|
Shape::Convex | Shape::Concave => {
|
||||||
self.edge_indices
|
self.library
|
||||||
|
.edge_indices
|
||||||
.lower_curve_indices
|
.lower_curve_indices
|
||||||
.push(CurveIndices::new(lower_subdivision.left_curve_left,
|
.push(CurveIndices::new(lower_subdivision.left_curve_left,
|
||||||
lower_subdivision.left_curve_control_point,
|
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];
|
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());
|
BVertexLoopBlinnData::new(upper_active_edge.endpoint_kind());
|
||||||
upper_active_edge.toggle_parity();
|
upper_active_edge.toggle_parity();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let lower_active_edge = &mut self.active_edges[lower_active_edge_index as usize];
|
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());
|
BVertexLoopBlinnData::new(lower_active_edge.endpoint_kind());
|
||||||
lower_active_edge.toggle_parity();
|
lower_active_edge.toggle_parity();
|
||||||
}
|
}
|
||||||
|
@ -684,7 +669,7 @@ impl<'a> Partitioner<'a> {
|
||||||
(Shape::Flat, Shape::Convex) |
|
(Shape::Flat, Shape::Convex) |
|
||||||
(Shape::Convex, Shape::Flat) |
|
(Shape::Convex, Shape::Flat) |
|
||||||
(Shape::Convex, Shape::Convex) => {
|
(Shape::Convex, Shape::Convex) => {
|
||||||
self.cover_indices.interior_indices.extend([
|
self.library.cover_indices.interior_indices.extend([
|
||||||
upper_subdivision.left_curve_left,
|
upper_subdivision.left_curve_left,
|
||||||
upper_subdivision.middle_point,
|
upper_subdivision.middle_point,
|
||||||
lower_subdivision.left_curve_left,
|
lower_subdivision.left_curve_left,
|
||||||
|
@ -693,14 +678,14 @@ impl<'a> Partitioner<'a> {
|
||||||
upper_subdivision.middle_point,
|
upper_subdivision.middle_point,
|
||||||
].into_iter());
|
].into_iter());
|
||||||
if upper_shape != Shape::Flat {
|
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.left_curve_control_point,
|
||||||
upper_subdivision.middle_point,
|
upper_subdivision.middle_point,
|
||||||
upper_subdivision.left_curve_left,
|
upper_subdivision.left_curve_left,
|
||||||
].into_iter())
|
].into_iter())
|
||||||
}
|
}
|
||||||
if lower_shape != Shape::Flat {
|
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_control_point,
|
||||||
lower_subdivision.left_curve_left,
|
lower_subdivision.left_curve_left,
|
||||||
lower_subdivision.middle_point,
|
lower_subdivision.middle_point,
|
||||||
|
@ -710,7 +695,7 @@ impl<'a> Partitioner<'a> {
|
||||||
|
|
||||||
(Shape::Concave, Shape::Flat) |
|
(Shape::Concave, Shape::Flat) |
|
||||||
(Shape::Concave, Shape::Convex) => {
|
(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_left,
|
||||||
upper_subdivision.left_curve_control_point,
|
upper_subdivision.left_curve_control_point,
|
||||||
lower_subdivision.left_curve_left,
|
lower_subdivision.left_curve_left,
|
||||||
|
@ -721,13 +706,13 @@ impl<'a> Partitioner<'a> {
|
||||||
lower_subdivision.left_curve_left,
|
lower_subdivision.left_curve_left,
|
||||||
upper_subdivision.left_curve_control_point,
|
upper_subdivision.left_curve_control_point,
|
||||||
].into_iter());
|
].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_control_point,
|
||||||
upper_subdivision.left_curve_left,
|
upper_subdivision.left_curve_left,
|
||||||
upper_subdivision.middle_point,
|
upper_subdivision.middle_point,
|
||||||
].into_iter());
|
].into_iter());
|
||||||
if lower_shape != Shape::Flat {
|
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_control_point,
|
||||||
lower_subdivision.left_curve_left,
|
lower_subdivision.left_curve_left,
|
||||||
lower_subdivision.middle_point,
|
lower_subdivision.middle_point,
|
||||||
|
@ -737,7 +722,7 @@ impl<'a> Partitioner<'a> {
|
||||||
|
|
||||||
(Shape::Flat, Shape::Concave) |
|
(Shape::Flat, Shape::Concave) |
|
||||||
(Shape::Convex, 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.left_curve_left,
|
||||||
upper_subdivision.middle_point,
|
upper_subdivision.middle_point,
|
||||||
lower_subdivision.left_curve_control_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_control_point,
|
||||||
lower_subdivision.left_curve_left,
|
lower_subdivision.left_curve_left,
|
||||||
].into_iter());
|
].into_iter());
|
||||||
self.cover_indices.curve_indices.extend([
|
self.library.cover_indices.curve_indices.extend([
|
||||||
lower_subdivision.left_curve_control_point,
|
lower_subdivision.left_curve_control_point,
|
||||||
lower_subdivision.middle_point,
|
lower_subdivision.middle_point,
|
||||||
lower_subdivision.left_curve_left,
|
lower_subdivision.left_curve_left,
|
||||||
].into_iter());
|
].into_iter());
|
||||||
if upper_shape != Shape::Flat {
|
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.left_curve_control_point,
|
||||||
upper_subdivision.middle_point,
|
upper_subdivision.middle_point,
|
||||||
upper_subdivision.left_curve_left,
|
upper_subdivision.left_curve_left,
|
||||||
|
@ -763,7 +748,7 @@ impl<'a> Partitioner<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
(Shape::Concave, Shape::Concave) => {
|
(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_left,
|
||||||
upper_subdivision.left_curve_control_point,
|
upper_subdivision.left_curve_control_point,
|
||||||
lower_subdivision.left_curve_left,
|
lower_subdivision.left_curve_left,
|
||||||
|
@ -777,7 +762,7 @@ impl<'a> Partitioner<'a> {
|
||||||
lower_subdivision.middle_point,
|
lower_subdivision.middle_point,
|
||||||
lower_subdivision.left_curve_control_point,
|
lower_subdivision.left_curve_control_point,
|
||||||
].into_iter());
|
].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_control_point,
|
||||||
upper_subdivision.left_curve_left,
|
upper_subdivision.left_curve_left,
|
||||||
upper_subdivision.middle_point,
|
upper_subdivision.middle_point,
|
||||||
|
@ -788,12 +773,12 @@ 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.left_curve_control_point,
|
||||||
upper_subdivision.middle_point,
|
upper_subdivision.middle_point,
|
||||||
lower_subdivision.left_curve_left,
|
lower_subdivision.left_curve_left,
|
||||||
lower_subdivision.left_curve_control_point,
|
lower_subdivision.left_curve_control_point,
|
||||||
lower_subdivision.middle_point))
|
lower_subdivision.middle_point))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subdivide_active_edge_again_at_t(&mut self,
|
fn subdivide_active_edge_again_at_t(&mut self,
|
||||||
|
@ -801,24 +786,24 @@ impl<'a> Partitioner<'a> {
|
||||||
t: f32,
|
t: f32,
|
||||||
bottom: bool)
|
bottom: bool)
|
||||||
-> (SubdividedActiveEdge, SubdividedActiveEdge) {
|
-> (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!");
|
.expect("subdivide_active_edge_again_at_t(): not a curve!");
|
||||||
let (left_curve, right_curve) = curve.subdivide(t);
|
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 midpoint_index = left_control_point_index + 1;
|
||||||
let right_control_point_index = midpoint_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.control_point,
|
||||||
left_curve.endpoints[1],
|
left_curve.endpoints[1],
|
||||||
right_curve.control_point,
|
right_curve.control_point,
|
||||||
].into_iter());
|
].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
|
// Initially, assume that the parity is false. We will modify the Loop-Blinn data later if
|
||||||
// that is incorrect.
|
// 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],
|
BVertexLoopBlinnData::control_point(&left_curve.endpoints[0],
|
||||||
&left_curve.control_point,
|
&left_curve.control_point,
|
||||||
&left_curve.endpoints[1],
|
&left_curve.endpoints[1],
|
||||||
|
@ -846,7 +831,7 @@ impl<'a> Partitioner<'a> {
|
||||||
x: f32,
|
x: f32,
|
||||||
bottom: bool)
|
bottom: bool)
|
||||||
-> (SubdividedActiveEdge, SubdividedActiveEdge) {
|
-> (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!");
|
.expect("subdivide_active_edge_again_at_x(): not a curve!");
|
||||||
let t = curve.solve_t_for_x(x);
|
let t = curve.solve_t_for_x(x);
|
||||||
self.subdivide_active_edge_again_at_t(subdivision, t, bottom)
|
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 {
|
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
|
let left_vertex_position =
|
||||||
usize];
|
&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]
|
let right_endpoint_position = &self.endpoints[active_edge.right_endpoint_index as usize]
|
||||||
.position;
|
.position;
|
||||||
match active_edge.control_point_vertex_index {
|
match active_edge.control_point_vertex_index {
|
||||||
u32::MAX => Line::new(left_vertex_position, right_endpoint_position).solve_t_for_x(x),
|
u32::MAX => Line::new(left_vertex_position, right_endpoint_position).solve_t_for_x(x),
|
||||||
control_point_vertex_index => {
|
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,
|
Curve::new(left_vertex_position,
|
||||||
control_point,
|
control_point,
|
||||||
right_endpoint_position).solve_t_for_x(x)
|
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> {
|
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
|
let left_vertex_position =
|
||||||
usize];
|
&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]
|
let right_endpoint_position =
|
||||||
.position;
|
&self.endpoints[active_edge.right_endpoint_index as usize].position;
|
||||||
match active_edge.control_point_vertex_index {
|
match active_edge.control_point_vertex_index {
|
||||||
u32::MAX => {
|
u32::MAX => {
|
||||||
left_vertex_position.to_vector()
|
left_vertex_position.to_vector()
|
||||||
|
@ -942,7 +928,8 @@ impl<'a> Partitioner<'a> {
|
||||||
.to_point()
|
.to_point()
|
||||||
}
|
}
|
||||||
control_point_vertex_index => {
|
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)
|
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 =
|
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 =
|
let upper_right_endpoint_position =
|
||||||
&self.endpoints[upper_active_edge.right_endpoint_index as usize].position;
|
&self.endpoints[upper_active_edge.right_endpoint_index as usize].position;
|
||||||
let lower_left_vertex_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 =
|
let lower_right_endpoint_position =
|
||||||
&self.endpoints[lower_active_edge.right_endpoint_index as usize].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) => {
|
(upper_control_point_vertex_index, u32::MAX) => {
|
||||||
let upper_control_point =
|
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, _) =
|
let (upper_curve, _) =
|
||||||
Curve::new(&upper_left_vertex_position,
|
Curve::new(&upper_left_vertex_position,
|
||||||
&upper_control_point,
|
&upper_control_point,
|
||||||
|
@ -995,7 +982,7 @@ impl<'a> Partitioner<'a> {
|
||||||
|
|
||||||
(u32::MAX, lower_control_point_vertex_index) => {
|
(u32::MAX, lower_control_point_vertex_index) => {
|
||||||
let lower_control_point =
|
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, _) =
|
let (lower_curve, _) =
|
||||||
Curve::new(&lower_left_vertex_position,
|
Curve::new(&lower_left_vertex_position,
|
||||||
&lower_control_point,
|
&lower_control_point,
|
||||||
|
@ -1008,9 +995,9 @@ impl<'a> Partitioner<'a> {
|
||||||
|
|
||||||
(upper_control_point_vertex_index, lower_control_point_vertex_index) => {
|
(upper_control_point_vertex_index, lower_control_point_vertex_index) => {
|
||||||
let upper_control_point =
|
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 =
|
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, _) =
|
let (upper_curve, _) =
|
||||||
Curve::new(&upper_left_vertex_position,
|
Curve::new(&upper_left_vertex_position,
|
||||||
&upper_control_point,
|
&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 {
|
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_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()
|
x - left_point_position.x >= f32::approx_epsilon()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1037,7 +1024,7 @@ impl<'a> Partitioner<'a> {
|
||||||
subdivision_type: SubdivisionType)
|
subdivision_type: SubdivisionType)
|
||||||
-> SubdividedActiveEdge {
|
-> SubdividedActiveEdge {
|
||||||
let left_curve_left = self.active_edges[active_edge_index as usize].left_vertex_index;
|
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]);
|
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;
|
let left_curve_control_point_vertex_index;
|
||||||
match active_edge.control_point_vertex_index {
|
match active_edge.control_point_vertex_index {
|
||||||
u32::MAX => {
|
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]
|
let right_point = self.endpoints[active_edge.right_endpoint_index as usize]
|
||||||
.position;
|
.position;
|
||||||
let middle_point = left_point_position.to_vector().lerp(right_point.to_vector(), t);
|
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;
|
active_edge.left_vertex_index = self.library.b_vertex_loop_blinn_data.len() as u32;
|
||||||
self.b_vertex_positions.push(middle_point.to_point());
|
self.library.b_vertex_positions.push(middle_point.to_point());
|
||||||
self.b_vertex_path_ids.push(path_id);
|
self.library.b_vertex_path_ids.push(path_id);
|
||||||
self.b_vertex_loop_blinn_data
|
self.library
|
||||||
|
.b_vertex_loop_blinn_data
|
||||||
.push(BVertexLoopBlinnData::new(active_edge.endpoint_kind()));
|
.push(BVertexLoopBlinnData::new(active_edge.endpoint_kind()));
|
||||||
|
|
||||||
left_curve_control_point_vertex_index = u32::MAX;
|
left_curve_control_point_vertex_index = u32::MAX;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let left_endpoint_position =
|
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 =
|
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 =
|
let right_endpoint_position =
|
||||||
self.endpoints[active_edge.right_endpoint_index as usize].position;
|
self.endpoints[active_edge.right_endpoint_index as usize].position;
|
||||||
let original_curve = Curve::new(&left_endpoint_position,
|
let original_curve = Curve::new(&left_endpoint_position,
|
||||||
|
@ -1072,17 +1061,18 @@ impl<'a> Partitioner<'a> {
|
||||||
&right_endpoint_position);
|
&right_endpoint_position);
|
||||||
let (left_curve, right_curve) = original_curve.subdivide(t);
|
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.left_vertex_index = left_curve_control_point_vertex_index + 1;
|
||||||
active_edge.control_point_vertex_index = left_curve_control_point_vertex_index + 2;
|
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.control_point,
|
||||||
left_curve.endpoints[1],
|
left_curve.endpoints[1],
|
||||||
right_curve.control_point,
|
right_curve.control_point,
|
||||||
].into_iter());
|
].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));
|
||||||
self.b_vertex_loop_blinn_data.extend([
|
self.library.b_vertex_loop_blinn_data.extend([
|
||||||
BVertexLoopBlinnData::control_point(&left_curve.endpoints[0],
|
BVertexLoopBlinnData::control_point(&left_curve.endpoints[0],
|
||||||
&left_curve.control_point,
|
&left_curve.control_point,
|
||||||
&left_curve.endpoints[1],
|
&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)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
struct Point {
|
struct Point {
|
||||||
position: Point2D<f32>,
|
position: Point2D<f32>,
|
||||||
|
|
Loading…
Reference in New Issue