Skip to content

Commit 6a1e8be

Browse files
bnbailey-pslsmbanx
andcommitted
[1.3.52] 2025-10-02
- Fixed a bug in the maize phytomer creation function where the scale could be left uninitialized, leading to undefined behavior. - Removed a duplicate code block in the tomato phytomer creation function. - Added new apple fruiting wall plant model (`apple_fruitingwall`) - Fixed fruit set probability calculation when skipping flower stages - now applies compound probability (flower bud break × fruit set) when jumping directly from BUD_ACTIVE to BUD_FRUITING - Fixed child shoot insertion angle calculation to properly account for parent petiole position using angular offset - Updated pistachio tree parameters for improved canopy structure - Fixed vector bounds checking for write flags (`write_depth`, `write_norm_depth`, `write_segmentation_mask`) - Fixed initialization of write flag vectors in `xmlGetValues()` - vectors are now properly sized when no XML values are present - Fixed initialization of write flag vectors when adding new rigs via `addRig()` - Updated bounding box writing calls to include `classes.txt` filename parameter matching new Radiation API - Merged in many project builder bug fixes and updates Co-authored-by: Sean Banks <[email protected]>
1 parent ae94725 commit 6a1e8be

File tree

11 files changed

+3861
-2954
lines changed

11 files changed

+3861
-2954
lines changed

doc/CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# Changelog
22

3+
# [1.3.52] 2025-10-02
4+
5+
## Plant Architecture
6+
- Fixed a bug in the maize phytomer creation function where the scale could be left uninitialized, leading to undefined behavior.
7+
- Removed a duplicate code block in the tomato phytomer creation function.
8+
- Added new apple fruiting wall plant model (`apple_fruitingwall`)
9+
- Fixed fruit set probability calculation when skipping flower stages - now applies compound probability (flower bud break × fruit set) when jumping directly from BUD_ACTIVE to BUD_FRUITING
10+
- Fixed child shoot insertion angle calculation to properly account for parent petiole position using angular offset
11+
- Updated pistachio tree parameters for improved canopy structure
12+
13+
## Project Builder
14+
- Fixed vector bounds checking for write flags (`write_depth`, `write_norm_depth`, `write_segmentation_mask`)
15+
- Fixed initialization of write flag vectors in `xmlGetValues()` - vectors are now properly sized when no XML values are present
16+
- Fixed initialization of write flag vectors when adding new rigs via `addRig()`
17+
- Updated bounding box writing calls to include `classes.txt` filename parameter matching new Radiation API
18+
- Merged in many project builder bug fixes and updates
19+
320
# [1.3.51] 2025-09-25
421

522
- Added 'validation' page in documentation

doc/Validation.dox

Lines changed: 64 additions & 59 deletions
Large diffs are not rendered by default.
107 KB
Loading

