Skip to content

Commit 9d5ba41

Browse files
Add mmAnimCurveFilterPops command.
A maya command plug-in that is used to manipulate an animation curve. This also adds C++ bindings via CXX. GitHub issue #268
1 parent 78fbc47 commit 9d5ba41

File tree

15 files changed

+642
-34
lines changed

15 files changed

+642
-34
lines changed

lib/cppbind/mmscenegraph/include/mmscenegraph/_cxxbridge.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,4 +1202,8 @@ MMSCENEGRAPH_API_EXPORT bool shim_fit_straight_line_to_ordered_points(::rust::Sl
12021202
MMSCENEGRAPH_API_EXPORT bool shim_line_point_intersection(::mmscenegraph::Point3 point, ::mmscenegraph::Point3 line_a, ::mmscenegraph::Point3 line_b, ::mmscenegraph::Point3 &out_point) noexcept;
12031203

12041204
MMSCENEGRAPH_API_EXPORT bool shim_fit_plane_to_points(::rust::Slice<const double> points_xyz, double &out_point_x, double &out_point_y, double &out_point_z, double &out_dir_x, double &out_dir_y, double &out_dir_z, double &out_scale, double &out_rms_error) noexcept;
1205+
1206+
MMSCENEGRAPH_API_EXPORT bool shim_detect_curve_pops(::rust::Slice<const double> x_values, ::rust::Slice<const double> y_values, double threshold, ::rust::Vec<double> &out_x_values, ::rust::Vec<double> &out_y_values) noexcept;
1207+
1208+
MMSCENEGRAPH_API_EXPORT bool shim_filter_curve_pops(::rust::Slice<const double> x_values, ::rust::Slice<const double> y_values, double threshold, ::rust::Vec<double> &out_x_values, ::rust::Vec<double> &out_y_values) noexcept;
12051209
} // namespace mmscenegraph
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (C) 2024 David Cattermole.
3+
*
4+
* This file is part of mmSolver.
5+
*
6+
* mmSolver is free software: you can redistribute it and/or modify it
7+
* under the terms of the GNU Lesser General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* mmSolver is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with mmSolver. If not, see <https://www.gnu.org/licenses/>.
18+
* ====================================================================
19+
*
20+
*/
21+
22+
#ifndef MM_SOLVER_MM_SCENE_GRAPH_CURVE_DETECT_POPS_H
23+
#define MM_SOLVER_MM_SCENE_GRAPH_CURVE_DETECT_POPS_H
24+
25+
#include "_cxx.h"
26+
#include "_cxxbridge.h"
27+
#include "_symbol_export.h"
28+
#include "_types.h"
29+
30+
namespace mmscenegraph {
31+
32+
MMSCENEGRAPH_API_EXPORT
33+
bool detect_curve_pops(rust::Slice<const Real> &x_values,
34+
rust::Slice<const Real> &y_values, const Real threshold,
35+
rust::Vec<Real> &out_x_values,
36+
rust::Vec<Real> &out_y_values) noexcept;
37+
38+
MMSCENEGRAPH_API_EXPORT
39+
bool filter_curve_pops(rust::Slice<const Real> &x_values,
40+
rust::Slice<const Real> &y_values, const Real threshold,
41+
rust::Vec<Real> &out_x_values,
42+
rust::Vec<Real> &out_y_values) noexcept;
43+
44+
} // namespace mmscenegraph
45+
46+
#endif // MM_SOLVER_MM_SCENE_GRAPH_CURVE_DETECT_POPS_H

lib/cppbind/mmscenegraph/include/mmscenegraph/mmscenegraph.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "_cxxbridge.h"
2727
#include "_types.h"
2828
#include "attrdatablock.h"
29+
#include "curve_detect_pops.h"
2930
#include "fit_plane.h"
3031
#include "flatscene.h"
3132
#include "line.h"

