use crate::feature_pipeline::features::common;
use crate::feature_pipeline::{FeatureContext, FeatureResult};
pub fn execute(ctx: &FeatureContext) -> FeatureResult {
let mut result = FeatureResult::empty(ctx.id.clone(), ctx.feature_type.clone());
let names = common::unique_reference_names(ctx.param("faces"));
if names.is_empty() {
return result;
}
match ctx.number("distance") {
Ok(distance) if distance.is_finite() => {}
_ => return result,
}
for name in &names {
if ctx.scene.resolve_face(name).is_none() {
result.unresolved.push(name.clone());
}
}
result
}
pub fn context_applicable(probe: &crate::feature_pipeline::SelectionProbe) -> bool {
probe.faces > 0
}
pub fn schema() -> serde_json::Value {
serde_json::json!({
"type": "O.F",
"shortName": "O.F",
"longName": "Offset Face",
"displayBuilder": true,
"inputParamsSchema": {
"id": {
"type": "string",
"default_value": null,
"hint": "Optional identifier used for naming the offset faces"
},
"faces": {
"type": "reference_selection",
"selectionFilter": [
"FACE"
],
"timestampDependency": "parentSolid",
"multiple": true,
"default_value": [],
"hint": "Select one or more faces to offset"
},
"distance": {
"type": "number",
"default_value": 1,
"hint": "Offset distance along the face normal (positive or negative)"
}
}
})
}