plugins/plantarchitecture/include/PlantArchitecture.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2883,6 +2883,10 @@ class PlantArchitecture {
28832883

28842884
uint buildAppleTree(const helios::vec3 &base_position);
28852885

2886+
void initializeAppleFruitingWallShoots();
2887+
2888+
uint buildAppleFruitingWall(const helios::vec3 &base_position);
2889+
28862890
void initializeAsparagusShoots();
28872891

28882892
uint buildAsparagusPlant(const helios::vec3 &base_position);

plugins/plantarchitecture/src/Assets.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ uint MaizeEarPrototype(helios::Context *context_ptr, uint subdivisions) {
565565
void MaizePhytomerCreationFunction(std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age) {
566566

567567
// set leaf scale based on position along the shoot
568-
float scale;
568+
float scale = 1.f;
569569
if (shoot_node_index <= 5) {
570570
scale = fmin(1.f, 0.7 + 0.3 * float(shoot_node_index) / 5.f);
571571
phytomer->scaleInternodeMaxLength(scale);
@@ -887,10 +887,6 @@ void TomatoPhytomerCreationFunction(std::shared_ptr<Phytomer> phytomer, uint sho
887887
phytomer->setFloralBudState(BUD_DEAD);
888888
phytomer->setVegetativeBudState(BUD_DEAD);
889889
}
890-
if (phytomer->rank > 1) {
891-
phytomer->setFloralBudState(BUD_DEAD);
892-
phytomer->setVegetativeBudState(BUD_DEAD);
893-
}
894890

895891
// set leaf and internode scale based on position along the shoot
896892
float leaf_scale = fmin(1.f, 0.5 + 0.5 * plant_age / 10.f);

plugins/plantarchitecture/src/PlantArchitecture.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4598,13 +4598,19 @@ void PlantArchitecture::advanceTime(const std::vector<uint> &plantIDs, float tim
45984598
if (shoot->shoot_parameters.phytomer_parameters.inflorescence.fruit_prototype_function != nullptr) {
45994599
if ((fbud.state == BUD_FLOWER_OPEN && plant_instance.dd_to_fruit_set >= 0.f) ||
46004600
// flower opened and fruit set is enabled
4601-
(fbud.state == BUD_ACTIVE && plant_instance.dd_to_flower_initiation < 0.f && plant_instance.dd_to_flower_opening < 0.f && plant_instance.dd_to_fruit_set >= 0.f) ||
4602-
// jumped straight to fruit set with no flowering
4601+
(fbud.state == BUD_ACTIVE && plant_instance.dd_to_flower_initiation < 0.f && (plant_instance.dd_to_flower_opening < 0.f || shoot->shoot_parameters.phytomer_parameters.inflorescence.flower_prototype_function == nullptr) && plant_instance.dd_to_fruit_set >= 0.f) ||
4602+
// jumped straight to fruit set with no flowering (either flower opening disabled OR no flower prototype defined)
46034603
(fbud.state == BUD_FLOWER_CLOSED && plant_instance.dd_to_flower_opening < 0.f && plant_instance.dd_to_fruit_set >= 0.f)) {
46044604
// jumped from closed flower to fruit set with no flower opening
46054605
if (fbud.time_counter >= plant_instance.dd_to_fruit_set) {
46064606
fbud.time_counter = 0;
4607-
if (context_ptr->randu() < shoot->shoot_parameters.fruit_set_probability.val()) {
4607+
// When skipping flowering entirely (BUD_ACTIVE -> BUD_FRUITING), apply compound probability
4608+
float fruit_set_prob = shoot->shoot_parameters.fruit_set_probability.val();
4609+
if (fbud.state == BUD_ACTIVE) {
4610+
// Apply compound probability: flower_bud_break_probability * fruit_set_probability
4611+
fruit_set_prob *= shoot->shoot_parameters.flower_bud_break_probability.val();
4612+
}
4613+
if (context_ptr->randu() < fruit_set_prob) {
46084614
phytomer->setFloralBudState(BUD_FRUITING, fbud);
46094615
} else {
46104616
phytomer->setFloralBudState(BUD_DEAD, fbud);
@@ -4697,7 +4703,9 @@ void PlantArchitecture::advanceTime(const std::vector<uint> &plantIDs, float tim
46974703
// new_shoot_parameters->insertion_angle_tip.resample();
46984704
// }
46994705
float insertion_angle_adjustment = fmin(shoot->shoot_parameters.insertion_angle_tip.val() + shoot->shoot_parameters.insertion_angle_decay_rate.val() * float(parent_node_count - phytomer->shoot_index.x - 1), 90.f);
4700-
AxisRotation base_rotation = make_AxisRotation(deg2rad(insertion_angle_adjustment), deg2rad(new_shoot_parameters->base_yaw.val()), deg2rad(new_shoot_parameters->base_roll.val()));
4706+
// Calculate angular offset for child shoot based on parent petiole position
4707+
float budrot = float(parent_petiole_index) * 2.f * PI_F / float(phytomer->axillary_vegetative_buds.size());
4708+
AxisRotation base_rotation = make_AxisRotation(deg2rad(insertion_angle_adjustment), deg2rad(new_shoot_parameters->base_yaw.val()) + budrot, deg2rad(new_shoot_parameters->base_roll.val()));
47014709
new_shoot_parameters->base_yaw.resample();
47024710
if (shoot->shoot_parameters.insertion_angle_decay_rate.val() == 0) {
47034711
shoot->shoot_parameters.insertion_angle_tip.resample();

0 commit comments

Comments
 (0)