lib/cppbind/mmscenegraph/src/_cxxbridge.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,10 @@ bool mmscenegraph$cxxbridge1$shim_fit_straight_line_to_ordered_points(::rust::Sl
13401340
bool mmscenegraph$cxxbridge1$shim_line_point_intersection(::mmscenegraph::Point3 point, ::mmscenegraph::Point3 line_a, ::mmscenegraph::Point3 line_b, ::mmscenegraph::Point3 &out_point) noexcept;
13411341

13421342
bool mmscenegraph$cxxbridge1$shim_fit_plane_to_points(::rust::Slice<const double> points_xyz, double &out_point_x, double &out_point_y, double &out_point_z, double &out_dir_x, double &out_dir_y, double &out_dir_z, double &out_scale, double &out_rms_error) noexcept;
1343+
1344+
bool mmscenegraph$cxxbridge1$shim_detect_curve_pops(::rust::Slice<const double> x_values, ::rust::Slice<const double> y_values, double threshold, ::rust::Vec<double> &out_x_values, ::rust::Vec<double> &out_y_values) noexcept;
1345+
1346+
bool mmscenegraph$cxxbridge1$shim_filter_curve_pops(::rust::Slice<const double> x_values, ::rust::Slice<const double> y_values, double threshold, ::rust::Vec<double> &out_x_values, ::rust::Vec<double> &out_y_values) noexcept;
13431347
} // extern "C"
13441348
} // namespace mmscenegraph
13451349

@@ -1774,6 +1778,14 @@ MMSCENEGRAPH_API_EXPORT bool shim_line_point_intersection(::mmscenegraph::Point3
17741778
MMSCENEGRAPH_API_EXPORT bool shim_fit_plane_to_points(::rust::Slice<const double> points_xyz, double &out_point_x, double &out_point_y, double &out_point_z, double &out_dir_x, double &out_dir_y, double &out_dir_z, double &out_scale, double &out_rms_error) noexcept {
17751779
return mmscenegraph$cxxbridge1$shim_fit_plane_to_points(points_xyz, out_point_x, out_point_y, out_point_z, out_dir_x, out_dir_y, out_dir_z, out_scale, out_rms_error);
17761780
}
1781+
1782+
MMSCENEGRAPH_API_EXPORT bool shim_detect_curve_pops(::rust::Slice<const double> x_values, ::rust::Slice<const double> y_values, double threshold, ::rust::Vec<double> &out_x_values, ::rust::Vec<double> &out_y_values) noexcept {
1783+
return mmscenegraph$cxxbridge1$shim_detect_curve_pops(x_values, y_values, threshold, out_x_values, out_y_values);
1784+
}
1785+
1786+
MMSCENEGRAPH_API_EXPORT bool shim_filter_curve_pops(::rust::Slice<const double> x_values, ::rust::Slice<const double> y_values, double threshold, ::rust::Vec<double> &out_x_values, ::rust::Vec<double> &out_y_values) noexcept {
1787+
return mmscenegraph$cxxbridge1$shim_filter_curve_pops(x_values, y_values, threshold, out_x_values, out_y_values);
1788+
}
17771789
} // namespace mmscenegraph
17781790

