mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-11-26 13:32:32 +00:00
Compare commits
6 Commits
185c25f7b2
...
cf87ace91f
Author | SHA1 | Date | |
---|---|---|---|
|
cf87ace91f | ||
|
e7118f2565 | ||
|
f224148e1d | ||
|
ff68109f0f | ||
|
98a654095b | ||
|
ca02c1df8c |
36
RELEASE_NOTES.md
Normal file
36
RELEASE_NOTES.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
This new release has a lot of breaking changes in the Blender tooling as well as in the Bevy crates
|
||||||
|
Here is a rundown + rationale behing the changes:
|
||||||
|
|
||||||
|
|
||||||
|
- Blender add-ons
|
||||||
|
- Auto_export:
|
||||||
|
- spliting out of gltf exporter settings
|
||||||
|
up until now , the auto export add-on provided a *subset* of gltf settings, causing issues due to lack of features (in particular for animation settings),
|
||||||
|
and it required me to play catch up every time there where added / changed settings
|
||||||
|
the Ui of Blender's gltf exporter is NOT reusable in any form or way inside another add-on . I tried various solutions such as turning the auto exporter
|
||||||
|
into a 'extension' of the standard exporter, but none of them worked in a reliable or 'nice to use' way
|
||||||
|
|
||||||
|
So I decided to split the gltf settings from the auto_export setting, this has multiple advantages:
|
||||||
|
* access to ALL gltf settings
|
||||||
|
* the gltf UI & settings will always keep up with the official releases
|
||||||
|
* less maintenance work
|
||||||
|
|
||||||
|
The only disadvantage is that the standard gltf exporter is a normal exporter, so it generates a 'fake' gltf file that immediatly gets deleted after export,
|
||||||
|
so you will need to use the new side panel to set your gltf settings:
|
||||||
|
* this is also done to ensure that the gltf settings settings used for auto export are NOT interfering with the ones you might use when exporting gltf files normally
|
||||||
|
|
||||||
|
- change detection :
|
||||||
|
after spending MANY hours analysing the issues with change detection (using some of Blender's built in logic) I came to the conclusion that it was not going to be reliable enough, so I opted for a 'hand made' brute force approach to change detection:
|
||||||
|
* every time you save (& thus export), all your scenes are serialized / hashed and that hashed version is compared to the one from the last save to determine what changed and what did not
|
||||||
|
|
||||||
|
- handling of external/ embeded / split etc collections
|
||||||
|
while adding tests I also realised that the detection of which main scenes & blueprints that needed to be exported was faulty, so I rewrote all the code in charge of that : this means that in general , based on your settings, the add-on will more accuratly export only those levels/blueprints that really NEED to be exported
|
||||||
|
|
||||||
|
- improved handling of multi-blend file projects
|
||||||
|
Up until now, all export paths where relative ** to the blend file itself** which could lead to issues when working with multiple blend files
|
||||||
|
Also for future improvements regarding assets managment, I changed the export paths to be relative to a new "project root" folder which is your *Bevy project's root folder*
|
||||||
|
- the levels/worlds now also got a seperate setting so you can easilly set where to export them too (they are not dumped out into the main export folder anymore), giving you more control over your non blueprint exports
|
||||||
|
|
||||||
|
- bevy_components
|
||||||
|
Up until now , it was not possible to have multiple components with the same name (ie ) as all the logic was based on short names
|
||||||
|
This required completely changing HOW/WHERE components are stored in objects, and they are now stored inside a 'bevy_components' custom property
|
@ -31,8 +31,7 @@ pub fn add_components_from_gltf_extras(world: &mut World) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let type_registry: &AppTypeRegistry = world.resource();
|
let type_registry: &AppTypeRegistry = world.resource();
|
||||||
let type_registry = type_registry.read();
|
let type_registry = type_registry.read();
|
||||||
|
|
||||||
let reflect_components = ronstring_to_reflect_component(&extra.value, &type_registry);
|
let reflect_components = ronstring_to_reflect_component(&extra.value, &type_registry);
|
||||||
|
|
||||||
// we assign the components specified /xxx_components objects to their parent node
|
// we assign the components specified /xxx_components objects to their parent node
|
||||||
|
@ -13,10 +13,84 @@ pub fn ronstring_to_reflect_component(
|
|||||||
) -> Vec<(Box<dyn Reflect>, TypeRegistration)> {
|
) -> Vec<(Box<dyn Reflect>, TypeRegistration)> {
|
||||||
let lookup: HashMap<String, Value> = ron::from_str(ron_string).unwrap();
|
let lookup: HashMap<String, Value> = ron::from_str(ron_string).unwrap();
|
||||||
let mut components: Vec<(Box<dyn Reflect>, TypeRegistration)> = Vec::new();
|
let mut components: Vec<(Box<dyn Reflect>, TypeRegistration)> = Vec::new();
|
||||||
for (key, value) in lookup.into_iter() {
|
// println!("ron_string {:?}", ron_string);
|
||||||
let type_string = key.replace("component: ", "").trim().to_string();
|
for (name, value) in lookup.into_iter() {
|
||||||
let capitalized_type_name = capitalize_first_letter(type_string.as_str());
|
|
||||||
|
|
||||||
|
let parsed_value: String;
|
||||||
|
match value.clone() {
|
||||||
|
Value::String(str) => {
|
||||||
|
parsed_value = str;
|
||||||
|
}
|
||||||
|
_ => parsed_value = ron::to_string(&value).unwrap().to_string(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if name.as_str() == "bevy_components" {
|
||||||
|
bevy_components_string_to_components(parsed_value, type_registry, &mut components)
|
||||||
|
} else {
|
||||||
|
components_string_to_components(name, value, parsed_value, type_registry, &mut components)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
components
|
||||||
|
}
|
||||||
|
|
||||||
|
fn components_string_to_components(
|
||||||
|
name: String,
|
||||||
|
value: Value,
|
||||||
|
parsed_value: String,
|
||||||
|
type_registry: &TypeRegistry,
|
||||||
|
components: &mut Vec<(Box<dyn Reflect>, TypeRegistration)>
|
||||||
|
){
|
||||||
|
let type_string = name.replace("component: ", "").trim().to_string();
|
||||||
|
let capitalized_type_name = capitalize_first_letter(type_string.as_str());
|
||||||
|
|
||||||
|
if let Some(type_registration) =
|
||||||
|
type_registry.get_with_short_type_path(capitalized_type_name.as_str())
|
||||||
|
{
|
||||||
|
debug!("TYPE INFO {:?}", type_registration.type_info());
|
||||||
|
|
||||||
|
let ron_string = format!(
|
||||||
|
"{{ \"{}\":{} }}",
|
||||||
|
type_registration.type_info().type_path(),
|
||||||
|
parsed_value
|
||||||
|
);
|
||||||
|
|
||||||
|
// usefull to determine what an entity looks like Serialized
|
||||||
|
/*let test_struct = CameraRenderGraph::new("name");
|
||||||
|
let serializer = ReflectSerializer::new(&test_struct, &type_registry);
|
||||||
|
let serialized =
|
||||||
|
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
|
||||||
|
println!("serialized Component {}", serialized);*/
|
||||||
|
|
||||||
|
debug!("component data ron string {}", ron_string);
|
||||||
|
let mut deserializer = ron::Deserializer::from_str(ron_string.as_str())
|
||||||
|
.expect("deserialzer should have been generated from string");
|
||||||
|
let reflect_deserializer = UntypedReflectDeserializer::new(type_registry);
|
||||||
|
let component = reflect_deserializer
|
||||||
|
.deserialize(&mut deserializer)
|
||||||
|
.unwrap_or_else(|_| {
|
||||||
|
panic!(
|
||||||
|
"failed to deserialize component {} with value: {:?}",
|
||||||
|
name, value
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
debug!("component {:?}", component);
|
||||||
|
debug!("real type {:?}", component.get_represented_type_info());
|
||||||
|
components.push((component, type_registration.clone()));
|
||||||
|
debug!("found type registration for {}", capitalized_type_name);
|
||||||
|
} else {
|
||||||
|
warn!("no type registration for {}", capitalized_type_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bevy_components_string_to_components(
|
||||||
|
parsed_value: String,
|
||||||
|
type_registry: &TypeRegistry,
|
||||||
|
components: &mut Vec<(Box<dyn Reflect>, TypeRegistration)>
|
||||||
|
){
|
||||||
|
let lookup: HashMap<String, Value> = ron::from_str(&parsed_value).unwrap();
|
||||||
|
for (key, value) in lookup.into_iter() {
|
||||||
let parsed_value: String;
|
let parsed_value: String;
|
||||||
match value.clone() {
|
match value.clone() {
|
||||||
Value::String(str) => {
|
Value::String(str) => {
|
||||||
@ -26,7 +100,7 @@ pub fn ronstring_to_reflect_component(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(type_registration) =
|
if let Some(type_registration) =
|
||||||
type_registry.get_with_short_type_path(capitalized_type_name.as_str())
|
type_registry.get_with_type_path(key.as_str())
|
||||||
{
|
{
|
||||||
debug!("TYPE INFO {:?}", type_registration.type_info());
|
debug!("TYPE INFO {:?}", type_registration.type_info());
|
||||||
|
|
||||||
@ -36,13 +110,6 @@ pub fn ronstring_to_reflect_component(
|
|||||||
parsed_value
|
parsed_value
|
||||||
);
|
);
|
||||||
|
|
||||||
// usefull to determine what an entity looks like Serialized
|
|
||||||
/*let test_struct = CameraRenderGraph::new("name");
|
|
||||||
let serializer = ReflectSerializer::new(&test_struct, &type_registry);
|
|
||||||
let serialized =
|
|
||||||
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
|
|
||||||
println!("serialized Component {}", serialized);*/
|
|
||||||
|
|
||||||
debug!("component data ron string {}", ron_string);
|
debug!("component data ron string {}", ron_string);
|
||||||
let mut deserializer = ron::Deserializer::from_str(ron_string.as_str())
|
let mut deserializer = ron::Deserializer::from_str(ron_string.as_str())
|
||||||
.expect("deserialzer should have been generated from string");
|
.expect("deserialzer should have been generated from string");
|
||||||
@ -59,10 +126,9 @@ pub fn ronstring_to_reflect_component(
|
|||||||
debug!("component {:?}", component);
|
debug!("component {:?}", component);
|
||||||
debug!("real type {:?}", component.get_represented_type_info());
|
debug!("real type {:?}", component.get_represented_type_info());
|
||||||
components.push((component, type_registration.clone()));
|
components.push((component, type_registration.clone()));
|
||||||
debug!("found type registration for {}", capitalized_type_name);
|
debug!("found type registration for {}", key);
|
||||||
} else {
|
} else {
|
||||||
warn!("no type registration for {}", capitalized_type_name);
|
warn!("no type registration for {}", key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
components
|
}
|
||||||
}
|
|
@ -3168,6 +3168,117 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"typeInfo": "Enum"
|
"typeInfo": "Enum"
|
||||||
},
|
},
|
||||||
|
"bevy_example::test_components::HashmapTestIntColor": {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"isComponent": true,
|
||||||
|
"isResource": false,
|
||||||
|
"properties": {
|
||||||
|
"inner": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/bevy_utils::hashbrown::HashMap<u32, bevy_render::color::Color, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"inner"
|
||||||
|
],
|
||||||
|
"short_name": "HashmapTestIntColor",
|
||||||
|
"title": "bevy_example::test_components::HashmapTestIntColor",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Struct"
|
||||||
|
},
|
||||||
|
"bevy_example::test_components::HashmapTestIntString": {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"isComponent": true,
|
||||||
|
"isResource": false,
|
||||||
|
"properties": {
|
||||||
|
"named_animations": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/bevy_utils::hashbrown::HashMap<u32, alloc::string::String, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"named_animations"
|
||||||
|
],
|
||||||
|
"short_name": "HashmapTestIntString",
|
||||||
|
"title": "bevy_example::test_components::HashmapTestIntString",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Struct"
|
||||||
|
},
|
||||||
|
"bevy_example::test_components::HashmapTestSimple": {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"isComponent": true,
|
||||||
|
"isResource": false,
|
||||||
|
"properties": {
|
||||||
|
"named_animations": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/bevy_utils::hashbrown::HashMap<alloc::string::String, alloc::string::String, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"named_animations"
|
||||||
|
],
|
||||||
|
"short_name": "HashmapTestSimple",
|
||||||
|
"title": "bevy_example::test_components::HashmapTestSimple",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Struct"
|
||||||
|
},
|
||||||
|
"bevy_example::test_components::HashmapTestStringColor": {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"isComponent": true,
|
||||||
|
"isResource": false,
|
||||||
|
"properties": {
|
||||||
|
"inner": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/bevy_utils::hashbrown::HashMap<alloc::string::String, bevy_render::color::Color, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"inner"
|
||||||
|
],
|
||||||
|
"short_name": "HashmapTestStringColor",
|
||||||
|
"title": "bevy_example::test_components::HashmapTestStringColor",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Struct"
|
||||||
|
},
|
||||||
|
"bevy_example::test_components::HashmapTestStringColorFlat": {
|
||||||
|
"isComponent": true,
|
||||||
|
"isResource": false,
|
||||||
|
"items": false,
|
||||||
|
"prefixItems": [
|
||||||
|
{
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/bevy_utils::hashbrown::HashMap<alloc::string::String, bevy_render::color::Color, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"short_name": "HashmapTestStringColorFlat",
|
||||||
|
"title": "bevy_example::test_components::HashmapTestStringColorFlat",
|
||||||
|
"type": "array",
|
||||||
|
"typeInfo": "TupleStruct"
|
||||||
|
},
|
||||||
|
"bevy_example::test_components::HashmapTestStringFloat": {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"isComponent": true,
|
||||||
|
"isResource": false,
|
||||||
|
"properties": {
|
||||||
|
"named_animations": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/bevy_utils::hashbrown::HashMap<alloc::string::String, f32, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"named_animations"
|
||||||
|
],
|
||||||
|
"short_name": "HashmapTestStringFloat",
|
||||||
|
"title": "bevy_example::test_components::HashmapTestStringFloat",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Struct"
|
||||||
|
},
|
||||||
"bevy_example::test_components::NestedTupleStuff": {
|
"bevy_example::test_components::NestedTupleStuff": {
|
||||||
"isComponent": true,
|
"isComponent": true,
|
||||||
"isResource": false,
|
"isResource": false,
|
||||||
@ -11026,6 +11137,19 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"typeInfo": "Value"
|
"typeInfo": "Value"
|
||||||
},
|
},
|
||||||
|
"bevy_utils::hashbrown::HashMap<alloc::string::String, alloc::string::String, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/alloc::string::String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isComponent": false,
|
||||||
|
"isResource": false,
|
||||||
|
"short_name": "HashMap<String, String, DefaultHashBuilder>",
|
||||||
|
"title": "bevy_utils::hashbrown::HashMap<alloc::string::String, alloc::string::String, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Map"
|
||||||
|
},
|
||||||
"bevy_utils::hashbrown::HashMap<alloc::string::String, alloc::vec::Vec<alloc::string::String>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
"bevy_utils::hashbrown::HashMap<alloc::string::String, alloc::vec::Vec<alloc::string::String>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
||||||
"additionalProperties": {
|
"additionalProperties": {
|
||||||
"type": {
|
"type": {
|
||||||
@ -11039,6 +11163,19 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"typeInfo": "Map"
|
"typeInfo": "Map"
|
||||||
},
|
},
|
||||||
|
"bevy_utils::hashbrown::HashMap<alloc::string::String, bevy_render::color::Color, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/bevy_render::color::Color"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isComponent": false,
|
||||||
|
"isResource": false,
|
||||||
|
"short_name": "HashMap<String, Color, DefaultHashBuilder>",
|
||||||
|
"title": "bevy_utils::hashbrown::HashMap<alloc::string::String, bevy_render::color::Color, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Map"
|
||||||
|
},
|
||||||
"bevy_utils::hashbrown::HashMap<alloc::string::String, bevy_utils::hashbrown::HashMap<u32, alloc::vec::Vec<alloc::string::String>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
"bevy_utils::hashbrown::HashMap<alloc::string::String, bevy_utils::hashbrown::HashMap<u32, alloc::vec::Vec<alloc::string::String>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
||||||
"additionalProperties": {
|
"additionalProperties": {
|
||||||
"type": {
|
"type": {
|
||||||
@ -11052,6 +11189,32 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"typeInfo": "Map"
|
"typeInfo": "Map"
|
||||||
},
|
},
|
||||||
|
"bevy_utils::hashbrown::HashMap<alloc::string::String, f32, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/f32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isComponent": false,
|
||||||
|
"isResource": false,
|
||||||
|
"short_name": "HashMap<String, f32, DefaultHashBuilder>",
|
||||||
|
"title": "bevy_utils::hashbrown::HashMap<alloc::string::String, f32, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Map"
|
||||||
|
},
|
||||||
|
"bevy_utils::hashbrown::HashMap<u32, alloc::string::String, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/alloc::string::String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isComponent": false,
|
||||||
|
"isResource": false,
|
||||||
|
"short_name": "HashMap<u32, String, DefaultHashBuilder>",
|
||||||
|
"title": "bevy_utils::hashbrown::HashMap<u32, alloc::string::String, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Map"
|
||||||
|
},
|
||||||
"bevy_utils::hashbrown::HashMap<u32, alloc::vec::Vec<alloc::string::String>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
"bevy_utils::hashbrown::HashMap<u32, alloc::vec::Vec<alloc::string::String>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
||||||
"additionalProperties": {
|
"additionalProperties": {
|
||||||
"type": {
|
"type": {
|
||||||
@ -11065,6 +11228,19 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"typeInfo": "Map"
|
"typeInfo": "Map"
|
||||||
},
|
},
|
||||||
|
"bevy_utils::hashbrown::HashMap<u32, bevy_render::color::Color, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/bevy_render::color::Color"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isComponent": false,
|
||||||
|
"isResource": false,
|
||||||
|
"short_name": "HashMap<u32, Color, DefaultHashBuilder>",
|
||||||
|
"title": "bevy_utils::hashbrown::HashMap<u32, bevy_render::color::Color, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Map"
|
||||||
|
},
|
||||||
"bevy_utils::smallvec::SmallVec<[bevy_ecs::entity::Entity; 8]>": {
|
"bevy_utils::smallvec::SmallVec<[bevy_ecs::entity::Entity; 8]>": {
|
||||||
"isComponent": false,
|
"isComponent": false,
|
||||||
"isResource": false,
|
"isResource": false,
|
||||||
|
@ -145,11 +145,11 @@ impl Plugin for GamePlugin {
|
|||||||
.add_systems(Update, play_animations)
|
.add_systems(Update, play_animations)
|
||||||
.add_systems(Update, react_to_animation_markers)
|
.add_systems(Update, react_to_animation_markers)
|
||||||
|
|
||||||
.add_systems(Update, generate_screenshot.run_if(on_timer(Duration::from_secs_f32(0.2)))) // TODO: run once
|
/*.add_systems(Update, generate_screenshot.run_if(on_timer(Duration::from_secs_f32(0.2)))) // TODO: run once
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
exit_game.run_if(on_timer(Duration::from_secs_f32(0.5))),
|
exit_game.run_if(on_timer(Duration::from_secs_f32(0.5))),
|
||||||
) // shut down the app after this time
|
) // shut down the app after this time*/
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,6 +152,43 @@ impl MaterialExtension for MyExtension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
use bevy::utils::HashMap;
|
||||||
|
|
||||||
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct HashmapTestSimple {
|
||||||
|
pub named_animations: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct HashmapTestStringFloat {
|
||||||
|
pub named_animations: HashMap<String, f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct HashmapTestIntString {
|
||||||
|
pub named_animations: HashMap<u32, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct HashmapTestIntColor {
|
||||||
|
pub inner: HashMap<u32, Color>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct HashmapTestStringColor {
|
||||||
|
pub inner: HashMap<String, Color>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct HashmapTestStringColorFlat(HashMap<String, Color>);
|
||||||
|
|
||||||
pub struct ComponentsTestPlugin;
|
pub struct ComponentsTestPlugin;
|
||||||
impl Plugin for ComponentsTestPlugin {
|
impl Plugin for ComponentsTestPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
@ -185,6 +222,20 @@ impl Plugin for ComponentsTestPlugin {
|
|||||||
.register_type::<Vec<f32>>()
|
.register_type::<Vec<f32>>()
|
||||||
// .register_type::<AAAAddedCOMPONENT>()
|
// .register_type::<AAAAddedCOMPONENT>()
|
||||||
.register_type::<AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut>()
|
.register_type::<AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut>()
|
||||||
|
.register_type::<HashMap<String, String>>()
|
||||||
|
.register_type::<HashmapTestSimple>()
|
||||||
|
.register_type::<HashMap<String, f32>>()
|
||||||
|
.register_type::<HashmapTestStringFloat>()
|
||||||
|
.register_type::<HashMap<u32, String>>()
|
||||||
|
.register_type::<HashmapTestIntString>()
|
||||||
|
|
||||||
|
.register_type::<HashMap<u32, Color>>()
|
||||||
|
.register_type::<HashmapTestIntColor>()
|
||||||
|
|
||||||
|
.register_type::<HashMap<String, Color>>()
|
||||||
|
.register_type::<HashmapTestStringColor>()
|
||||||
|
.register_type::<HashmapTestStringColorFlat>()
|
||||||
|
|
||||||
.add_plugins(MaterialPlugin::<
|
.add_plugins(MaterialPlugin::<
|
||||||
ExtendedMaterial<StandardMaterial, MyExtension>,
|
ExtendedMaterial<StandardMaterial, MyExtension>,
|
||||||
>::default());
|
>::default());
|
||||||
|
@ -206,4 +206,14 @@ UI:
|
|||||||
- [x] delete => remove
|
- [x] delete => remove
|
||||||
|
|
||||||
- [x] clean up reloading of registry settings
|
- [x] clean up reloading of registry settings
|
||||||
- [x] clean up file watcher
|
- [x] clean up file watcher
|
||||||
|
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Restructuring of storage of components
|
||||||
|
- [x] marking of invalid root propgroups/components should be based on long name
|
||||||
|
- [ ] overhaul & check each prop group type's use of short names => long names
|
||||||
|
- [ ] lists
|
||||||
|
|
||||||
|
- [ ] in conversions from propgroups
|
||||||
|
component_name = definition["short_name"]
|
||||||
|
@ -22,9 +22,9 @@ from .registry.registry import ComponentsRegistry,MissingBevyType
|
|||||||
from .registry.operators import (COMPONENTS_OT_REFRESH_CUSTOM_PROPERTIES_ALL, COMPONENTS_OT_REFRESH_CUSTOM_PROPERTIES_CURRENT, COMPONENTS_OT_REFRESH_PROPGROUPS_FROM_CUSTOM_PROPERTIES_ALL, COMPONENTS_OT_REFRESH_PROPGROUPS_FROM_CUSTOM_PROPERTIES_CURRENT, OT_select_component_name_to_replace, OT_select_object, ReloadRegistryOperator, OT_OpenFilebrowser)
|
from .registry.operators import (COMPONENTS_OT_REFRESH_CUSTOM_PROPERTIES_ALL, COMPONENTS_OT_REFRESH_CUSTOM_PROPERTIES_CURRENT, COMPONENTS_OT_REFRESH_PROPGROUPS_FROM_CUSTOM_PROPERTIES_ALL, COMPONENTS_OT_REFRESH_PROPGROUPS_FROM_CUSTOM_PROPERTIES_CURRENT, OT_select_component_name_to_replace, OT_select_object, ReloadRegistryOperator, OT_OpenFilebrowser)
|
||||||
from .registry.ui import (BEVY_COMPONENTS_PT_Configuration, BEVY_COMPONENTS_PT_AdvancedToolsPanel, BEVY_COMPONENTS_PT_MissingTypesPanel, MISSING_TYPES_UL_List)
|
from .registry.ui import (BEVY_COMPONENTS_PT_Configuration, BEVY_COMPONENTS_PT_AdvancedToolsPanel, BEVY_COMPONENTS_PT_MissingTypesPanel, MISSING_TYPES_UL_List)
|
||||||
|
|
||||||
from .components.metadata import (ComponentMetadata, ComponentsMeta, ensure_metadata_for_all_objects)
|
from .components.metadata import (ComponentMetadata, ComponentsMeta)
|
||||||
from .propGroups.prop_groups import (generate_propertyGroups_for_components)
|
|
||||||
from .components.lists import GENERIC_LIST_OT_actions, Generic_LIST_OT_AddItem, Generic_LIST_OT_RemoveItem, Generic_LIST_OT_SelectItem
|
from .components.lists import GENERIC_LIST_OT_actions, Generic_LIST_OT_AddItem, Generic_LIST_OT_RemoveItem, Generic_LIST_OT_SelectItem
|
||||||
|
from .components.maps import GENERIC_MAP_OT_actions
|
||||||
from .components.definitions_list import (ComponentDefinitionsList, ClearComponentDefinitionsList)
|
from .components.definitions_list import (ComponentDefinitionsList, ClearComponentDefinitionsList)
|
||||||
from .components.ui import (BEVY_COMPONENTS_PT_ComponentsPanel)
|
from .components.ui import (BEVY_COMPONENTS_PT_ComponentsPanel)
|
||||||
|
|
||||||
@ -123,7 +123,9 @@ classes = [
|
|||||||
Generic_LIST_OT_SelectItem,
|
Generic_LIST_OT_SelectItem,
|
||||||
Generic_LIST_OT_AddItem,
|
Generic_LIST_OT_AddItem,
|
||||||
Generic_LIST_OT_RemoveItem,
|
Generic_LIST_OT_RemoveItem,
|
||||||
GENERIC_LIST_OT_actions
|
GENERIC_LIST_OT_actions,
|
||||||
|
|
||||||
|
GENERIC_MAP_OT_actions
|
||||||
]
|
]
|
||||||
|
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
|
@ -47,12 +47,12 @@ class ComponentDefinitionsList(bpy.types.PropertyGroup):
|
|||||||
description="list",
|
description="list",
|
||||||
# items argument required to initialize, just filled with empty values
|
# items argument required to initialize, just filled with empty values
|
||||||
items = add_component_to_ui_list,
|
items = add_component_to_ui_list,
|
||||||
)
|
) # type: ignore
|
||||||
filter: StringProperty(
|
filter: StringProperty(
|
||||||
name="component filter",
|
name="component filter",
|
||||||
description="filter for the components list",
|
description="filter for the components list",
|
||||||
options={'TEXTEDIT_UPDATE'}
|
options={'TEXTEDIT_UPDATE'}
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class ClearComponentDefinitionsList(bpy.types.Operator):
|
class ClearComponentDefinitionsList(bpy.types.Operator):
|
||||||
|
@ -10,19 +10,19 @@ class Generic_LIST_OT_AddItem(Operator):
|
|||||||
property_group_path: StringProperty(
|
property_group_path: StringProperty(
|
||||||
name="property group path",
|
name="property group path",
|
||||||
description="",
|
description="",
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
component_name: StringProperty(
|
component_name: StringProperty(
|
||||||
name="component name",
|
name="component name",
|
||||||
description="",
|
description="",
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
print("")
|
print("")
|
||||||
object = context.object
|
object = context.object
|
||||||
# information is stored in component meta
|
# information is stored in component meta
|
||||||
components_in_object = object.components_meta.components
|
components_in_object = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None)
|
component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None)
|
||||||
|
|
||||||
propertyGroup = component_meta
|
propertyGroup = component_meta
|
||||||
for path_item in json.loads(self.property_group_path):
|
for path_item in json.loads(self.property_group_path):
|
||||||
@ -47,19 +47,19 @@ class Generic_LIST_OT_RemoveItem(Operator):
|
|||||||
property_group_path: StringProperty(
|
property_group_path: StringProperty(
|
||||||
name="property group path",
|
name="property group path",
|
||||||
description="",
|
description="",
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
component_name: StringProperty(
|
component_name: StringProperty(
|
||||||
name="component name",
|
name="component name",
|
||||||
description="",
|
description="",
|
||||||
)
|
) # type: ignore
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
print("remove from list", context.object)
|
print("remove from list", context.object)
|
||||||
|
|
||||||
object = context.object
|
object = context.object
|
||||||
# information is stored in component meta
|
# information is stored in component meta
|
||||||
components_in_object = object.components_meta.components
|
components_in_object = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None)
|
component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None)
|
||||||
|
|
||||||
propertyGroup = component_meta
|
propertyGroup = component_meta
|
||||||
for path_item in json.loads(self.property_group_path):
|
for path_item in json.loads(self.property_group_path):
|
||||||
@ -81,14 +81,14 @@ class Generic_LIST_OT_SelectItem(Operator):
|
|||||||
property_group_path: StringProperty(
|
property_group_path: StringProperty(
|
||||||
name="property group path",
|
name="property group path",
|
||||||
description="",
|
description="",
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
component_name: StringProperty(
|
component_name: StringProperty(
|
||||||
name="component name",
|
name="component name",
|
||||||
description="",
|
description="",
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
selection_index: IntProperty()
|
selection_index: IntProperty() # type: ignore
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
print("select in list", context.object)
|
print("select in list", context.object)
|
||||||
@ -96,7 +96,7 @@ class Generic_LIST_OT_SelectItem(Operator):
|
|||||||
object = context.object
|
object = context.object
|
||||||
# information is stored in component meta
|
# information is stored in component meta
|
||||||
components_in_object = object.components_meta.components
|
components_in_object = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None)
|
component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None)
|
||||||
|
|
||||||
propertyGroup = component_meta
|
propertyGroup = component_meta
|
||||||
for path_item in json.loads(self.property_group_path):
|
for path_item in json.loads(self.property_group_path):
|
||||||
@ -121,23 +121,23 @@ class GENERIC_LIST_OT_actions(Operator):
|
|||||||
('UP', "Up", ""),
|
('UP', "Up", ""),
|
||||||
('DOWN', "Down", ""),
|
('DOWN', "Down", ""),
|
||||||
('REMOVE', "Remove", ""),
|
('REMOVE', "Remove", ""),
|
||||||
('ADD', "Add", "")))
|
('ADD', "Add", ""))) # type: ignore
|
||||||
|
|
||||||
property_group_path: StringProperty(
|
property_group_path: StringProperty(
|
||||||
name="property group path",
|
name="property group path",
|
||||||
description="",
|
description="",
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
component_name: StringProperty(
|
component_name: StringProperty(
|
||||||
name="component name",
|
name="component name",
|
||||||
description="",
|
description="",
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
object = context.object
|
object = context.object
|
||||||
# information is stored in component meta
|
# information is stored in component meta
|
||||||
components_in_object = object.components_meta.components
|
components_in_object = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None)
|
component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None)
|
||||||
|
|
||||||
propertyGroup = component_meta
|
propertyGroup = component_meta
|
||||||
for path_item in json.loads(self.property_group_path):
|
for path_item in json.loads(self.property_group_path):
|
||||||
|
71
tools/bevy_components/components/maps.py
Normal file
71
tools/bevy_components/components/maps.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import json
|
||||||
|
from bpy_types import Operator, UIList
|
||||||
|
from bpy.props import (StringProperty, EnumProperty, PointerProperty, FloatVectorProperty, IntProperty)
|
||||||
|
|
||||||
|
class GENERIC_MAP_OT_actions(Operator):
|
||||||
|
"""Move items up and down, add and remove"""
|
||||||
|
bl_idname = "generic_map.map_action"
|
||||||
|
bl_label = "List Actions"
|
||||||
|
bl_description = "Move items up and down, add and remove"
|
||||||
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
|
action: EnumProperty(
|
||||||
|
items=(
|
||||||
|
('UP', "Up", ""),
|
||||||
|
('DOWN', "Down", ""),
|
||||||
|
('REMOVE', "Remove", ""),
|
||||||
|
('ADD', "Add", ""))) # type: ignore
|
||||||
|
|
||||||
|
property_group_path: StringProperty(
|
||||||
|
name="property group path",
|
||||||
|
description="",
|
||||||
|
) # type: ignore
|
||||||
|
|
||||||
|
component_name: StringProperty(
|
||||||
|
name="component name",
|
||||||
|
description="",
|
||||||
|
) # type: ignore
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
object = context.object
|
||||||
|
# information is stored in component meta
|
||||||
|
components_in_object = object.components_meta.components
|
||||||
|
component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None)
|
||||||
|
|
||||||
|
propertyGroup = component_meta
|
||||||
|
for path_item in json.loads(self.property_group_path):
|
||||||
|
propertyGroup = getattr(propertyGroup, path_item)
|
||||||
|
|
||||||
|
target_list = getattr(propertyGroup, "list")
|
||||||
|
index = getattr(propertyGroup, "list_index")
|
||||||
|
|
||||||
|
values_list = getattr(propertyGroup, "values_list")
|
||||||
|
values_index = getattr(propertyGroup, "values_list_index")
|
||||||
|
|
||||||
|
|
||||||
|
if self.action == 'DOWN' and index < len(target_list) - 1:
|
||||||
|
#item_next = scn.rule_list[index + 1].name
|
||||||
|
target_list.move(index, index + 1)
|
||||||
|
propertyGroup.list_index += 1
|
||||||
|
|
||||||
|
elif self.action == 'UP' and index >= 1:
|
||||||
|
#item_prev = scn.rule_list[index - 1].name
|
||||||
|
target_list.move(index, index - 1)
|
||||||
|
propertyGroup.list_index -= 1
|
||||||
|
|
||||||
|
elif self.action == 'REMOVE':
|
||||||
|
target_list.remove(index)
|
||||||
|
propertyGroup.list_index = min(max(0, index - 1), len(target_list) - 1)
|
||||||
|
|
||||||
|
if self.action == 'ADD':
|
||||||
|
key = target_list.add()
|
||||||
|
value = values_list.add()
|
||||||
|
|
||||||
|
propertyGroup.list_index = index + 1 # we use this to force the change detection
|
||||||
|
propertyGroup.values_index = index + 1 # we use this to force the change detection
|
||||||
|
|
||||||
|
|
||||||
|
#info = '"%s" added to list' % (item.name)
|
||||||
|
#self.report({'INFO'}, info)
|
||||||
|
|
||||||
|
return {"FINISHED"}
|
@ -10,51 +10,51 @@ class ComponentMetadata(bpy.types.PropertyGroup):
|
|||||||
name : bpy.props.StringProperty(
|
name : bpy.props.StringProperty(
|
||||||
name = "name",
|
name = "name",
|
||||||
default = ""
|
default = ""
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
long_name : bpy.props.StringProperty(
|
long_name : bpy.props.StringProperty(
|
||||||
name = "long name",
|
name = "long name",
|
||||||
default = ""
|
default = ""
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
type_name : bpy.props.StringProperty(
|
type_name : bpy.props.StringProperty(
|
||||||
name = "Type",
|
name = "Type",
|
||||||
default = ""
|
default = ""
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
values: bpy.props.StringProperty(
|
values: bpy.props.StringProperty(
|
||||||
name = "Value",
|
name = "Value",
|
||||||
default = ""
|
default = ""
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
enabled: BoolProperty(
|
enabled: BoolProperty(
|
||||||
name="enabled",
|
name="enabled",
|
||||||
description="component enabled",
|
description="component enabled",
|
||||||
default=True
|
default=True
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
invalid: BoolProperty(
|
invalid: BoolProperty(
|
||||||
name="invalid",
|
name="invalid",
|
||||||
description="component is invalid, because of missing registration/ other issues",
|
description="component is invalid, because of missing registration/ other issues",
|
||||||
default=False
|
default=False
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
invalid_details: StringProperty(
|
invalid_details: StringProperty(
|
||||||
name="invalid details",
|
name="invalid details",
|
||||||
description="detailed information about why the component is invalid",
|
description="detailed information about why the component is invalid",
|
||||||
default=""
|
default=""
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
visible: BoolProperty( # REALLY dislike doing this for UI control, but ok hack for now
|
visible: BoolProperty( # REALLY dislike doing this for UI control, but ok hack for now
|
||||||
default=True
|
default=True
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
class ComponentsMeta(PropertyGroup):
|
class ComponentsMeta(PropertyGroup):
|
||||||
infos_per_component: StringProperty(
|
infos_per_component: StringProperty(
|
||||||
name="infos per component",
|
name="infos per component",
|
||||||
description="component"
|
description="component"
|
||||||
)
|
) # type: ignore
|
||||||
components: bpy.props.CollectionProperty(type = ComponentMetadata)
|
components: bpy.props.CollectionProperty(type = ComponentMetadata) # type: ignore
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def register(cls):
|
def register(cls):
|
||||||
@ -72,7 +72,9 @@ def get_component_metadata_by_short_name(object, short_name):
|
|||||||
|
|
||||||
# remove no longer valid metadata from object
|
# remove no longer valid metadata from object
|
||||||
def cleanup_invalid_metadata(object):
|
def cleanup_invalid_metadata(object):
|
||||||
bevy_components = json.loads(object['bevy_components']) if 'bevy_components' in object else {}
|
bevy_components = get_bevy_components(object)
|
||||||
|
if len(bevy_components.keys()) == 0: # no components, bail out
|
||||||
|
return
|
||||||
components_metadata = object.components_meta.components
|
components_metadata = object.components_meta.components
|
||||||
to_remove = []
|
to_remove = []
|
||||||
for index, component_meta in enumerate(components_metadata):
|
for index, component_meta in enumerate(components_metadata):
|
||||||
@ -93,6 +95,10 @@ def find_component_definition_from_short_name(short_name):
|
|||||||
return registry.type_infos.get(long_name, None)
|
return registry.type_infos.get(long_name, None)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def find_component_definition_from_long_name(long_name):
|
||||||
|
registry = bpy.context.window_manager.components_registry
|
||||||
|
return registry.type_infos.get(long_name, None)
|
||||||
|
|
||||||
# FIXME: feels a bit heavy duty, should only be done
|
# FIXME: feels a bit heavy duty, should only be done
|
||||||
# if the components panel is active ?
|
# if the components panel is active ?
|
||||||
def ensure_metadata_for_all_objects():
|
def ensure_metadata_for_all_objects():
|
||||||
@ -123,31 +129,45 @@ def do_object_custom_properties_have_missing_metadata(object):
|
|||||||
return missing_metadata
|
return missing_metadata
|
||||||
|
|
||||||
|
|
||||||
# adds metadata to object only if it is missing
|
|
||||||
def add_metadata_to_components_without_metadata(object):
|
|
||||||
registry = bpy.context.window_manager.components_registry
|
|
||||||
|
|
||||||
for component_name in dict(object) :
|
|
||||||
if component_name == "components_meta":
|
|
||||||
continue
|
|
||||||
upsert_component_in_object(object, component_name, registry)
|
|
||||||
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
def inject_component(object, long_name, value):
|
def upsert_bevy_component(object, long_name, value):
|
||||||
if not 'bevy_components' in object:
|
if not 'bevy_components' in object:
|
||||||
object['bevy_components'] = '{}'
|
object['bevy_components'] = '{}'
|
||||||
previous = json.loads(object['bevy_components'])
|
bevy_components = json.loads(object['bevy_components'])
|
||||||
previous[long_name] = value
|
bevy_components[long_name] = value
|
||||||
object['bevy_components'] = json.dumps(previous)
|
object['bevy_components'] = json.dumps(bevy_components)
|
||||||
#object['bevy_components'][long_name] = value # Sigh, this does not work, hits Blender's 63 char length limit
|
#object['bevy_components'][long_name] = value # Sigh, this does not work, hits Blender's 63 char length limit
|
||||||
|
|
||||||
def bla_component(object, long_name):
|
def remove_bevy_component(object, long_name):
|
||||||
if 'bevy_components' in object:
|
if 'bevy_components' in object:
|
||||||
current = json.loads(object['bevy_components'])
|
current = json.loads(object['bevy_components'])
|
||||||
del current[long_name]
|
del current[long_name]
|
||||||
object['bevy_components'] = json.dumps(current)
|
object['bevy_components'] = json.dumps(current)
|
||||||
|
|
||||||
|
def get_bevy_components(object):
|
||||||
|
if 'bevy_components' in object:
|
||||||
|
bevy_components = json.loads(object['bevy_components'])
|
||||||
|
return bevy_components
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def get_bevy_component_value_by_long_name(object, long_name):
|
||||||
|
bevy_components = get_bevy_components(object)
|
||||||
|
if len(bevy_components.keys()) == 0 :
|
||||||
|
return None
|
||||||
|
return bevy_components.get(long_name, None)
|
||||||
|
|
||||||
|
def is_bevy_component_in_object(object, long_name):
|
||||||
|
return get_bevy_component_value_by_long_name(object, long_name) is not None
|
||||||
|
|
||||||
|
# adds metadata to object only if it is missing
|
||||||
|
def add_metadata_to_components_without_metadata(object):
|
||||||
|
registry = bpy.context.window_manager.components_registry
|
||||||
|
|
||||||
|
for component_name in get_bevy_components(object) :
|
||||||
|
if component_name == "components_meta":
|
||||||
|
continue
|
||||||
|
upsert_component_in_object(object, component_name, registry)
|
||||||
|
|
||||||
# adds a component to an object (including metadata) using the provided component definition & optional value
|
# adds a component to an object (including metadata) using the provided component definition & optional value
|
||||||
def add_component_to_object(object, component_definition, value=None):
|
def add_component_to_object(object, component_definition, value=None):
|
||||||
cleanup_invalid_metadata(object)
|
cleanup_invalid_metadata(object)
|
||||||
@ -158,7 +178,6 @@ def add_component_to_object(object, component_definition, value=None):
|
|||||||
if not registry.has_type_infos():
|
if not registry.has_type_infos():
|
||||||
raise Exception('registry type infos have not been loaded yet or are missing !')
|
raise Exception('registry type infos have not been loaded yet or are missing !')
|
||||||
definition = registry.type_infos[long_name]
|
definition = registry.type_infos[long_name]
|
||||||
print("HEAAAY", value)
|
|
||||||
# now we use our pre_generated property groups to set the initial value of our custom property
|
# now we use our pre_generated property groups to set the initial value of our custom property
|
||||||
(_, propertyGroup) = upsert_component_in_object(object, long_name=long_name, registry=registry)
|
(_, propertyGroup) = upsert_component_in_object(object, long_name=long_name, registry=registry)
|
||||||
if value == None:
|
if value == None:
|
||||||
@ -170,7 +189,7 @@ def add_component_to_object(object, component_definition, value=None):
|
|||||||
|
|
||||||
# object[short_name] = value
|
# object[short_name] = value
|
||||||
print("ADDING VAALUEEE", value)
|
print("ADDING VAALUEEE", value)
|
||||||
inject_component(object, long_name, value)
|
upsert_bevy_component(object, long_name, value)
|
||||||
#ping_depsgraph_update(object)
|
#ping_depsgraph_update(object)
|
||||||
|
|
||||||
|
|
||||||
@ -226,14 +245,14 @@ def copy_propertyGroup_values_to_another_object(source_object, target_object, co
|
|||||||
if source_object == None or target_object == None or component_name == None:
|
if source_object == None or target_object == None or component_name == None:
|
||||||
raise Exception('missing input data, cannot copy component propertryGroup')
|
raise Exception('missing input data, cannot copy component propertryGroup')
|
||||||
|
|
||||||
component_definition = find_component_definition_from_short_name(component_name)
|
component_definition = find_component_definition_from_long_name(component_name)
|
||||||
short_name = component_definition["short_name"]
|
long_name = component_name
|
||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_longName(long_name)
|
||||||
|
|
||||||
registry = bpy.context.window_manager.components_registry
|
registry = bpy.context.window_manager.components_registry
|
||||||
|
|
||||||
source_components_metadata = source_object.components_meta.components
|
source_components_metadata = source_object.components_meta.components
|
||||||
source_componentMeta = next(filter(lambda component: component["name"] == short_name, source_components_metadata), None)
|
source_componentMeta = next(filter(lambda component: component["long_name"] == long_name, source_components_metadata), None)
|
||||||
# matching component means we already have this type of component
|
# matching component means we already have this type of component
|
||||||
source_propertyGroup = getattr(source_componentMeta, property_group_name)
|
source_propertyGroup = getattr(source_componentMeta, property_group_name)
|
||||||
|
|
||||||
@ -241,28 +260,27 @@ def copy_propertyGroup_values_to_another_object(source_object, target_object, co
|
|||||||
(_, target_propertyGroup) = upsert_component_in_object(target_object, component_name, registry)
|
(_, target_propertyGroup) = upsert_component_in_object(target_object, component_name, registry)
|
||||||
# add to object
|
# add to object
|
||||||
value = property_group_value_to_custom_property_value(target_propertyGroup, component_definition, registry, None)
|
value = property_group_value_to_custom_property_value(target_propertyGroup, component_definition, registry, None)
|
||||||
target_object[short_name] = value
|
upsert_bevy_component(target_object, long_name, value)
|
||||||
|
|
||||||
# copy the values over
|
# copy the values over
|
||||||
for field_name in source_propertyGroup.field_names:
|
for field_name in source_propertyGroup.field_names:
|
||||||
if field_name in source_propertyGroup:
|
if field_name in source_propertyGroup:
|
||||||
target_propertyGroup[field_name] = source_propertyGroup[field_name]
|
target_propertyGroup[field_name] = source_propertyGroup[field_name]
|
||||||
apply_propertyGroup_values_to_object_customProperties(target_object)
|
apply_propertyGroup_values_to_object_customProperties(target_object)
|
||||||
ping_depsgraph_update(object)
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: move to propgroups ?
|
# TODO: move to propgroups ?
|
||||||
def apply_propertyGroup_values_to_object_customProperties(object):
|
def apply_propertyGroup_values_to_object_customProperties(object):
|
||||||
cleanup_invalid_metadata(object)
|
cleanup_invalid_metadata(object)
|
||||||
registry = bpy.context.window_manager.components_registry
|
registry = bpy.context.window_manager.components_registry
|
||||||
for component_name in dict(object) :
|
for component_name in get_bevy_components(object) :
|
||||||
if component_name == "components_meta":
|
"""if component_name == "components_meta":
|
||||||
continue
|
continue"""
|
||||||
(_, propertyGroup) = upsert_component_in_object(object, component_name, registry)
|
(_, propertyGroup) = upsert_component_in_object(object, component_name, registry)
|
||||||
component_definition = find_component_definition_from_short_name(component_name)
|
component_definition = find_component_definition_from_long_name(component_name)
|
||||||
if component_definition != None:
|
if component_definition != None:
|
||||||
value = property_group_value_to_custom_property_value(propertyGroup, component_definition, registry, None)
|
value = property_group_value_to_custom_property_value(propertyGroup, component_definition, registry, None)
|
||||||
object[component_name] = value
|
upsert_bevy_component(object=object, long_name=component_name, value=value)
|
||||||
|
|
||||||
# apply component value(s) to custom property of a single component
|
# apply component value(s) to custom property of a single component
|
||||||
def apply_propertyGroup_values_to_object_customProperties_for_component(object, component_name):
|
def apply_propertyGroup_values_to_object_customProperties_for_component(object, component_name):
|
||||||
@ -304,7 +322,7 @@ def apply_customProperty_values_to_object_propertyGroups(object):
|
|||||||
|
|
||||||
# removes the given component from the object: removes both the custom property and the matching metadata from the object
|
# removes the given component from the object: removes both the custom property and the matching metadata from the object
|
||||||
def remove_component_from_object(object, component_name):
|
def remove_component_from_object(object, component_name):
|
||||||
bla_component(object, component_name)
|
remove_bevy_component(object, component_name)
|
||||||
|
|
||||||
components_metadata = getattr(object, "components_meta", None)
|
components_metadata = getattr(object, "components_meta", None)
|
||||||
if components_metadata == None:
|
if components_metadata == None:
|
||||||
@ -319,16 +337,14 @@ def remove_component_from_object(object, component_name):
|
|||||||
break
|
break
|
||||||
for index in to_remove:
|
for index in to_remove:
|
||||||
components_metadata.remove(index)
|
components_metadata.remove(index)
|
||||||
ping_depsgraph_update(object)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def add_component_from_custom_property(object):
|
def add_component_from_custom_property(object):
|
||||||
add_metadata_to_components_without_metadata(object)
|
add_metadata_to_components_without_metadata(object)
|
||||||
apply_customProperty_values_to_object_propertyGroups(object)
|
apply_customProperty_values_to_object_propertyGroups(object)
|
||||||
ping_depsgraph_update(object)
|
|
||||||
|
|
||||||
def toggle_component(object, component_name):
|
def toggle_component(object, component_name):
|
||||||
components_in_object = object.components_meta.components
|
components_in_object = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == component_name, components_in_object), None)
|
component_meta = next(filter(lambda component: component["long_name"] == component_name, components_in_object), None)
|
||||||
if component_meta != None:
|
if component_meta != None:
|
||||||
component_meta.visible = not component_meta.visible
|
component_meta.visible = not component_meta.visible
|
||||||
|
@ -4,7 +4,7 @@ import bpy
|
|||||||
from bpy_types import Operator
|
from bpy_types import Operator
|
||||||
from bpy.props import (StringProperty)
|
from bpy.props import (StringProperty)
|
||||||
|
|
||||||
from .metadata import add_component_from_custom_property, add_component_to_object, add_metadata_to_components_without_metadata, apply_customProperty_values_to_object_propertyGroups, apply_propertyGroup_values_to_object_customProperties_for_component, copy_propertyGroup_values_to_another_object, find_component_definition_from_short_name, remove_component_from_object, toggle_component
|
from .metadata import add_component_from_custom_property, add_component_to_object, add_metadata_to_components_without_metadata, apply_customProperty_values_to_object_propertyGroups, apply_propertyGroup_values_to_object_customProperties_for_component, copy_propertyGroup_values_to_another_object, find_component_definition_from_short_name, get_bevy_component_value_by_long_name, get_bevy_components, is_bevy_component_in_object, remove_component_from_object, toggle_component
|
||||||
|
|
||||||
class AddComponentOperator(Operator):
|
class AddComponentOperator(Operator):
|
||||||
"""Add Bevy component to object"""
|
"""Add Bevy component to object"""
|
||||||
@ -36,7 +36,7 @@ class CopyComponentOperator(Operator):
|
|||||||
bl_options = {"UNDO"}
|
bl_options = {"UNDO"}
|
||||||
|
|
||||||
source_component_name: StringProperty(
|
source_component_name: StringProperty(
|
||||||
name="source component_name",
|
name="source component_name (long)",
|
||||||
description="name of the component to copy",
|
description="name of the component to copy",
|
||||||
) # type: ignore
|
) # type: ignore
|
||||||
|
|
||||||
@ -80,10 +80,10 @@ class PasteComponentOperator(Operator):
|
|||||||
self.report({"ERROR"}, "The source object to copy a component from does not exist")
|
self.report({"ERROR"}, "The source object to copy a component from does not exist")
|
||||||
else:
|
else:
|
||||||
component_name = context.window_manager.copied_source_component_name
|
component_name = context.window_manager.copied_source_component_name
|
||||||
if not component_name in source_object:
|
component_value = get_bevy_component_value_by_long_name(source_object, component_name)
|
||||||
|
if component_value is None:
|
||||||
self.report({"ERROR"}, "The source component to copy from does not exist")
|
self.report({"ERROR"}, "The source component to copy from does not exist")
|
||||||
else:
|
else:
|
||||||
component_value = source_object[component_name]
|
|
||||||
print("pasting component to object: component name:", str(component_name), "component value:" + str(component_value))
|
print("pasting component to object: component name:", str(component_name), "component value:" + str(component_value))
|
||||||
print (context.object)
|
print (context.object)
|
||||||
registry = context.window_manager.components_registry
|
registry = context.window_manager.components_registry
|
||||||
@ -114,10 +114,15 @@ class RemoveComponentOperator(Operator):
|
|||||||
else:
|
else:
|
||||||
object = bpy.data.objects[self.object_name]
|
object = bpy.data.objects[self.object_name]
|
||||||
print("removing component ", self.component_name, "from object '"+object.name+"'")
|
print("removing component ", self.component_name, "from object '"+object.name+"'")
|
||||||
if object is not None and 'bevy_components' in object and self.component_name in object['bevy_components']:
|
|
||||||
remove_component_from_object(object, self.component_name)
|
if object is not None and 'bevy_components' in object :
|
||||||
|
component_value = get_bevy_component_value_by_long_name(object, self.component_name)
|
||||||
|
if component_value is not None:
|
||||||
|
remove_component_from_object(object, self.component_name)
|
||||||
|
else :
|
||||||
|
self.report({"ERROR"}, "The component to remove ("+ self.component_name +") does not exist")
|
||||||
else:
|
else:
|
||||||
self.report({"ERROR"}, "The object/ component to remove ("+ self.component_name +") does not exist")
|
self.report({"ERROR"}, "The object to remove ("+ self.component_name +") from does not exist")
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
@ -145,7 +150,7 @@ class RemoveComponentFromAllObjectsOperator(Operator):
|
|||||||
total = len(bpy.data.objects)
|
total = len(bpy.data.objects)
|
||||||
for index, object in enumerate(bpy.data.objects):
|
for index, object in enumerate(bpy.data.objects):
|
||||||
if len(object.keys()) > 0:
|
if len(object.keys()) > 0:
|
||||||
if object is not None and self.component_name in object:
|
if object is not None and is_bevy_component_in_object(object, self.component_name):
|
||||||
remove_component_from_object(object, self.component_name)
|
remove_component_from_object(object, self.component_name)
|
||||||
|
|
||||||
progress = index / total
|
progress = index / total
|
||||||
@ -222,7 +227,7 @@ class OT_rename_component(Operator):
|
|||||||
components_metadata = getattr(object, "components_meta", None)
|
components_metadata = getattr(object, "components_meta", None)
|
||||||
if components_metadata:
|
if components_metadata:
|
||||||
components_metadata = components_metadata.components
|
components_metadata = components_metadata.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == new_name, components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == new_name, components_metadata), None)
|
||||||
if component_meta:
|
if component_meta:
|
||||||
component_meta.invalid = True
|
component_meta.invalid = True
|
||||||
component_meta.invalid_details = "unknow issue when renaming/transforming component, please remove it & add it back again"
|
component_meta.invalid_details = "unknow issue when renaming/transforming component, please remove it & add it back again"
|
||||||
@ -240,7 +245,7 @@ class OT_rename_component(Operator):
|
|||||||
components_metadata = getattr(object, "components_meta", None)
|
components_metadata = getattr(object, "components_meta", None)
|
||||||
if components_metadata:
|
if components_metadata:
|
||||||
components_metadata = components_metadata.components
|
components_metadata = components_metadata.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == new_name, components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == new_name, components_metadata), None)
|
||||||
if component_meta:
|
if component_meta:
|
||||||
component_meta.invalid = True
|
component_meta.invalid = True
|
||||||
component_meta.invalid_details = "wrong custom property value, overwrite them by changing the values in the ui or change them & regenerate"
|
component_meta.invalid_details = "wrong custom property value, overwrite them by changing the values in the ui or change them & regenerate"
|
||||||
|
@ -8,6 +8,7 @@ from .operators import AddComponentOperator, CopyComponentOperator, Fix_Componen
|
|||||||
def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None):
|
def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None):
|
||||||
is_enum = getattr(propertyGroup, "with_enum")
|
is_enum = getattr(propertyGroup, "with_enum")
|
||||||
is_list = getattr(propertyGroup, "with_list")
|
is_list = getattr(propertyGroup, "with_list")
|
||||||
|
is_map = getattr(propertyGroup, "with_map")
|
||||||
#nesting = nesting + [current_short_name] # we need this convoluted "nested path strings " workaround so that operators working on a given
|
#nesting = nesting + [current_short_name] # we need this convoluted "nested path strings " workaround so that operators working on a given
|
||||||
# item in our components hierarchy can get the correct propertyGroup by STRINGS because of course, we cannot pass objects to operators...sigh
|
# item in our components hierarchy can get the correct propertyGroup by STRINGS because of course, we cannot pass objects to operators...sigh
|
||||||
|
|
||||||
@ -83,6 +84,43 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None):
|
|||||||
op.component_name = rootName
|
op.component_name = rootName
|
||||||
op.property_group_path = json.dumps(nesting)
|
op.property_group_path = json.dumps(nesting)
|
||||||
|
|
||||||
|
elif is_map:
|
||||||
|
keys_list = getattr(propertyGroup, "list")
|
||||||
|
values_list = getattr(propertyGroup, "values_list")
|
||||||
|
box = layout.box()
|
||||||
|
row = box.row()
|
||||||
|
row.label(text="key")
|
||||||
|
row.label(text="value")
|
||||||
|
#values_setter = getattr(propertyGroup, "values_setter")
|
||||||
|
# draw_propertyGroup(values_setter, row, nesting, rootName)
|
||||||
|
|
||||||
|
split = box.split(factor=0.9)
|
||||||
|
list_column, buttons_column = (split.column(),split.column())
|
||||||
|
list_column = list_column.box()
|
||||||
|
|
||||||
|
for index, item in enumerate(keys_list):
|
||||||
|
row = list_column.row()
|
||||||
|
#row.label(text=str(index))
|
||||||
|
draw_propertyGroup(item, row, nesting, rootName)
|
||||||
|
|
||||||
|
value = values_list[index]
|
||||||
|
draw_propertyGroup(value, row, nesting, rootName)
|
||||||
|
|
||||||
|
|
||||||
|
#various control buttons
|
||||||
|
buttons_column.separator()
|
||||||
|
row = buttons_column.row()
|
||||||
|
op = row.operator('generic_map.map_action', icon='ADD', text="")
|
||||||
|
op.action = 'ADD'
|
||||||
|
op.component_name = rootName
|
||||||
|
op.property_group_path = json.dumps(nesting)
|
||||||
|
|
||||||
|
row = buttons_column.row()
|
||||||
|
op = row.operator('generic_map.map_action', icon='REMOVE', text="")
|
||||||
|
op.action = 'REMOVE'
|
||||||
|
op.component_name = rootName
|
||||||
|
op.property_group_path = json.dumps(nesting)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for fname in field_names:
|
for fname in field_names:
|
||||||
subrow = layout.row()
|
subrow = layout.row()
|
||||||
@ -178,12 +216,12 @@ class BEVY_COMPONENTS_PT_ComponentsPanel(bpy.types.Panel):
|
|||||||
|
|
||||||
# we fetch the matching ui property group
|
# we fetch the matching ui property group
|
||||||
root_propertyGroup_name = registry.get_propertyGroupName_from_longName(component_name)
|
root_propertyGroup_name = registry.get_propertyGroupName_from_longName(component_name)
|
||||||
print("root_propertyGroup_name", root_propertyGroup_name)
|
"""print("root_propertyGroup_name", root_propertyGroup_name)
|
||||||
print("component_meta", component_meta, component_invalid)
|
print("component_meta", component_meta, component_invalid)"""
|
||||||
|
|
||||||
if root_propertyGroup_name:
|
if root_propertyGroup_name:
|
||||||
propertyGroup = getattr(component_meta, root_propertyGroup_name, None)
|
propertyGroup = getattr(component_meta, root_propertyGroup_name, None)
|
||||||
print("propertyGroup", propertyGroup)
|
"""print("propertyGroup", propertyGroup)"""
|
||||||
if propertyGroup:
|
if propertyGroup:
|
||||||
# if the component has only 0 or 1 field names, display inline, otherwise change layout
|
# if the component has only 0 or 1 field names, display inline, otherwise change layout
|
||||||
single_field = len(propertyGroup.field_names) < 2
|
single_field = len(propertyGroup.field_names) < 2
|
||||||
|
@ -5,8 +5,8 @@ conversion_tables = {
|
|||||||
|
|
||||||
"char": lambda value: '"'+value+'"',
|
"char": lambda value: '"'+value+'"',
|
||||||
"str": lambda value: '"'+value+'"',
|
"str": lambda value: '"'+value+'"',
|
||||||
"alloc::string::String": lambda value: '"'+value+'"',
|
"alloc::string::String": lambda value: '"'+str(value)+'"',
|
||||||
"alloc::borrow::Cow<str>": lambda value: '"'+value+'"',
|
"alloc::borrow::Cow<str>": lambda value: '"'+str(value)+'"',
|
||||||
|
|
||||||
"glam::Vec2": lambda value: "Vec2(x:"+str(value[0])+ ", y:"+str(value[1])+")",
|
"glam::Vec2": lambda value: "Vec2(x:"+str(value[0])+ ", y:"+str(value[1])+")",
|
||||||
"glam::DVec2": lambda value: "DVec2(x:"+str(value[0])+ ", y:"+str(value[1])+")",
|
"glam::DVec2": lambda value: "DVec2(x:"+str(value[0])+ ", y:"+str(value[1])+")",
|
||||||
@ -28,20 +28,22 @@ conversion_tables = {
|
|||||||
#converts the value of a property group(no matter its complexity) into a single custom property value
|
#converts the value of a property group(no matter its complexity) into a single custom property value
|
||||||
# this is more or less a glorified "to_ron()" method (not quite but close to)
|
# this is more or less a glorified "to_ron()" method (not quite but close to)
|
||||||
def property_group_value_to_custom_property_value(property_group, definition, registry, parent=None, value=None):
|
def property_group_value_to_custom_property_value(property_group, definition, registry, parent=None, value=None):
|
||||||
component_name = definition["short_name"]
|
component_name = definition["short_name"] # FIXME: we should operate based on long names
|
||||||
type_info = definition["typeInfo"] if "typeInfo" in definition else None
|
type_info = definition["typeInfo"] if "typeInfo" in definition else None
|
||||||
type_def = definition["type"] if "type" in definition else None
|
type_def = definition["type"] if "type" in definition else None
|
||||||
type_name = definition["title"]
|
type_name = definition["title"]
|
||||||
is_value_type = type_name in conversion_tables
|
is_value_type = type_name in conversion_tables
|
||||||
#print("computing custom property", component_name, type_info, type_def, type_name)
|
print("computing custom property: component name:", component_name, "type_info", type_info, "type_def", type_def, "type_name", type_name)
|
||||||
|
|
||||||
if is_value_type:
|
if is_value_type:
|
||||||
value = conversion_tables[type_name](value)
|
value = conversion_tables[type_name](value)
|
||||||
elif type_info == "Struct":
|
elif type_info == "Struct":
|
||||||
|
print("generating string for struct")
|
||||||
values = {}
|
values = {}
|
||||||
if len(property_group.field_names) ==0:
|
if len(property_group.field_names) ==0:
|
||||||
value = '()'
|
value = '()'
|
||||||
else:
|
else:
|
||||||
|
print("toto", type_def, definition, property_group)
|
||||||
for index, field_name in enumerate(property_group.field_names):
|
for index, field_name in enumerate(property_group.field_names):
|
||||||
item_type_name = definition["properties"][field_name]["type"]["$ref"].replace("#/$defs/", "")
|
item_type_name = definition["properties"][field_name]["type"]["$ref"].replace("#/$defs/", "")
|
||||||
item_definition = registry.type_infos[item_type_name] if item_type_name in registry.type_infos else None
|
item_definition = registry.type_infos[item_type_name] if item_type_name in registry.type_infos else None
|
||||||
@ -74,8 +76,10 @@ def property_group_value_to_custom_property_value(property_group, definition, re
|
|||||||
elif type_info == "TupleStruct":
|
elif type_info == "TupleStruct":
|
||||||
values = {}
|
values = {}
|
||||||
for index, field_name in enumerate(property_group.field_names):
|
for index, field_name in enumerate(property_group.field_names):
|
||||||
|
#print("toto", index, definition["prefixItems"][index]["type"]["$ref"])
|
||||||
item_type_name = definition["prefixItems"][index]["type"]["$ref"].replace("#/$defs/", "")
|
item_type_name = definition["prefixItems"][index]["type"]["$ref"].replace("#/$defs/", "")
|
||||||
item_definition = registry.type_infos[item_type_name] if item_type_name in registry.type_infos else None
|
item_definition = registry.type_infos[item_type_name] if item_type_name in registry.type_infos else None
|
||||||
|
# print("here", item_type_name, item_definition)
|
||||||
|
|
||||||
value = getattr(property_group, field_name)
|
value = getattr(property_group, field_name)
|
||||||
is_property_group = isinstance(value, PropertyGroup)
|
is_property_group = isinstance(value, PropertyGroup)
|
||||||
@ -88,6 +92,7 @@ def property_group_value_to_custom_property_value(property_group, definition, re
|
|||||||
|
|
||||||
value = tuple(e for e in list(values.values()))
|
value = tuple(e for e in list(values.values()))
|
||||||
elif type_info == "Enum":
|
elif type_info == "Enum":
|
||||||
|
# TODO: perhaps use a mapping of (long) component name to a short ID , like we do in get_propertyGroupName_from_longName
|
||||||
selected = getattr(property_group, component_name)
|
selected = getattr(property_group, component_name)
|
||||||
|
|
||||||
if type_def == "object":
|
if type_def == "object":
|
||||||
@ -134,6 +139,38 @@ def property_group_value_to_custom_property_value(property_group, definition, re
|
|||||||
else:
|
else:
|
||||||
item_value = '""'
|
item_value = '""'
|
||||||
value.append(item_value)
|
value.append(item_value)
|
||||||
|
|
||||||
|
elif type_info == "Map":
|
||||||
|
print("MAAAAAP", property_group)
|
||||||
|
keys_list = getattr(property_group, "list", {})
|
||||||
|
values_list = getattr(property_group, "values_list")
|
||||||
|
value = {}
|
||||||
|
for index, key in enumerate(keys_list):
|
||||||
|
# first get the keys
|
||||||
|
key_type_name = getattr(key, "type_name")
|
||||||
|
definition = registry.type_infos[key_type_name] if key_type_name in registry.type_infos else None
|
||||||
|
if definition != None:
|
||||||
|
key_value = property_group_value_to_custom_property_value(key, definition, registry, component_name, None)
|
||||||
|
if key_type_name.startswith("wrapper_"): #if we have a "fake" tupple for aka for value types, we need to remove one nested level
|
||||||
|
key_value = key_value[0]
|
||||||
|
else:
|
||||||
|
key_value = '""'
|
||||||
|
# and then the values
|
||||||
|
val = values_list[index]
|
||||||
|
value_type_name = getattr(val, "type_name")
|
||||||
|
definition = registry.type_infos[value_type_name] if value_type_name in registry.type_infos else None
|
||||||
|
print("value definition", definition)
|
||||||
|
if definition != None:
|
||||||
|
val_value = property_group_value_to_custom_property_value(val, definition, registry, component_name, None)
|
||||||
|
if value_type_name.startswith("wrapper_"): #if we have a "fake" tupple for aka for value types, we need to remove one nested level
|
||||||
|
val_value = val_value[0]
|
||||||
|
else:
|
||||||
|
val_value = '""'
|
||||||
|
|
||||||
|
|
||||||
|
value[key_value] = val_value
|
||||||
|
print("MAP VALUES", value)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
value = conversion_tables[type_name](value) if is_value_type else value
|
value = conversion_tables[type_name](value) if is_value_type else value
|
||||||
value = '""' if isinstance(value, PropertyGroup) else value
|
value = '""' if isinstance(value, PropertyGroup) else value
|
||||||
@ -145,7 +182,7 @@ def property_group_value_to_custom_property_value(property_group, definition, re
|
|||||||
if parent == None:
|
if parent == None:
|
||||||
value = str(value).replace("'", "")
|
value = str(value).replace("'", "")
|
||||||
value = value.replace(",)",")")
|
value = value.replace(",)",")")
|
||||||
value = value.replace("{", "(").replace("}", ")")
|
value = value.replace("{", "(").replace("}", ")") # FIXME: deal with hashmaps
|
||||||
value = value.replace("True", "true").replace("False", "false")
|
value = value.replace("True", "true").replace("False", "false")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@ -5,8 +5,9 @@ from . import process_structs
|
|||||||
from . import process_tupples
|
from . import process_tupples
|
||||||
from . import process_enum
|
from . import process_enum
|
||||||
from . import process_list
|
from . import process_list
|
||||||
|
from . import process_map
|
||||||
|
|
||||||
def process_component(registry, definition, update, extras=None, nesting = []):
|
def process_component(registry, definition, update, extras=None, nesting = [], nesting_long_names = []):
|
||||||
component_name = definition['title']
|
component_name = definition['title']
|
||||||
short_name = definition["short_name"]
|
short_name = definition["short_name"]
|
||||||
type_info = definition["typeInfo"] if "typeInfo" in definition else None
|
type_info = definition["typeInfo"] if "typeInfo" in definition else None
|
||||||
@ -18,6 +19,7 @@ def process_component(registry, definition, update, extras=None, nesting = []):
|
|||||||
has_prefixItems = len(prefixItems) > 0
|
has_prefixItems = len(prefixItems) > 0
|
||||||
is_enum = type_info == "Enum"
|
is_enum = type_info == "Enum"
|
||||||
is_list = type_info == "List"
|
is_list = type_info == "List"
|
||||||
|
is_map = type_info == "Map"
|
||||||
|
|
||||||
# print("processing", short_name, component_name, type_def, type_info)
|
# print("processing", short_name, component_name, type_def, type_info)
|
||||||
|
|
||||||
@ -28,25 +30,30 @@ def process_component(registry, definition, update, extras=None, nesting = []):
|
|||||||
with_items = False
|
with_items = False
|
||||||
with_enum = False
|
with_enum = False
|
||||||
with_list = False
|
with_list = False
|
||||||
|
with_map = False
|
||||||
|
|
||||||
|
|
||||||
if has_properties:
|
if has_properties:
|
||||||
__annotations__ = __annotations__ | process_structs.process_structs(registry, definition, properties, update, nesting)
|
__annotations__ = __annotations__ | process_structs.process_structs(registry, definition, properties, update, nesting, nesting_long_names)
|
||||||
with_properties = True
|
with_properties = True
|
||||||
tupple_or_struct = "struct"
|
tupple_or_struct = "struct"
|
||||||
|
|
||||||
if has_prefixItems:
|
if has_prefixItems:
|
||||||
__annotations__ = __annotations__ | process_tupples.process_tupples(registry, definition, prefixItems, update, nesting)
|
__annotations__ = __annotations__ | process_tupples.process_tupples(registry, definition, prefixItems, update, nesting, nesting_long_names)
|
||||||
with_items = True
|
with_items = True
|
||||||
tupple_or_struct = "tupple"
|
tupple_or_struct = "tupple"
|
||||||
|
|
||||||
if is_enum:
|
if is_enum:
|
||||||
__annotations__ = __annotations__ | process_enum.process_enum(registry, definition, update, nesting)
|
__annotations__ = __annotations__ | process_enum.process_enum(registry, definition, update, nesting, nesting_long_names)
|
||||||
with_enum = True
|
with_enum = True
|
||||||
|
|
||||||
if is_list:
|
if is_list:
|
||||||
__annotations__ = __annotations__ | process_list.process_list(registry, definition, update, nesting)
|
__annotations__ = __annotations__ | process_list.process_list(registry, definition, update, nesting, nesting_long_names)
|
||||||
with_list= True
|
with_list= True
|
||||||
|
|
||||||
|
if is_map:
|
||||||
|
__annotations__ = __annotations__ | process_map.process_map(registry, definition, update, nesting, nesting_long_names)
|
||||||
|
with_map = True
|
||||||
|
|
||||||
field_names = []
|
field_names = []
|
||||||
for a in __annotations__:
|
for a in __annotations__:
|
||||||
@ -56,7 +63,7 @@ def process_component(registry, definition, update, extras=None, nesting = []):
|
|||||||
extras = extras if extras is not None else {
|
extras = extras if extras is not None else {
|
||||||
"type_name": component_name
|
"type_name": component_name
|
||||||
}
|
}
|
||||||
root_component = nesting[0] if len(nesting) > 0 else component_name
|
root_component = nesting_long_names[0] if len(nesting_long_names) > 0 else component_name
|
||||||
# print("DONE:",short_name,"__annotations__", __annotations__)
|
# print("DONE:",short_name,"__annotations__", __annotations__)
|
||||||
# print("")
|
# print("")
|
||||||
property_group_params = {
|
property_group_params = {
|
||||||
@ -64,7 +71,7 @@ def process_component(registry, definition, update, extras=None, nesting = []):
|
|||||||
'__annotations__': __annotations__,
|
'__annotations__': __annotations__,
|
||||||
'tupple_or_struct': tupple_or_struct,
|
'tupple_or_struct': tupple_or_struct,
|
||||||
'field_names': field_names,
|
'field_names': field_names,
|
||||||
**dict(with_properties = with_properties, with_items= with_items, with_enum= with_enum, with_list= with_list, short_name= short_name),
|
**dict(with_properties = with_properties, with_items= with_items, with_enum= with_enum, with_list= with_list, with_map = with_map, short_name= short_name),
|
||||||
'root_component': root_component
|
'root_component': root_component
|
||||||
}
|
}
|
||||||
#FIXME: YIKES, but have not found another way:
|
#FIXME: YIKES, but have not found another way:
|
||||||
@ -74,7 +81,7 @@ def process_component(registry, definition, update, extras=None, nesting = []):
|
|||||||
-BasicTest => the registration & update callback of this one overwrites the first "basicTest"
|
-BasicTest => the registration & update callback of this one overwrites the first "basicTest"
|
||||||
have not found a cleaner workaround so far
|
have not found a cleaner workaround so far
|
||||||
"""
|
"""
|
||||||
property_group_name = registry.generate_propGroup_name(nesting, short_name, component_name)
|
property_group_name = registry.generate_propGroup_name(nesting, component_name)
|
||||||
(property_group_pointer, property_group_class) = property_group_from_infos(property_group_name, property_group_params)
|
(property_group_pointer, property_group_class) = property_group_from_infos(property_group_name, property_group_params)
|
||||||
# add our component propertyGroup to the registry
|
# add our component propertyGroup to the registry
|
||||||
registry.register_component_propertyGroup(property_group_name, property_group_pointer)
|
registry.register_component_propertyGroup(property_group_name, property_group_pointer)
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
from bpy.props import (StringProperty)
|
from bpy.props import (StringProperty)
|
||||||
from . import process_component
|
from . import process_component
|
||||||
|
|
||||||
def process_enum(registry, definition, update, nesting):
|
def process_enum(registry, definition, update, nesting, nesting_long_names):
|
||||||
blender_property_mapping = registry.blender_property_mapping
|
blender_property_mapping = registry.blender_property_mapping
|
||||||
short_name = definition["short_name"]
|
short_name = definition["short_name"]
|
||||||
|
long_name = definition["title"]
|
||||||
|
|
||||||
type_def = definition["type"] if "type" in definition else None
|
type_def = definition["type"] if "type" in definition else None
|
||||||
values = definition["oneOf"]
|
values = definition["oneOf"]
|
||||||
|
|
||||||
nesting = nesting + [short_name]
|
nesting = nesting + [short_name]
|
||||||
|
nesting_long_names = nesting_long_names = [long_name]
|
||||||
|
|
||||||
__annotations__ = {}
|
__annotations__ = {}
|
||||||
original_type_name = "enum"
|
original_type_name = "enum"
|
||||||
|
|
||||||
@ -25,12 +29,12 @@ def process_enum(registry, definition, update, nesting):
|
|||||||
if "prefixItems" in item:
|
if "prefixItems" in item:
|
||||||
#print("tupple variant in enum", short_name, item)
|
#print("tupple variant in enum", short_name, item)
|
||||||
registry.add_custom_type(item_short_name, item)
|
registry.add_custom_type(item_short_name, item)
|
||||||
(sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting)
|
(sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting, nesting_long_names)
|
||||||
additional_annotations[variant_name] = sub_component_group
|
additional_annotations[variant_name] = sub_component_group
|
||||||
elif "properties" in item:
|
elif "properties" in item:
|
||||||
#print("struct variant in enum", short_name, item)
|
#print("struct variant in enum", short_name, item)
|
||||||
registry.add_custom_type(item_short_name, item)
|
registry.add_custom_type(item_short_name, item)
|
||||||
(sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting)
|
(sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting, nesting_long_names)
|
||||||
additional_annotations[variant_name] = sub_component_group
|
additional_annotations[variant_name] = sub_component_group
|
||||||
else: # for the cases where it's neither a tupple nor a structs: FIXME: not 100% sure of this
|
else: # for the cases where it's neither a tupple nor a structs: FIXME: not 100% sure of this
|
||||||
#print("other variant in enum", short_name)
|
#print("other variant in enum", short_name)
|
||||||
|
@ -2,12 +2,16 @@ from bpy.props import (StringProperty, IntProperty, CollectionProperty)
|
|||||||
from .utils import generate_wrapper_propertyGroup
|
from .utils import generate_wrapper_propertyGroup
|
||||||
from . import process_component
|
from . import process_component
|
||||||
|
|
||||||
def process_list(registry, definition, update, nesting=[]):
|
def process_list(registry, definition, update, nesting=[], nesting_long_names=[]):
|
||||||
value_types_defaults = registry.value_types_defaults
|
value_types_defaults = registry.value_types_defaults
|
||||||
type_infos = registry.type_infos
|
type_infos = registry.type_infos
|
||||||
|
|
||||||
short_name = definition["short_name"]
|
short_name = definition["short_name"]
|
||||||
|
long_name = definition["title"]
|
||||||
ref_name = definition["items"]["type"]["$ref"].replace("#/$defs/", "")
|
ref_name = definition["items"]["type"]["$ref"].replace("#/$defs/", "")
|
||||||
|
|
||||||
|
nesting = nesting+[short_name]
|
||||||
|
nesting_long_names = nesting_long_names + [long_name]
|
||||||
|
|
||||||
item_definition = type_infos[ref_name]
|
item_definition = type_infos[ref_name]
|
||||||
item_long_name = item_definition["title"]
|
item_long_name = item_definition["title"]
|
||||||
@ -17,12 +21,11 @@ def process_list(registry, definition, update, nesting=[]):
|
|||||||
property_group_class = None
|
property_group_class = None
|
||||||
#if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName !
|
#if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName !
|
||||||
if is_item_value_type:
|
if is_item_value_type:
|
||||||
property_group_class = generate_wrapper_propertyGroup(short_name, item_long_name, definition["items"]["type"]["$ref"],registry, update)
|
property_group_class = generate_wrapper_propertyGroup(long_name, item_long_name, definition["items"]["type"]["$ref"], registry, update)
|
||||||
else:
|
else:
|
||||||
(_, list_content_group_class) = process_component.process_component(registry, item_definition, update, {"nested": True, "type_name": item_long_name}, nesting)
|
(_, list_content_group_class) = process_component.process_component(registry, item_definition, update, {"nested": True, "type_name": item_long_name}, nesting)
|
||||||
property_group_class = list_content_group_class
|
property_group_class = list_content_group_class
|
||||||
|
|
||||||
nesting = nesting+[short_name]
|
|
||||||
item_collection = CollectionProperty(type=property_group_class)
|
item_collection = CollectionProperty(type=property_group_class)
|
||||||
|
|
||||||
item_short_name = item_short_name if not is_item_value_type else "wrapper_" + item_short_name
|
item_short_name = item_short_name if not is_item_value_type else "wrapper_" + item_short_name
|
||||||
|
71
tools/bevy_components/propGroups/process_map.py
Normal file
71
tools/bevy_components/propGroups/process_map.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
from bpy.props import (StringProperty, IntProperty, CollectionProperty)
|
||||||
|
from .utils import generate_wrapper_propertyGroup
|
||||||
|
from . import process_component
|
||||||
|
|
||||||
|
def process_map(registry, definition, update, nesting=[], nesting_long_names=[]):
|
||||||
|
print("IS HASHMAP")
|
||||||
|
value_types_defaults = registry.value_types_defaults
|
||||||
|
type_infos = registry.type_infos
|
||||||
|
|
||||||
|
short_name = definition["short_name"]
|
||||||
|
long_name = definition["title"]
|
||||||
|
|
||||||
|
nesting = nesting + [short_name]
|
||||||
|
nesting_long_names = nesting_long_names + [long_name]
|
||||||
|
|
||||||
|
#ref_name = definition["items"]["type"]["$ref"].replace("#/$defs/", "")
|
||||||
|
value_ref_name = definition["additionalProperties"]["type"]["$ref"].replace("#/$defs/", "")
|
||||||
|
key_ref_name = long_name.split(',')[0].split('<')[1]# FIXME: hack !!!
|
||||||
|
key_type = ''
|
||||||
|
value_type = ''
|
||||||
|
print("infos", short_name, "long name", long_name)
|
||||||
|
print("value ref", value_ref_name, "key ref", key_ref_name)
|
||||||
|
#print("definition", definition)
|
||||||
|
|
||||||
|
if value_ref_name in type_infos:
|
||||||
|
value_definition = type_infos[value_ref_name]
|
||||||
|
original_type_name = value_definition["title"]
|
||||||
|
original_short_name = value_definition["short_name"]
|
||||||
|
is_value_value_type = original_type_name in value_types_defaults
|
||||||
|
definition_link = definition["additionalProperties"]["type"]["$ref"]#f"#/$defs/{value_ref_name}"
|
||||||
|
|
||||||
|
print("hashmap VALUE type", original_type_name)
|
||||||
|
|
||||||
|
#if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName !
|
||||||
|
if is_value_value_type:
|
||||||
|
values_property_group_class = generate_wrapper_propertyGroup(long_name, original_type_name, definition_link, registry, update)
|
||||||
|
else:
|
||||||
|
(_, list_content_group_class) = process_component.process_component(registry, value_definition, update, {"nested": True, "type_name": original_type_name}, nesting)
|
||||||
|
values_property_group_class = list_content_group_class
|
||||||
|
|
||||||
|
values_collection = CollectionProperty(type=values_property_group_class)
|
||||||
|
|
||||||
|
if key_ref_name in type_infos:
|
||||||
|
key_definition = type_infos[key_ref_name]
|
||||||
|
original_type_name = key_definition["title"]
|
||||||
|
original_short_name = key_definition["short_name"]
|
||||||
|
is_key_value_type = original_type_name in value_types_defaults
|
||||||
|
definition_link = f"#/$defs/{key_ref_name}"
|
||||||
|
|
||||||
|
#if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName !
|
||||||
|
if is_key_value_type:
|
||||||
|
keys_property_group_class = generate_wrapper_propertyGroup(long_name+'_values', original_type_name, definition_link, registry, update)
|
||||||
|
else:
|
||||||
|
(_, list_content_group_class) = process_component.process_component(registry, key_definition, update, {"nested": True, "type_name": original_type_name}, nesting)
|
||||||
|
keys_property_group_class = list_content_group_class
|
||||||
|
|
||||||
|
keys_collection = CollectionProperty(type=keys_property_group_class)
|
||||||
|
|
||||||
|
__annotations__ = {
|
||||||
|
"list": keys_collection,
|
||||||
|
"list_index": IntProperty(name = "Index for keys", default = 0, update=update),
|
||||||
|
"values_list": values_collection,
|
||||||
|
"values_list_index": IntProperty(name = "Index for values", default = 0, update=update),
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
"values_setter": values_setter,
|
||||||
|
"values_list": values_collection,
|
||||||
|
"values_list_index": IntProperty(name = "Index for values", default = 0, update=update),
|
||||||
|
'''
|
||||||
|
|
||||||
|
return __annotations__
|
@ -1,19 +1,24 @@
|
|||||||
from bpy.props import (StringProperty)
|
from bpy.props import (StringProperty)
|
||||||
from . import process_component
|
from . import process_component
|
||||||
|
|
||||||
def process_structs(registry, definition, properties, update, nesting):
|
def process_structs(registry, definition, properties, update, nesting, nesting_long_names):
|
||||||
value_types_defaults = registry.value_types_defaults
|
value_types_defaults = registry.value_types_defaults
|
||||||
blender_property_mapping = registry.blender_property_mapping
|
blender_property_mapping = registry.blender_property_mapping
|
||||||
type_infos = registry.type_infos
|
type_infos = registry.type_infos
|
||||||
|
long_name = definition["title"]
|
||||||
short_name = definition["short_name"]
|
short_name = definition["short_name"]
|
||||||
|
|
||||||
__annotations__ = {}
|
__annotations__ = {}
|
||||||
default_values = {}
|
default_values = {}
|
||||||
nesting = nesting + [short_name]
|
nesting = nesting + [short_name]
|
||||||
|
nesting_long_names = nesting_long_names + [long_name]
|
||||||
|
|
||||||
|
if short_name == "HashmapTestSimple":
|
||||||
|
print("Struct", short_name)
|
||||||
for property_name in properties.keys():
|
for property_name in properties.keys():
|
||||||
ref_name = properties[property_name]["type"]["$ref"].replace("#/$defs/", "")
|
ref_name = properties[property_name]["type"]["$ref"].replace("#/$defs/", "")
|
||||||
|
if short_name == "HashmapTestSimple":
|
||||||
|
print("ref name", ref_name)
|
||||||
if ref_name in type_infos:
|
if ref_name in type_infos:
|
||||||
original = type_infos[ref_name]
|
original = type_infos[ref_name]
|
||||||
original_type_name = original["title"]
|
original_type_name = original["title"]
|
||||||
@ -21,6 +26,9 @@ def process_structs(registry, definition, properties, update, nesting):
|
|||||||
value = value_types_defaults[original_type_name] if is_value_type else None
|
value = value_types_defaults[original_type_name] if is_value_type else None
|
||||||
default_values[property_name] = value
|
default_values[property_name] = value
|
||||||
|
|
||||||
|
if short_name == "HashmapTestSimple":
|
||||||
|
print("original",original, original_type_name, is_value_type, value)
|
||||||
|
|
||||||
if is_value_type:
|
if is_value_type:
|
||||||
if original_type_name in blender_property_mapping:
|
if original_type_name in blender_property_mapping:
|
||||||
blender_property_def = blender_property_mapping[original_type_name]
|
blender_property_def = blender_property_mapping[original_type_name]
|
||||||
@ -33,7 +41,7 @@ def process_structs(registry, definition, properties, update, nesting):
|
|||||||
__annotations__[property_name] = blender_property
|
__annotations__[property_name] = blender_property
|
||||||
else:
|
else:
|
||||||
original_long_name = original["title"]
|
original_long_name = original["title"]
|
||||||
(sub_component_group, _) = process_component.process_component(registry, original, update, {"nested": True, "type_name": original_long_name}, nesting)
|
(sub_component_group, _) = process_component.process_component(registry, original, update, {"nested": True, "type_name": original_long_name}, nesting, nesting_long_names)
|
||||||
__annotations__[property_name] = sub_component_group
|
__annotations__[property_name] = sub_component_group
|
||||||
# if there are sub fields, add an attribute "sub_fields" possibly a pointer property ? or add a standard field to the type , that is stored under "attributes" and not __annotations (better)
|
# if there are sub fields, add an attribute "sub_fields" possibly a pointer property ? or add a standard field to the type , that is stored under "attributes" and not __annotations (better)
|
||||||
else:
|
else:
|
||||||
@ -41,6 +49,6 @@ def process_structs(registry, definition, properties, update, nesting):
|
|||||||
__annotations__[property_name] = StringProperty(default="N/A")
|
__annotations__[property_name] = StringProperty(default="N/A")
|
||||||
registry.add_missing_typeInfo(ref_name)
|
registry.add_missing_typeInfo(ref_name)
|
||||||
# the root component also becomes invalid (in practice it is not always a component, but good enough)
|
# the root component also becomes invalid (in practice it is not always a component, but good enough)
|
||||||
registry.add_invalid_component(nesting[0])
|
registry.add_invalid_component(nesting_long_names[0])
|
||||||
|
|
||||||
return __annotations__
|
return __annotations__
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
from bpy.props import (StringProperty)
|
from bpy.props import (StringProperty)
|
||||||
from . import process_component
|
from . import process_component
|
||||||
|
|
||||||
def process_tupples(registry, definition, prefixItems, update, nesting=[]):
|
def process_tupples(registry, definition, prefixItems, update, nesting=[], nesting_long_names=[]):
|
||||||
value_types_defaults = registry.value_types_defaults
|
value_types_defaults = registry.value_types_defaults
|
||||||
blender_property_mapping = registry.blender_property_mapping
|
blender_property_mapping = registry.blender_property_mapping
|
||||||
type_infos = registry.type_infos
|
type_infos = registry.type_infos
|
||||||
|
long_name = definition["title"]
|
||||||
short_name = definition["short_name"]
|
short_name = definition["short_name"]
|
||||||
|
|
||||||
nesting = nesting+[short_name]
|
nesting = nesting+[short_name]
|
||||||
|
nesting_long_names = nesting_long_names + [long_name]
|
||||||
__annotations__ = {}
|
__annotations__ = {}
|
||||||
|
|
||||||
default_values = []
|
default_values = []
|
||||||
@ -46,7 +48,7 @@ def process_tupples(registry, definition, prefixItems, update, nesting=[]):
|
|||||||
__annotations__[property_name] = StringProperty(default="N/A")
|
__annotations__[property_name] = StringProperty(default="N/A")
|
||||||
registry.add_missing_typeInfo(ref_name)
|
registry.add_missing_typeInfo(ref_name)
|
||||||
# the root component also becomes invalid (in practice it is not always a component, but good enough)
|
# the root component also becomes invalid (in practice it is not always a component, but good enough)
|
||||||
registry.add_invalid_component(nesting[0])
|
registry.add_invalid_component(nesting_long_names[0])
|
||||||
|
|
||||||
|
|
||||||
return __annotations__
|
return __annotations__
|
||||||
|
@ -3,6 +3,7 @@ from .conversions_from_prop_group import property_group_value_to_custom_property
|
|||||||
from .process_component import process_component
|
from .process_component import process_component
|
||||||
from .utils import update_calback_helper
|
from .utils import update_calback_helper
|
||||||
|
|
||||||
|
import json
|
||||||
## main callback function, fired whenever any property changes, no matter the nesting level
|
## main callback function, fired whenever any property changes, no matter the nesting level
|
||||||
def update_component(self, context, definition, component_name):
|
def update_component(self, context, definition, component_name):
|
||||||
registry = bpy.context.window_manager.components_registry
|
registry = bpy.context.window_manager.components_registry
|
||||||
@ -14,12 +15,17 @@ def update_component(self, context, definition, component_name):
|
|||||||
print("")
|
print("")
|
||||||
print("update in component", component_name, self, "current_object", current_object.name)
|
print("update in component", component_name, self, "current_object", current_object.name)
|
||||||
components_in_object = current_object.components_meta.components
|
components_in_object = current_object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == component_name, components_in_object), None)
|
component_meta = next(filter(lambda component: component["long_name"] == component_name, components_in_object), None)
|
||||||
|
print("component_meta", component_meta)
|
||||||
|
|
||||||
if component_meta != None:
|
if component_meta != None:
|
||||||
property_group_name = registry.get_propertyGroupName_from_shortName(component_name)
|
property_group_name = registry.get_propertyGroupName_from_longName(component_name)
|
||||||
self = getattr(component_meta, property_group_name)
|
property_group = getattr(component_meta, property_group_name)
|
||||||
# we use our helper to set the values
|
# we use our helper to set the values
|
||||||
context.object[component_name] = property_group_value_to_custom_property_value(self, definition, registry, None)
|
object = context.object
|
||||||
|
previous = json.loads(object['bevy_components'])
|
||||||
|
previous[component_name] = property_group_value_to_custom_property_value(property_group, definition, registry, None)
|
||||||
|
object['bevy_components'] = json.dumps(previous)
|
||||||
|
|
||||||
|
|
||||||
def generate_propertyGroups_for_components():
|
def generate_propertyGroups_for_components():
|
||||||
@ -31,9 +37,8 @@ def generate_propertyGroups_for_components():
|
|||||||
|
|
||||||
for component_name in type_infos:
|
for component_name in type_infos:
|
||||||
definition = type_infos[component_name]
|
definition = type_infos[component_name]
|
||||||
short_name = definition["short_name"]
|
|
||||||
is_component = definition['isComponent'] if "isComponent" in definition else False
|
is_component = definition['isComponent'] if "isComponent" in definition else False
|
||||||
root_property_name = short_name if is_component else None
|
root_property_name = component_name if is_component else None
|
||||||
process_component(registry, definition, update_calback_helper(definition, update_component, root_property_name), None, [])
|
process_component(registry, definition, update_calback_helper(definition, update_component, root_property_name), None, [])
|
||||||
|
|
||||||
# if we had to add any wrapper types on the fly, process them now
|
# if we had to add any wrapper types on the fly, process them now
|
||||||
|
@ -8,13 +8,16 @@ from bpy_types import PropertyGroup
|
|||||||
|
|
||||||
# this helper creates a "fake"/wrapper property group that is NOT a real type in the registry
|
# this helper creates a "fake"/wrapper property group that is NOT a real type in the registry
|
||||||
# usefull for things like value types in list items etc
|
# usefull for things like value types in list items etc
|
||||||
def generate_wrapper_propertyGroup(short_name, item_long_name, definition, registry, update):
|
def generate_wrapper_propertyGroup(wrapped_type_long_name_name, item_long_name, definition_link, registry, update):
|
||||||
value_types_defaults = registry.value_types_defaults
|
value_types_defaults = registry.value_types_defaults
|
||||||
blender_property_mapping = registry.blender_property_mapping
|
blender_property_mapping = registry.blender_property_mapping
|
||||||
is_item_value_type = item_long_name in value_types_defaults
|
is_item_value_type = item_long_name in value_types_defaults
|
||||||
|
|
||||||
wrapper_name = "wrapper_" + short_name
|
wrapper_name = "wrapper_" + wrapped_type_long_name_name
|
||||||
|
print("WRAPPER NAME", wrapper_name)
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME: this is not a correct generic value for hashmaps !!?
|
||||||
wrapper_definition = {
|
wrapper_definition = {
|
||||||
"isComponent": False,
|
"isComponent": False,
|
||||||
"isResource": False,
|
"isResource": False,
|
||||||
@ -22,17 +25,21 @@ def generate_wrapper_propertyGroup(short_name, item_long_name, definition, regis
|
|||||||
"prefixItems": [
|
"prefixItems": [
|
||||||
{
|
{
|
||||||
"type": {
|
"type": {
|
||||||
"$ref": definition
|
"$ref": definition_link
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"short_name": wrapper_name,
|
"short_name": wrapper_name, # FIXME !!!
|
||||||
"title": wrapper_name,
|
"title": wrapper_name,
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"typeInfo": "TupleStruct"
|
"typeInfo": "TupleStruct"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# we generate a very small 'hash' for the component name
|
||||||
|
property_group_name = registry.generate_propGroup_name(nesting=[], longName=wrapper_name)
|
||||||
registry.add_custom_type(wrapper_name, wrapper_definition)
|
registry.add_custom_type(wrapper_name, wrapper_definition)
|
||||||
|
|
||||||
|
|
||||||
blender_property = StringProperty(default="", update=update)
|
blender_property = StringProperty(default="", update=update)
|
||||||
if item_long_name in blender_property_mapping:
|
if item_long_name in blender_property_mapping:
|
||||||
value = value_types_defaults[item_long_name] if is_item_value_type else None
|
value = value_types_defaults[item_long_name] if is_item_value_type else None
|
||||||
@ -51,10 +58,9 @@ def generate_wrapper_propertyGroup(short_name, item_long_name, definition, regis
|
|||||||
'__annotations__': wrapper_annotations,
|
'__annotations__': wrapper_annotations,
|
||||||
'tupple_or_struct': "tupple",
|
'tupple_or_struct': "tupple",
|
||||||
'field_names': ['0'],
|
'field_names': ['0'],
|
||||||
**dict(with_properties = False, with_items= True, with_enum= False, with_list= False, short_name= wrapper_name, type_name=wrapper_name),
|
**dict(with_properties = False, with_items= True, with_enum= False, with_list= False, with_map =False, short_name=wrapper_name, type_name=wrapper_name),
|
||||||
#'root_component': root_component
|
|
||||||
}
|
}
|
||||||
property_group_class = type(wrapper_name, (PropertyGroup,), property_group_params)
|
property_group_class = type(property_group_name, (PropertyGroup,), property_group_params)
|
||||||
bpy.utils.register_class(property_group_class)
|
bpy.utils.register_class(property_group_class)
|
||||||
|
|
||||||
return property_group_class
|
return property_group_class
|
@ -317,6 +317,7 @@ class ComponentsRegistry(PropertyGroup):
|
|||||||
self.type_infos[type_name] = self.custom_types_to_add[type_name]
|
self.type_infos[type_name] = self.custom_types_to_add[type_name]
|
||||||
self.custom_types_to_add.clear()
|
self.custom_types_to_add.clear()
|
||||||
|
|
||||||
|
# add an invalid component to the list (long name)
|
||||||
def add_invalid_component(self, component_name):
|
def add_invalid_component(self, component_name):
|
||||||
self.invalid_components.append(component_name)
|
self.invalid_components.append(component_name)
|
||||||
|
|
||||||
@ -335,7 +336,7 @@ class ComponentsRegistry(PropertyGroup):
|
|||||||
long_names_to_propgroup_names = {}
|
long_names_to_propgroup_names = {}
|
||||||
|
|
||||||
# generate propGroup name from nesting level & shortName: each shortName + nesting is unique
|
# generate propGroup name from nesting level & shortName: each shortName + nesting is unique
|
||||||
def generate_propGroup_name(self, nesting, shortName, longName):
|
def generate_propGroup_name(self, nesting, longName):
|
||||||
#print("gen propGroup name for", shortName, nesting)
|
#print("gen propGroup name for", shortName, nesting)
|
||||||
#if shortName in self.short_names_to_propgroup_names and len(nesting) == 0:
|
#if shortName in self.short_names_to_propgroup_names and len(nesting) == 0:
|
||||||
# return self.get_propertyGroupName_from_shortName(shortName)
|
# return self.get_propertyGroupName_from_shortName(shortName)
|
||||||
@ -350,7 +351,7 @@ class ComponentsRegistry(PropertyGroup):
|
|||||||
self.short_names_to_propgroup_names[key] = propGroupName"""
|
self.short_names_to_propgroup_names[key] = propGroupName"""
|
||||||
# FIXME:
|
# FIXME:
|
||||||
key = str(nesting) + longName if len(nesting) > 0 else longName
|
key = str(nesting) + longName if len(nesting) > 0 else longName
|
||||||
self.long_names_to_propgroup_names[longName] = propGroupName
|
self.long_names_to_propgroup_names[key] = propGroupName
|
||||||
return propGroupName
|
return propGroupName
|
||||||
|
|
||||||
def get_propertyGroupName_from_shortName(self, shortName):
|
def get_propertyGroupName_from_shortName(self, shortName):
|
||||||
@ -358,7 +359,9 @@ class ComponentsRegistry(PropertyGroup):
|
|||||||
|
|
||||||
def get_propertyGroupName_from_longName(self, longName):
|
def get_propertyGroupName_from_longName(self, longName):
|
||||||
return self.long_names_to_propgroup_names.get(longName, None)
|
return self.long_names_to_propgroup_names.get(longName, None)
|
||||||
|
|
||||||
|
def long_name_to_key():
|
||||||
|
pass
|
||||||
|
|
||||||
###########
|
###########
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ def test_components_should_generate_correct_custom_properties(setup_data):
|
|||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
|
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
added_components.append(component_type)
|
added_components.append(component_type)
|
||||||
custom_property_values[short_name] = object[short_name]
|
custom_property_values[short_name] = object[short_name]
|
||||||
@ -87,7 +87,7 @@ def test_components_should_generate_correct_custom_properties_with_randomized_va
|
|||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
|
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
component_values_shuffler(seed= 10, property_group=propertyGroup, definition=definition, registry=registry)
|
component_values_shuffler(seed= 10, property_group=propertyGroup, definition=definition, registry=registry)
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ def test_components_should_generate_correct_propertyGroup_values_from_custom_pro
|
|||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
|
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
added_components.append(component_type)
|
added_components.append(component_type)
|
||||||
# randomise values
|
# randomise values
|
||||||
@ -195,7 +195,7 @@ def test_remove_components(setup_data):
|
|||||||
object = bpy.context.object
|
object = bpy.context.object
|
||||||
|
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
# print("propertyGroup", propertyGroup, propertyGroup.field_names)
|
# print("propertyGroup", propertyGroup, propertyGroup.field_names)
|
||||||
added_components.append(component_type)
|
added_components.append(component_type)
|
||||||
@ -231,7 +231,7 @@ def test_copy_paste_components(setup_data):
|
|||||||
object = context.object
|
object = context.object
|
||||||
|
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
|
|
||||||
setattr(propertyGroup, propertyGroup.field_names[0], 25.0)
|
setattr(propertyGroup, propertyGroup.field_names[0], 25.0)
|
||||||
@ -246,7 +246,7 @@ def test_copy_paste_components(setup_data):
|
|||||||
# change name
|
# change name
|
||||||
new_cube.name = "TargetCube"
|
new_cube.name = "TargetCube"
|
||||||
target_components_metadata = new_cube.components_meta.components
|
target_components_metadata = new_cube.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
|
|
||||||
# first check that there is no component currently
|
# first check that there is no component currently
|
||||||
assert component_meta == None
|
assert component_meta == None
|
||||||
@ -255,7 +255,7 @@ def test_copy_paste_components(setup_data):
|
|||||||
paste_component_operator()
|
paste_component_operator()
|
||||||
|
|
||||||
target_components_metadata = new_cube.components_meta.components
|
target_components_metadata = new_cube.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
|
|
||||||
# now after pasting to the new object, it should have component meta
|
# now after pasting to the new object, it should have component meta
|
||||||
assert component_meta != None
|
assert component_meta != None
|
||||||
|
@ -16,7 +16,7 @@ def test_blend(setup_data):
|
|||||||
object = bpy.context.object
|
object = bpy.context.object
|
||||||
|
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ from .setup_data import setup_data
|
|||||||
# small helpers
|
# small helpers
|
||||||
def get_component_metadata(object, component_name):
|
def get_component_metadata(object, component_name):
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == component_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == component_name, target_components_metadata), None)
|
||||||
return component_meta
|
return component_meta
|
||||||
|
|
||||||
def get_component_propGroup(registry, component_name, component_meta):
|
def get_component_propGroup(registry, component_name, component_meta):
|
||||||
|
@ -19,7 +19,7 @@ def test_shuffler(setup_data):
|
|||||||
|
|
||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
|
|
||||||
definition = type_infos[component_type]
|
definition = type_infos[component_type]
|
||||||
@ -38,7 +38,7 @@ def test_shuffler(setup_data):
|
|||||||
|
|
||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
|
|
||||||
definition = type_infos[component_type]
|
definition = type_infos[component_type]
|
||||||
@ -57,7 +57,7 @@ def test_shuffler(setup_data):
|
|||||||
|
|
||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
|
|
||||||
definition = type_infos[component_type]
|
definition = type_infos[component_type]
|
||||||
@ -75,7 +75,7 @@ def test_shuffler(setup_data):
|
|||||||
|
|
||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
|
|
||||||
definition = type_infos[component_type]
|
definition = type_infos[component_type]
|
||||||
@ -95,7 +95,7 @@ def test_shuffler(setup_data):
|
|||||||
|
|
||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
|
|
||||||
definition = type_infos[component_type]
|
definition = type_infos[component_type]
|
||||||
@ -113,7 +113,7 @@ def test_shuffler(setup_data):
|
|||||||
|
|
||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
|
|
||||||
definition = type_infos[component_type]
|
definition = type_infos[component_type]
|
||||||
@ -130,7 +130,7 @@ def test_shuffler(setup_data):
|
|||||||
|
|
||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
|
|
||||||
definition = type_infos[component_type]
|
definition = type_infos[component_type]
|
||||||
@ -148,7 +148,7 @@ def test_shuffler(setup_data):
|
|||||||
|
|
||||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||||
target_components_metadata = object.components_meta.components
|
target_components_metadata = object.components_meta.components
|
||||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||||
|
|
||||||
definition = type_infos[component_type]
|
definition = type_infos[component_type]
|
||||||
|
@ -5,9 +5,6 @@ from ..helpers.helpers_scenes import (get_scenes, )
|
|||||||
# IF collection_instances_combine_mode is not 'split' check for each scene if any object in changes_per_scene has an instance in the scene
|
# IF collection_instances_combine_mode is not 'split' check for each scene if any object in changes_per_scene has an instance in the scene
|
||||||
def changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, collection_instances_combine_mode):
|
def changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, collection_instances_combine_mode):
|
||||||
# Embed / EmbedExternal
|
# Embed / EmbedExternal
|
||||||
"""if collection_instances_combine_mode == "Split": # 1 => Embed
|
|
||||||
return False"""
|
|
||||||
|
|
||||||
blueprints_from_objects = blueprints_data.blueprints_from_objects
|
blueprints_from_objects = blueprints_data.blueprints_from_objects
|
||||||
|
|
||||||
blueprint_instances_in_scene = blueprints_data.blueprint_instances_per_main_scene.get(scene_name, None)
|
blueprint_instances_in_scene = blueprints_data.blueprint_instances_per_main_scene.get(scene_name, None)
|
||||||
@ -34,7 +31,6 @@ def changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, coll
|
|||||||
# changes => list of changed objects (regardless of wether they have been changed in main scene or in lib scene)
|
# changes => list of changed objects (regardless of wether they have been changed in main scene or in lib scene)
|
||||||
# wich of those objects are blueprint instances
|
# wich of those objects are blueprint instances
|
||||||
# we need a list of changed objects that are blueprint instances
|
# we need a list of changed objects that are blueprint instances
|
||||||
|
|
||||||
return level_needs_export
|
return level_needs_export
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -178,10 +178,10 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
|
|||||||
# if there were no setting before, it is new, we need export
|
# if there were no setting before, it is new, we need export
|
||||||
changed = False
|
changed = False
|
||||||
if previous_auto_settings == None:
|
if previous_auto_settings == None:
|
||||||
print("previous settings missing, exporting")
|
#print("previous settings missing, exporting")
|
||||||
changed = True
|
changed = True
|
||||||
elif previous_gltf_settings == None:
|
elif previous_gltf_settings == None:
|
||||||
print("previous gltf settings missing, exporting")
|
#print("previous gltf settings missing, exporting")
|
||||||
previous_gltf_settings = bpy.data.texts.new(".gltf_auto_export_gltf_settings_previous")
|
previous_gltf_settings = bpy.data.texts.new(".gltf_auto_export_gltf_settings_previous")
|
||||||
previous_gltf_settings.write(json.dumps({}))
|
previous_gltf_settings.write(json.dumps({}))
|
||||||
if current_gltf_settings == None:
|
if current_gltf_settings == None:
|
||||||
@ -194,18 +194,17 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
|
|||||||
auto_settings_changed = sorted(json.loads(previous_auto_settings.as_string()).items()) != sorted(json.loads(current_auto_settings.as_string()).items()) if current_auto_settings != None else False
|
auto_settings_changed = sorted(json.loads(previous_auto_settings.as_string()).items()) != sorted(json.loads(current_auto_settings.as_string()).items()) if current_auto_settings != None else False
|
||||||
gltf_settings_changed = sorted(json.loads(previous_gltf_settings.as_string()).items()) != sorted(json.loads(current_gltf_settings.as_string()).items()) if current_gltf_settings != None else False
|
gltf_settings_changed = sorted(json.loads(previous_gltf_settings.as_string()).items()) != sorted(json.loads(current_gltf_settings.as_string()).items()) if current_gltf_settings != None else False
|
||||||
|
|
||||||
print("auto settings previous", sorted(json.loads(previous_auto_settings.as_string()).items()))
|
"""print("auto settings previous", sorted(json.loads(previous_auto_settings.as_string()).items()))
|
||||||
print("auto settings current", sorted(json.loads(current_auto_settings.as_string()).items()))
|
print("auto settings current", sorted(json.loads(current_auto_settings.as_string()).items()))
|
||||||
print("auto_settings_changed", auto_settings_changed)
|
print("auto_settings_changed", auto_settings_changed)
|
||||||
|
|
||||||
print("gltf settings previous", sorted(json.loads(previous_gltf_settings.as_string()).items()))
|
print("gltf settings previous", sorted(json.loads(previous_gltf_settings.as_string()).items()))
|
||||||
print("gltf settings current", sorted(json.loads(current_gltf_settings.as_string()).items()))
|
print("gltf settings current", sorted(json.loads(current_gltf_settings.as_string()).items()))
|
||||||
print("gltf_settings_changed", gltf_settings_changed)
|
print("gltf_settings_changed", gltf_settings_changed)"""
|
||||||
|
|
||||||
changed = auto_settings_changed or gltf_settings_changed
|
changed = auto_settings_changed or gltf_settings_changed
|
||||||
# now write the current settings to the "previous settings"
|
# now write the current settings to the "previous settings"
|
||||||
if current_auto_settings != None:
|
if current_auto_settings != None:
|
||||||
print("writing settings")
|
|
||||||
previous_auto_settings = bpy.data.texts[".gltf_auto_export_settings_previous"] if ".gltf_auto_export_settings_previous" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings_previous")
|
previous_auto_settings = bpy.data.texts[".gltf_auto_export_settings_previous"] if ".gltf_auto_export_settings_previous" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings_previous")
|
||||||
previous_auto_settings.clear()
|
previous_auto_settings.clear()
|
||||||
previous_auto_settings.write(current_auto_settings.as_string()) # TODO : check if this is always valid
|
previous_auto_settings.write(current_auto_settings.as_string()) # TODO : check if this is always valid
|
||||||
@ -294,15 +293,9 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
|
|||||||
changes_per_scene[scene][object_name] = bpy.data.objects[object_name]
|
changes_per_scene[scene][object_name] = bpy.data.objects[object_name]
|
||||||
bubble_up_changes(bpy.data.objects[object_name], changes_per_scene[scene])
|
bubble_up_changes(bpy.data.objects[object_name], changes_per_scene[scene])
|
||||||
# now bubble up for instances & parents
|
# now bubble up for instances & parents
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
previous_stored.clear()
|
previous_stored.clear()
|
||||||
previous_stored.write(json.dumps(current))
|
previous_stored.write(json.dumps(current))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print("changes per scene alternative", changes_per_scene)
|
print("changes per scene alternative", changes_per_scene)
|
||||||
return changes_per_scene
|
return changes_per_scene
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user