#[path = "attach.rs"]
pub mod attach;
use std::sync::Arc;
use ferrocad_core::object_registry::{self, ObjectType};
use ferrocad_core::{prop_status, Document, ObjectId, Property, Placement};
use ferrocad_part::{make_shape_property, ShapeProperty};
pub const FEATURE_PYTHON_TYPE: &str = "Part::FeaturePython";
pub const PART2D_PYTHON_TYPE: &str = "Part::Part2DObjectPython";
fn feature_properties() -> Vec<(String, Property, u32)> {
vec![
(
"Shape".to_string(),
make_shape_property(ShapeProperty::empty()),
prop_status::NONE,
),
(
"Placement".to_string(),
Property::Placement(Placement::identity()),
prop_status::NONE,
),
]
}
struct FeaturePython {
attached: bool,
}
impl ObjectType for FeaturePython {
fn default_properties(&self) -> Vec<(String, Property, u32)> {
let mut properties = feature_properties();
if self.attached {
properties.extend(attach::attachment_properties(attach::ATTACHER_PLANE));
}
properties
}
fn property_meta(&self, name: &str) -> Option<(String, String)> {
if matches!(
name,
"AttachmentSupport"
| "MapMode"
| "MapPathParameter"
| "AttachmentOffset"
| "AttacherType"
) {
return Some(("Attachment".to_string(), format!("Attachment {name}")));
}
Some(("Base".to_string(), format!("Part feature {name}")))
}
fn execute(&self, doc: &mut Document, id: ObjectId) {
if self.attached {
doc.add_extension(id, attach::BASE_EXTENSION);
}
if attach::has_attachment(doc, id) {
if let Err(reason) = attach::position_by_support(doc, id) {
doc.mark_invalid_with(id, reason);
return;
}
}
if !object_registry::python_executor_available() {
doc.mark_invalid_with(
id,
"no Python interpreter is available to run the feature's proxy",
);
return;
}
doc.mark_python_pending(id);
}
fn is_python_feature(&self) -> bool {
true
}
}
pub fn register() {
object_registry::register(
FEATURE_PYTHON_TYPE,
Arc::new(FeaturePython { attached: false }),
);
object_registry::register(
PART2D_PYTHON_TYPE,
Arc::new(FeaturePython { attached: true }),
);
attach::register();
}