17791791
extern "C" {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (C) 2024 David Cattermole.
3+
*
4+
* This file is part of mmSolver.
5+
*
6+
* mmSolver is free software: you can redistribute it and/or modify it
7+
* under the terms of the GNU Lesser General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* mmSolver is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with mmSolver. If not, see <https://www.gnu.org/licenses/>.
18+
* ====================================================================
19+
*
20+
*/
21+
22+
#include <mmscenegraph/_cxx.h>
23+
#include <mmscenegraph/_cxxbridge.h>
24+
#include <mmscenegraph/curve_detect_pops.h>
25+
26+
namespace mmscenegraph {
27+
28+
MMSCENEGRAPH_API_EXPORT
29+
bool detect_curve_pops(rust::Slice<const Real> &x_values,
30+
rust::Slice<const Real> &y_values, const Real threshold,
31+
rust::Vec<Real> &out_x_values,
32+
rust::Vec<Real> &out_y_values) noexcept {
33+
return shim_detect_curve_pops(x_values, y_values, threshold, out_x_values,
34+
out_y_values);
35+
}
36+
37+
MMSCENEGRAPH_API_EXPORT
38+
bool filter_curve_pops(rust::Slice<const Real> &x_values,
39+
rust::Slice<const Real> &y_values, const Real threshold,
40+
rust::Vec<Real> &out_x_values,
41+
rust::Vec<Real> &out_y_values) noexcept {
42+
return shim_filter_curve_pops(x_values, y_values, threshold, out_x_values,
43+
out_y_values);
44+
}
45+
46+
} // namespace mmscenegraph
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//
2+
// Copyright (C) 2024 David Cattermole.
3+
//
4+
// This file is part of mmSolver.
5+
//
6+
// mmSolver is free software: you can redistribute it and/or modify it
7+
// under the terms of the GNU Lesser General Public License as
8+
// published by the Free Software Foundation, either version 3 of the
9+
// License, or (at your option) any later version.
10+
//
11+
// mmSolver is distributed in the hope that it will be useful,
12+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
// GNU Lesser General Public License for more details.
15+
//
16+
// You should have received a copy of the GNU Lesser General Public License
17+
// along with mmSolver. If not, see <https://www.gnu.org/licenses/>.
18+
// ====================================================================
19+
//
20+
21+
use mmscenegraph_rust::constant::Real as CoreReal;
22+
use mmscenegraph_rust::curve::detect::pops::detect_curve_pops as core_detect_curve_pops;
23+
use mmscenegraph_rust::curve::detect::pops::filter_curve_pops as core_filter_curve_pops;
24+
25+
pub fn shim_detect_curve_pops(
26+
// xy_values: &[(CoreReal, CoreReal)],
27+
x_values: &[CoreReal],
28+
y_values: &[CoreReal],
29+
threshold: CoreReal,
30+
out_x_values: &mut Vec<CoreReal>,
31+
out_y_values: &mut Vec<CoreReal>,
32+
) -> bool {
33+
let result = core_detect_curve_pops(&x_values, &y_values, threshold);
34+
match result {
35+
Ok(values) => {
36+
let new_x_capacity =
37+
values.len().saturating_sub(out_x_values.capacity());
38+
let new_y_capacity =
39+
values.len().saturating_sub(out_y_values.capacity());
40+
out_x_values.reserve_exact(new_x_capacity);
41+
out_y_values.reserve_exact(new_y_capacity);
42+
out_x_values.clear();
43+
out_y_values.clear();
44+
45+
for value in values.iter() {
46+
let x = value.0;
47+
let y = value.1;
48+
out_x_values.push(x);
49+
out_y_values.push(y);
50+
}
51+
52+
true
53+
}
54+
Err(_) => false,
55+
}
56+
}
57+
58+
pub fn shim_filter_curve_pops(
59+
// xy_values: &[(CoreReal, CoreReal)],
60+
x_values: &[CoreReal],
61+
y_values: &[CoreReal],
62+
threshold: CoreReal,
63+
out_x_values: &mut Vec<CoreReal>,
64+
out_y_values: &mut Vec<CoreReal>,
65+
) -> bool {
66+
let result = core_filter_curve_pops(&x_values, &y_values, threshold);
67+
match result {
68+
Ok(values) => {
69+
let new_x_capacity =
70+
values.len().saturating_sub(out_x_values.capacity());
71+
let new_y_capacity =
72+
values.len().saturating_sub(out_y_values.capacity());
73+
out_x_values.reserve_exact(new_x_capacity);
74+
out_y_values.reserve_exact(new_y_capacity);
75+
out_x_values.clear();
76+
out_y_values.clear();
77+
78+
for value in values.iter() {
79+
let x = value.0;
80+
let y = value.1;
81+
out_x_values.push(x);
82+
out_y_values.push(y);
83+
}
84+
85+
true
86+
}
87+
Err(_) => false,
88+
}
89+
}

lib/cppbind/mmscenegraph/src/cxxbridge.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
use crate::attrdatablock::shim_create_attr_data_block_box;
2222
use crate::attrdatablock::ShimAttrDataBlock;
23+
use crate::curve_detect_pops::shim_detect_curve_pops;
24+
use crate::curve_detect_pops::shim_filter_curve_pops;
2325
use crate::evaluationobjects::shim_create_evaluation_objects_box;
2426
use crate::evaluationobjects::ShimEvaluationObjects;
2527
use crate::fit_plane::shim_fit_plane_to_points;
@@ -431,4 +433,23 @@ pub mod ffi {
431433
out_rms_error: &mut f64,
432434
) -> bool;
433435
}
436+
437+
// Fit Plane
438+
extern "Rust" {
439+
fn shim_detect_curve_pops(
440+
x_values: &[f64],
441+
y_values: &[f64],
442+
threshold: f64,
443+
out_x_values: &mut Vec<f64>,
444+
out_y_values: &mut Vec<f64>,
445+
) -> bool;
446+
447+
fn shim_filter_curve_pops(
448+
x_values: &[f64],
449+
y_values: &[f64],
450+
threshold: f64,
451+
out_x_values: &mut Vec<f64>,
452+
out_y_values: &mut Vec<f64>,
453+
) -> bool;
454+
}
434455
}

