use crate::*;
use ae_sys::*;
define_suite!(
PathQuerySuite,
PF_PathQuerySuite1,
kPFPathQuerySuite,
kPFPathQuerySuiteVersion1
);
impl PathQuerySuite {
pub fn new() -> Result<Self, Error> {
crate::Suite::new()
}
pub fn num_paths(&self, effect_ref: impl AsPtr<PF_ProgPtr>) -> Result<i32, Error> {
call_suite_fn_single!(self, PF_NumPaths -> A_long, effect_ref.as_ptr())
}
pub fn path_info(&self, effect_ref: impl AsPtr<PF_ProgPtr>, index: i32) -> Result<PF_PathID, Error> {
call_suite_fn_single!(self, PF_PathInfo -> PF_PathID, effect_ref.as_ptr(), index)
}
pub fn checkout_path(&self, effect_ref: impl AsPtr<PF_ProgPtr>, unique_id: PF_PathID, what_time: i32, time_step: i32, time_scale: u32) -> Result<Option<PathOutline>, Error> {
let effect_ref = effect_ref.as_ptr();
let path = call_suite_fn_single!(self, PF_CheckoutPath -> PF_PathOutlinePtr, effect_ref, unique_id, what_time, time_step, time_scale)?;
PathOutline::from_raw(effect_ref, unique_id, path)
}
pub fn checkin_path(&self, effect_ref: impl AsPtr<PF_ProgPtr>, unique_id: PF_PathID, changed: bool, path: PF_PathOutlinePtr) -> Result<(), Error> {
call_suite_fn!(self, PF_CheckinPath, effect_ref.as_ptr(), unique_id, changed as _, path)
}
}
define_suite!(
PathDataSuite,
PF_PathDataSuite1,
kPFPathDataSuite,
kPFPathDataSuiteVersion1
);
impl PathDataSuite {
pub fn new() -> Result<Self, Error> {
crate::Suite::new()
}
pub fn path_is_open(&self, effect_ref: impl AsPtr<PF_ProgPtr>, path: PF_PathOutlinePtr) -> Result<bool, Error> {
Ok(call_suite_fn_single!(self, PF_PathIsOpen -> PF_Boolean, effect_ref.as_ptr(), path)? != 0)
}
pub fn path_num_segments(&self, effect_ref: impl AsPtr<PF_ProgPtr>, path: PF_PathOutlinePtr) -> Result<i32, Error> {
call_suite_fn_single!(self, PF_PathNumSegments -> A_long, effect_ref.as_ptr(), path)
}
pub fn path_vertex_info(&self, effect_ref: impl AsPtr<PF_ProgPtr>, path: PF_PathOutlinePtr, which_point: i32) -> Result<PF_PathVertex, Error> {
call_suite_fn_single!(self, PF_PathVertexInfo -> PF_PathVertex, effect_ref.as_ptr(), path, which_point)
}
pub fn path_prepare_seg_length(&self, effect_ref: impl AsPtr<PF_ProgPtr>, path: PF_PathOutlinePtr, which_seg: i32, frequency: i32) -> Result<PF_PathSegPrepPtr, Error> {
call_suite_fn_single!(self, PF_PathPrepareSegLength -> PF_PathSegPrepPtr, effect_ref.as_ptr(), path, which_seg, frequency)
}
pub fn path_get_seg_length(&self, effect_ref: impl AsPtr<PF_ProgPtr>, path: PF_PathOutlinePtr, which_seg: i32, length_prep: &mut PF_PathSegPrepPtr) -> Result<f64, Error> {
call_suite_fn_single!(self, PF_PathGetSegLength -> PF_FpLong, effect_ref.as_ptr(), path, which_seg, length_prep)
}
pub fn path_eval_seg_length(&self, effect_ref: impl AsPtr<PF_ProgPtr>, path: PF_PathOutlinePtr, length_prep: &mut PF_PathSegPrepPtr, which_seg: i32, length: f64) -> Result<(f64, f64), Error> {
call_suite_fn_double!(self, PF_PathEvalSegLength -> PF_FpLong, PF_FpLong, effect_ref.as_ptr(), path, length_prep, which_seg, length)
}
pub fn path_eval_seg_length_deriv1(&self, effect_ref: impl AsPtr<PF_ProgPtr>, path: PF_PathOutlinePtr, length_prep: &mut PF_PathSegPrepPtr, which_seg: i32, length: f64) -> Result<(f64, f64, f64, f64), Error> {
let mut x = 0.0;
let mut y = 0.0;
let mut deriv1x = 0.0;
let mut deriv1y = 0.0;
call_suite_fn!(self, PF_PathEvalSegLengthDeriv1, effect_ref.as_ptr(), path, length_prep, which_seg, length, &mut x, &mut y, &mut deriv1x, &mut deriv1y)?;
Ok((x, y, deriv1x, deriv1y))
}
pub fn path_cleanup_seg_length(&self, effect_ref: impl AsPtr<PF_ProgPtr>, path: PF_PathOutlinePtr, which_seg: i32, length_prep: &mut PF_PathSegPrepPtr) -> Result<(), Error> {
call_suite_fn!(self, PF_PathCleanupSegLength, effect_ref.as_ptr(), path, which_seg, length_prep)
}
pub fn path_is_inverted(&self, effect_ref: impl AsPtr<PF_ProgPtr>, unique_id: PF_PathID) -> Result<bool, Error> {
Ok(call_suite_fn_single!(self, PF_PathIsInverted -> PF_Boolean, effect_ref.as_ptr(), unique_id)? != 0)
}
pub fn path_get_mask_mode(&self, effect_ref: impl AsPtr<PF_ProgPtr>, unique_id: PF_PathID) -> Result<MaskMode, Error> {
Ok(call_suite_fn_single!(self, PF_PathGetMaskMode -> PF_MaskMode, effect_ref.as_ptr(), unique_id)?.into())
}
pub fn path_get_name(&self, effect_ref: impl AsPtr<PF_ProgPtr>, unique_id: PF_PathID) -> Result<String, Error> {
let mut name = [0; PF_MAX_PATH_NAME_LEN as usize + 1];
call_suite_fn!(self, PF_PathGetName, effect_ref.as_ptr(), unique_id, name.as_mut_ptr())?;
Ok(unsafe { std::ffi::CStr::from_ptr(name.as_ptr()) }.to_string_lossy().into_owned())
}
}
define_enum! {
PF_MaskMode,
MaskMode {
None = ae_sys::PF_MaskMode_NONE,
Add = ae_sys::PF_MaskMode_ADD,
Subtract = ae_sys::PF_MaskMode_SUBTRACT,
Intersect = ae_sys::PF_MaskMode_INTERSECT,
Lighten = ae_sys::PF_MaskMode_LIGHTEN,
Darken = ae_sys::PF_MaskMode_DARKEN,
Difference = ae_sys::PF_MaskMode_DIFFERENCE,
Accum = ae_sys::PF_MaskMode_ACCUM,
}
}
pub struct PathOutline {
suite: PathDataSuite,
effect_ref: PF_ProgPtr,
unique_id: PF_PathID,
path: PF_PathOutlinePtr,
}
impl std::fmt::Debug for PathOutline {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn e(r: &Result<impl std::fmt::Debug, Error>) -> &dyn std::fmt::Debug {
match r {
Ok(x) => x,
Err(e) => e,
}
}
f.debug_struct("PathOutline")
.field("name", e(&self.name()))
.field("id", &self.id())
.field("num_segments", e(&self.num_segments()))
.field("is_open", e(&self.is_open()))
.field("is_inverted", e(&self.is_inverted()))
.field("mask_mode", e(&self.mask_mode()))
.finish()
}
}
impl AsPtr<PF_PathOutlinePtr> for PathOutline {
fn as_ptr(&self) -> PF_PathOutlinePtr {
self.path
}
}
impl PathOutline {
pub fn from_raw(effect_ref: PF_ProgPtr, unique_id: PF_PathID, path: PF_PathOutlinePtr) -> Result<Option<Self>, Error> {
if path.is_null() {
Ok(None)
} else {
Ok(Some(Self {
suite: PathDataSuite::new()?,
effect_ref,
unique_id,
path,
}))
}
}
pub fn id(&self) -> PF_PathID {
self.unique_id
}
pub fn is_open(&self) -> Result<bool, Error> {
self.suite.path_is_open(self.effect_ref, self.path)
}
pub fn num_segments(&self) -> Result<i32, Error> {
self.suite.path_num_segments(self.effect_ref, self.path)
}
pub fn vertex(&self, which_point: i32) -> Result<PF_PathVertex, Error> {
self.suite.path_vertex_info(self.effect_ref, self.path, which_point)
}
pub fn prepare_seg_length(&self, which_seg: i32, frequency: i32) -> Result<PathSegPrep<'_>, Error> {
Ok(PathSegPrep {
path: self,
which_seg,
length_prep: self.suite.path_prepare_seg_length(self.effect_ref, self.path, which_seg, frequency)?,
})
}
pub fn is_inverted(&self) -> Result<bool, Error> {
self.suite.path_is_inverted(self.effect_ref, self.unique_id)
}
pub fn mask_mode(&self) -> Result<MaskMode, Error> {
self.suite.path_get_mask_mode(self.effect_ref, self.unique_id)
}
pub fn name(&self) -> Result<String, Error> {
self.suite.path_get_name(self.effect_ref, self.unique_id)
}
}
impl Drop for PathOutline {
fn drop(&mut self) {
PathQuerySuite::new()
.expect("Failed to acquire PathQuerySuite")
.checkin_path(self.effect_ref, self.unique_id, false, self.path)
.expect("Failed to check in PF_PathOutlinePtr");
}
}
pub struct PathSegPrep<'a> {
path: &'a PathOutline,
which_seg: i32,
length_prep: PF_PathSegPrepPtr,
}
impl<'a> PathSegPrep<'a> {
pub fn length(&mut self) -> Result<f64, Error> {
self.path.suite.path_get_seg_length(self.path.effect_ref, self.path.path, self.which_seg, &mut self.length_prep)
}
pub fn eval(&mut self, length: f64) -> Result<(f64, f64), Error> {
self.path.suite.path_eval_seg_length(self.path.effect_ref, self.path.path, &mut self.length_prep, self.which_seg, length)
}
pub fn eval_deriv1(&mut self, length: f64) -> Result<(f64, f64, f64, f64), Error> {
self.path.suite.path_eval_seg_length_deriv1(self.path.effect_ref, self.path.path, &mut self.length_prep, self.which_seg, length)
}
}
impl<'a> Drop for PathSegPrep<'a> {
fn drop(&mut self) {
self.path
.suite
.path_cleanup_seg_length(self.path.effect_ref, self.path.path, self.which_seg, &mut self.length_prep)
.expect("Failed to clean up PF_PathSegPrepPtr");
}
}