lib/cppbind/mmscenegraph/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
pub mod attr;
2222
pub mod attrdatablock;
23+
pub mod curve_detect_pops;
2324
pub mod cxxbridge;
2425
pub mod evaluationobjects;
2526
pub mod fit_plane;

lib/mmsolverlibs/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ set(lib_source_files
6262

6363
${mmscenegraph_source_dir}/_cxxbridge.cpp
6464
${mmscenegraph_source_dir}/attrdatablock.cpp
65+
${mmscenegraph_source_dir}/curve_detect_pops.cpp
6566
${mmscenegraph_source_dir}/evaluationobjects.cpp
6667
${mmscenegraph_source_dir}/fit_plane.cpp
6768
${mmscenegraph_source_dir}/flatscene.cpp

lib/rust/mmscenegraph/src/curve/detect/pops.rs

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
use anyhow::bail;
2222
use anyhow::Result;
2323
use log::debug;
24-
use std::fmt;
2524

2625
use crate::constant::Real;
2726
use crate::curve::derivatives::allocate_derivatives_order_2;
@@ -32,24 +31,6 @@ use crate::math::statistics::calc_z_score;
3231
use crate::math::statistics::SortedDataSlice;
3332
use crate::math::statistics::SortedDataSliceOps;
3433

35-
/// Represents a point that was classified as a pop
36-
#[derive(Debug)]
37-
pub struct PopPoint {
38-
pub time: Real,
39-
pub value: Real,
40-
pub score: Real,
41-
}
42-
43-
impl fmt::Display for PopPoint {
44-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45-
write!(
46-
f,
47-
"PopPoint [ t={:.2}, v={:.2} (score={:.2}) ]",
48-
self.time, self.value, self.score
49-
)
50-
}
51-
}
52-
5334
fn calculate_per_frame_pop_score(
5435
times: &[Real],
5536
values: &[Real],
@@ -109,7 +90,7 @@ pub fn detect_curve_pops(
10990
times: &[Real],
11091
values: &[Real],
11192
threshold: Real,
112-
) -> Result<Vec<PopPoint>> {
93+
) -> Result<Vec<(Real, Real)>> {
11394
if times.len() != values.len() {
11495
bail!("Times and values must have the same length.");
11596
}
@@ -147,13 +128,7 @@ pub fn detect_curve_pops(
147128
if pop_prev || pop_current || pop_next {
148129
let t = times[i];
149130
let v = values[i];
150-
151-
let point = PopPoint {
152-
time: t,
153-
value: v,
154-
score: score_current,
155-
};
156-
out_values.push(point);
131+
out_values.push((t, v));
157132
}
158133
}
159134
} else {
@@ -162,13 +137,7 @@ pub fn detect_curve_pops(
162137
if score > threshold {
163138
let t = times[i];
164139
let v = values[i];
165-
166-
let point = PopPoint {
167-
time: t,
168-
value: v,
169-
score: score,
170-
};
171-
out_values.push(point);
140+
out_values.push((t, v));
172141
}
173142
}
174143
}

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ set(SOURCE_FILES
3838
mmSolver/adjust/adjust_solveFunc.cpp
3939
mmSolver/calibrate/calibrate_common.cpp
4040
mmSolver/calibrate/vanishing_point.cpp
41+
mmSolver/cmd/MMAnimCurveFilterPopsCmd.cpp
4142
mmSolver/cmd/MMBestFitPlaneCmd.cpp
4243
mmSolver/cmd/MMCameraPoseFromPointsCmd.cpp
4344
mmSolver/cmd/MMCameraRelativePoseCmd.cpp

0 commit comments

Comments
 (0)