diff --git a/plugins/projectbuilder/include/ProjectBuilder.h b/plugins/projectbuilder/include/ProjectBuilder.h index 2a1035cfa..ab5260490 100644 --- a/plugins/projectbuilder/include/ProjectBuilder.h +++ b/plugins/projectbuilder/include/ProjectBuilder.h @@ -187,10 +187,11 @@ struct distribution { }; //! Band group struct -struct bandGroup { - std::vector bands; - bool grayscale; - bool norm; +struct bandGroup{ + std::vector bands; + bool grayscale; + bool norm; + bool hdr; }; //! Canopy struct @@ -211,8 +212,9 @@ struct canopy { }; //! Object struct -struct object { +struct object{ int index; + uint objID; std::string name; std::string file; std::string data_group; @@ -231,15 +233,21 @@ struct object { //! Rig struct struct rig { + int num_images; std::string label; std::vector position_noise; + std::vector lookat_noise; helios::RGBcolor color; helios::vec3 position; helios::vec3 lookat; + std::vector camera_positions; + std::vector camera_lookats; + std::vector keypoint_frames; std::set camera_labels; std::set light_labels; bool write_depth; bool write_norm_depth; + bool write_segmentation_mask; }; bool parse_distribution(const std::string &input_string, distribution &converted_distribution); @@ -268,983 +276,1102 @@ distribution createDistribution(const std::weibull_distribution &dist, bo class ProjectBuilder { private: - //! XML Document - pugi::xml_document xmldoc; + //! XML Document + pugi::xml_document xmldoc; - //! XML Document path - std::string xml_input_file = "plugins/projectbuilder/inputs/inputs.xml"; + //! XML Document path + std::string xml_input_file = "plugins/projectbuilder/inputs/inputs.xml"; - //! User input - bool user_input; + //! User input + bool user_input; - //! Light coordinates type (false = Cartesian, true = Spherical) - bool light_coord_type = false; + //! Light coordinates type (false = Cartesian, true = Spherical) + bool light_coord_type = false; - //! If true, the context has been updated since the last time the visualizer has been updated - bool is_dirty = false; + //! If true, the context has been updated since the last time the visualizer has been updated + bool is_dirty = false; - //! If true, the project has been built and `visualize()` can be run. - bool built = false; + //! If true, the project has been built and `visualize()` can be run. + bool built = false; - //! Absorbed PAR value - float PAR_absorbed; + //! Absorbed PAR value + float PAR_absorbed; - //! Absorbed NIR value - float NIR_absorbed; + //! Absorbed NIR value + float NIR_absorbed; - //! Absorbed LW value - float LW_absorbed; + //! Absorbed LW value + float LW_absorbed; - //! Turbidity - float turbidity; + //! Turbidity + float turbidity; - //! Diffuse extinction coefficient - float diffuse_extinction_coeff = 0.1; + //! Diffuse extinction coefficient + float diffuse_extinction_coeff = 0.1; - //! Enforce periodic boundary x - bool enforce_periodic_boundary_x = true; + //! Enforce periodic boundary x + bool enforce_periodic_boundary_x = true; - //! Enforce periodic boundary y - bool enforce_periodic_boundary_y = true; + //! Enforce periodic boundary y + bool enforce_periodic_boundary_y = true; - //! Sun ID - uint sun_ID; + //! Sun ID + uint sun_ID; - //! Band Labels - std::vector bandlabels; + //! Band Labels + std::vector bandlabels; - //! Band group names - std::set band_group_names; + //! Band group names + std::set band_group_names; - //! Band groups lookup map - std::map band_group_lookup; + //! Band groups lookup map + std::map band_group_lookup; - //! Current band group - std::string current_band_group; + //! Current band group + std::string current_band_group; - //! Band Labels set - std::set bandlabels_set; + //! Band Labels set + std::set bandlabels_set; - //! Set of band labels with emissivity enabled - std::set bandlabels_set_emissivity; + //! Set of band labels with emissivity enabled + std::set bandlabels_set_emissivity; - //! Set of band labels with wavelength range set - std::set bandlabels_set_wavelength; + //! Set of band labels with wavelength range set + std::set bandlabels_set_wavelength; - //! Direct ray count map keyed by band label that returns the direct ray count for the specified band. - std::map direct_ray_count_dict; + //! Direct ray count map keyed by band label that returns the direct ray count for the specified band. + std::map direct_ray_count_dict; - //! Diffuse ray count map keyed by band label that returns the diffuse ray count for the specified band. - std::map diffuse_ray_count_dict; + //! Diffuse ray count map keyed by band label that returns the diffuse ray count for the specified band. + std::map diffuse_ray_count_dict; - //! Scattering depth map keyed by band label that returns the scattering depth for the specified band. - std::map scattering_depth_dict; + //! Scattering depth map keyed by band label that returns the scattering depth for the specified band. + std::map scattering_depth_dict; - //! New band label - std::string new_band_label; + //! New band label + std::string new_band_label; - //! New band wavelength min - float wavelength_min = 400.0f; + //! New band wavelength min + float wavelength_min = 400.0f; - //! New band wavelength max - float wavelength_max = 700.0f; + //! New band wavelength max + float wavelength_max = 700.0f; - //! New band enable wavelength - bool enable_wavelength; + //! New band enable wavelength + bool enable_wavelength; - //! New band enable emission - bool enable_emission; + //! New band enable emission + bool enable_emission; - //! Ground UUIDs - std::vector ground_UUIDs; + //! Ground UUIDs + std::vector ground_UUIDs; - //! Ground object ID - uint ground_objID; + //! Ground object ID + uint ground_objID; - //! Leaf UUIDs - std::vector leaf_UUIDs; + //! Leaf UUIDs + std::vector leaf_UUIDs; - //! Petiolule UUIDs - std::vector petiolule_UUIDs; + //! Petiolule UUIDs + std::vector petiolule_UUIDs; - //! Petiole UUIDs - std::vector petiole_UUIDs; + //! Petiole UUIDs + std::vector petiole_UUIDs; - //! Internode UUIDs - std::vector internode_UUIDs; + //! Internode UUIDs + std::vector internode_UUIDs; - //! Peduncle UUIDs - std::vector peduncle_UUIDs; + //! Peduncle UUIDs + std::vector peduncle_UUIDs; - //! Petal UUIDs - std::vector petal_UUIDs; + //! Petal UUIDs + std::vector petal_UUIDs; - //! Flower UUIDs - std::vector flower_UUIDs; + //! Flower UUIDs + std::vector flower_UUIDs; - //! Sepal UUIDs - std::vector sepal_UUIDs; + //! Sepal UUIDs + std::vector sepal_UUIDs; - //! Pedicel UUIDs - std::vector pedicel_UUIDs; + //! Pedicel UUIDs + std::vector pedicel_UUIDs; - //! Fruit UUIDs - std::vector fruit_UUIDs; + //! Fruit UUIDs + std::vector fruit_UUIDs; - //! Primitive names vector - std::vector primitive_names = {"All", "ground", "leaf", "petiolule", "petiole", "internode", "peduncle", "petal", "pedicel", "fruit"}; + //! Primitive names vector + std::vector primitive_names = {"All", "ground", "leaf", "petiolule", "petiole", "internode", "peduncle", "petal", "pedicel", "fruit"}; - //! Bounding boxes - std::map bounding_boxes = { - {"plantID", false}, {"leafID", false}, {"peduncleID", false}, {"closedflowerID", false}, {"openflowerID", false}, {"fruitID", false}, {"rank", false}, {"age", false}, {"carbohydrate_concentration", false}}; + //! Bounding boxes + std::map bounding_boxes = {{"plantID", false}, {"leafID", false}, {"peduncleID", false}, + {"closedflowerID", false}, {"openflowerID", false}, {"fruitID", false}, + {"rank", false}, {"age", false}, {"carbohydrate_concentration", false}}; - //! Bounding boxes map - std::map bounding_boxes_map; + //! Default bounding box objects + std::set bounding_boxes_default = {"plantID", "leafID", "peduncleID", "closedflowerID", "openflowerID", "fruitID", "rank"}; - //! Primitive names set - std::set primitive_names_set = {"All", "ground", "leaf", "petiolule", "petiole", "internode", "peduncle", "petal", "pedicel", "fruit"}; + //! Bounding box objects associated with a primitive type + std::set bounding_boxes_primitive; - //! Map keyed by primitive names that returns the address of a vector of UUIDs corresponding to the primitive name - std::map *> primitive_addresses; + //! Bounding box objects associated with an object type + std::set bounding_boxes_object; - //! Map keyed by primitive names that returns a vector of UUIDs corresponding to the primitive name - std::map> primitive_UUIDs; + //! Bounding boxes map + std::map bounding_boxes_map; - //! Map keyed by data group name that returns a map of primitive UUIDs for each primitive name in the data group - std::map>> primitive_UUIDs_dict; + //! Primitive names set + std::set primitive_names_set = {"All", "ground", "leaf", "petiolule", "petiole", "internode", "peduncle", "petal", "pedicel", "fruit"}; - //! Map keyed by primitive names that returns a bool representing whether the primitive has continuous spectra (reflectivity, transmissivity, emissivity) - std::map> primitive_continuous; + //! Map keyed by primitive names that returns the address of a vector of UUIDs corresponding to the primitive name + std::map *> primitive_addresses; - //! Map keyed by primitive names that returns a bool representing whether the primitive has continuous spectra (reflectivity, transmissivity, emissivity) - std::map>> primitive_continuous_dict; + //! Map keyed by primitive names that returns a vector of UUIDs corresponding to the primitive name + std::map> primitive_UUIDs; - //! Map keyed by primitive names that returns spectra (reflectivity, transmissivity, emissivity) - std::map> primitive_spectra; + //! Map keyed by data group name that returns a map of primitive UUIDs for each primitive name in the data group + std::map>> primitive_UUIDs_dict; - //! Map keyed by data group that returns a map of primitive spectra information for that data group - std::map>> primitive_spectra_dict; + //! Map keyed by primitive names that returns a bool representing whether the primitive has continuous spectra (reflectivity, transmissivity, emissivity) + std::map> primitive_continuous; - //! Primitive values map: band -> primitive type -> {reflectivity, transmissivity, emissivity} - std::map>> primitive_values; + //! Map keyed by primitive names that returns a bool representing whether the primitive has continuous spectra (reflectivity, transmissivity, emissivity) + std::map>> primitive_continuous_dict; - //! Primitive values map: band -> primitive type -> {reflectivity, transmissivity, emissivity} - std::map>>> primitive_values_dict; + //! Map keyed by primitive names that returns spectra (reflectivity, transmissivity, emissivity) + std::map> primitive_spectra; - //! Set of data group names - std::set data_groups_set = {"All"}; + //! Map keyed by data group that returns a map of primitive spectra information for that data group + std::map>> primitive_spectra_dict; - //! Ground area - float ground_area; + //! Primitive values map: band -> primitive type -> {reflectivity, transmissivity, emissivity} + std::map>> primitive_values; - //! Timeseries variables - std::vector timeseries_variables; + //! Primitive values map: band -> primitive type -> {reflectivity, transmissivity, emissivity} + std::map>>> primitive_values_dict; - //! Air temperature - float air_temperature = 300.f; + //! Set of data group names + std::set data_groups_set = {"All"}; - //! Air humidity - float air_humidity = 0.5f; + std::vector data_groups = {"All"}; - //! Sun direction vector - helios::vec3 sun_dir_vec; + //! Ground area + float ground_area; - //! R PAR dir - float R_PAR_dir; + //! Timeseries variables + std::vector timeseries_variables; - //! R NIR dir - float R_NIR_dir; + //! Air temperature + float air_temperature = 300.f; - //! fdiff - float fdiff; + //! Air humidity + float air_humidity = 0.5f; - //! XML Error String - std::string xml_error_string; + //! Sun direction vector + helios::vec3 sun_dir_vec; - //! Rig labels - std::vector rig_labels; + //! R PAR dir + float R_PAR_dir; - //! Rig position noise - std::vector> rig_position_noise; + //! R NIR dir + float R_NIR_dir; - //! Rig lookat noise - std::vector> rig_lookat_noise; + //! fdiff + float fdiff; - //! Rig colors - std::vector rig_colors; + //! XML Error String + std::string xml_error_string; - //! Camera positions - std::vector camera_positions; + rig default_rig{1, "default_rig", {}, {}, helios::RGBcolor(1, 0, 0), + helios::vec3(0, 0, 1), helios::vec3(0, 0, 0), {helios::vec3(0, 0, 1)}, {helios::vec3(0, 0, 0)}, + {1}, {}, {}, false, false, false}; - //! Camera lookats - std::vector camera_lookats; + //! Rig labels + std::vector rig_labels; + + //! Rig position noise + std::vector> rig_position_noise; + + //! Rig lookat noise + std::vector> rig_lookat_noise; + + //! Rig colors + std::vector rig_colors; - //! Vector containing the *first* camera label of every rig. - std::vector camera_labels; + //! Camera positions + std::vector camera_positions; - //! Vector of camera resolutions - std::vector camera_resolutions; + //! Camera lookats + std::vector camera_lookats; - //! Vector of focal plane distances for every camera - std::vector focal_plane_distances; + //! Vector containing the *first* camera label of every rig. + std::vector camera_labels; - //! Vector of lens diameters for every camera - std::vector lens_diameters; + //! Vector of camera resolutions + std::vector camera_resolutions; - //! Vector of FOV aspect ratios for every camera - std::vector FOV_aspect_ratios; + //! Vector of focal plane distances for every camera + std::vector focal_plane_distances; - //! Vector of HFOVs for every camera - std::vector HFOVs; + //! Vector of lens diameters for every camera + std::vector lens_diameters; - //! Map keyed by rig name that returns rig index - std::map rig_dict; + //! Vector of FOV aspect ratios for every camera + std::vector FOV_aspect_ratios; - //! Rig labels - std::set rig_labels_set; + //! Vector of HFOVs for every camera + std::vector HFOVs; - //! Vector of bools representing whether to write depth images for each rig - std::vector write_depth; + //! Map keyed by rig name that returns rig index + std::map rig_dict; - //! Vector of bools representing whether to write norm depth images for each rig - std::vector write_norm_depth; + //! Map keyed by rig name that returns the corresponding rig struct. + std::map rig_dict_; - //! Rig position - helios::vec3 camera_position = {0, 0, 0}; + //! Rig labels + std::set rig_labels_set; - //! Vector of keypoint frames for every rig - std::vector> keypoint_frames; + //! Vector of bools representing whether to write depth images for each rig + std::vector write_depth; - //! Vector of rig positions for every rig - std::vector> camera_position_vec; + //! Vector of bools representing whether to write norm depth images for each rig + std::vector write_norm_depth; - //! Vector of rig lookat positions for every rig - std::vector> camera_lookat_vec; + //! Vector of bools representing whether to write segmentation masks for each rig + std::vector write_segmentation_mask; - //! Rig lookat - helios::vec3 camera_lookat = {0, 0, 0}; + //! Rig position + helios::vec3 camera_position = {0, 0, 0}; - //! Camera label - std::string camera_label = "RGB"; + //! Vector of keypoint frames for every rig + std::vector> keypoint_frames; - //! Number of images/frames - int num_images = 5; + //! Vector of rig positions for every rig + std::vector> camera_position_vec; - //! Number of images/frames per rig - std::vector num_images_vec; + //! Vector of rig lookat positions for every rig + std::vector> camera_lookat_vec; - //! Vector of camera names - std::vector camera_names; + //! Rig lookat + helios::vec3 camera_lookat = {0, 0, 0}; - //! Set of camera names - std::set camera_names_set; + //! Camera label + std::string camera_label = "RGB"; - //! Camera resolution - helios::int2 camera_resolution = {1024, 1024}; + //! Number of images/frames + int num_images = 5; - //! Focal plane distance - float focal_plane_distance = 0.4; + //! Number of images/frames per rig + std::vector num_images_vec; - //! Lens diameter - float lens_diameter = 0.02; + //! Vector of camera names + std::vector camera_names; - //! FOV aspect ratio - float FOV_aspect_ratio = 1.4; + //! Set of camera names + std::set camera_names_set; - //! HFOV - float HFOV = 50.0; + //! Camera resolution + helios::int2 camera_resolution = {1024, 1024}; - //! Dictionary keyed by camera name that returns camera index. - std::map camera_dict; + //! Focal plane distance + float focal_plane_distance = 0.4; - //! Set of camera labels for every rig - std::vector> rig_camera_labels; + //! Lens diameter + float lens_diameter = 0.02; - //! Vector of light names. - std::vector light_names; + //! FOV aspect ratio + float FOV_aspect_ratio = 1.4; - //! Set of light names. - std::set light_names_set; + //! HFOV + float HFOV = 50.0; - //! Vector of light types (e.g. sphere, rectangle, etc.). - std::vector light_types; + //! Dictionary keyed by camera name that returns camera index. + std::map camera_dict; - //! Vector of all possible light types. - // std::vector all_light_types = {"collimated", "sphere", "sunsphere", "rectangle", "disk"}; - std::vector all_light_types = {"sphere", "rectangle", "disk"}; + //! Set of camera labels for every rig + std::vector> rig_camera_labels; - //! Vector of light positions for each light. - std::vector light_direction_vec; + //! Vector of light names. + std::vector light_names; - //! Vector of light spherical directions for each light. - std::vector light_direction_sph_vec; + //! Set of light names. + std::set light_names_set; - //! Vector of rotations for each light. - std::vector light_rotation_vec; + //! Vector of light types (e.g. sphere, rectangle, etc.). + std::vector light_types; - //! Vector of sizes for each light. - std::vector light_size_vec; + //! Vector of all possible light types. + // std::vector all_light_types = {"collimated", "sphere", "sunsphere", "rectangle", "disk"}; + std::vector all_light_types = {"sphere", "rectangle", "disk"}; - //! Vector of sizes for each light. - std::vector light_radius_vec; + //! Vector of light positions for each light. + std::vector light_direction_vec; - //! Vector of source flux for each light. - std::vector light_flux_vec; + //! Vector of light spherical directions for each light. + std::vector light_direction_sph_vec; - //! Dictionary keyed by light name that returns light index (in light_names). - std::map light_dict; + //! Vector of rotations for each light. + std::vector light_rotation_vec; - //! Vector of sets of lights. The i-th set in the vector contains the light names of the i-th rig. - std::vector> rig_light_labels; + //! Vector of sizes for each light. + std::vector light_size_vec; - //! Dictionary containing arrow UUIDs for every arrow - std::map>> arrow_dict; + //! Vector of sizes for each light. + std::vector light_radius_vec; - //! Arrow count - int arrow_count = 0; + //! Vector of source flux for each light. + std::vector light_flux_vec; - //! Helios XML node - pugi::xml_node helios; + //! Dictionary keyed by light name that returns light index (in light_names). + std::map light_dict; - //! Enable coordinate axes - bool enable_coordinate_axes = true; + //! Vector of sets of lights. The i-th set in the vector contains the light names of the i-th rig. + std::vector> rig_light_labels; - //! Enable colorbar - bool enable_colorbar = false; + //! Dictionary containing arrow UUIDs for every arrow + std::map>> arrow_dict; - //! Latitude - float latitude = 38.55; + //! Arrow count + int arrow_count = 0; - //! Longitude - float longitude = 121.76; + //! Helios XML node + pugi::xml_node helios; - //! UTC offset - int UTC_offset = 8; + //! Enable coordinate axes + bool enable_coordinate_axes = true; - //! CSV weather file path - std::string csv_weather_file = "plugins/projectbuilder/inputs/weather_data.csv"; + //! Enable colorbar + bool enable_colorbar = false; - //! CIMIS weather file path - std::string cimis_weather_file; + //! Latitude + float latitude = 38.55; - //! If true, weather file is CSV file. Else, weather file is CIMIS file. - bool is_weather_file_csv = true; + //! Longitude + float longitude = 121.76; - //! Domain origin - helios::vec3 domain_origin = {0, 0, 0}; + //! UTC offset + int UTC_offset = 8; - //! Domain extent - helios::vec2 domain_extent = {10, 10}; + //! CSV weather file path + std::string csv_weather_file = "plugins/projectbuilder/inputs/weather_data.csv"; - //! Ground resolution - helios::int2 ground_resolution = {1, 1}; + //! CIMIS weather file path + std::string cimis_weather_file; - //! Ground texture file + //! If true, weather file is CSV file. Else, weather file is CIMIS file. + bool is_weather_file_csv = true; + + //! Domain origin + helios::vec3 domain_origin = {0, 0, 0}; + + //! Domain extent + helios::vec2 domain_extent = {10, 10}; + + //! Ground resolution + helios::int2 ground_resolution = {1, 1}; + + //! Ground texture file std::string ground_texture_file = "plugins/projectbuilder/inputs/dirt.jpg"; - //! Use ground texture file (0 = manually enter color, 1 = texture file, 2 = model file) - int ground_flag = 1; - - bool use_ground_texture = true; - - //! Ground color - float ground_color[3] = {0.0, 0.0, 0.0}; - - //! Ground model file - std::string ground_model_file; - - //! Vector of canopy labels - std::vector canopy_labels; - - //! Set of canopy labels - std::set canopy_labels_set; - - //! Vector of data labels for each canopy - std::vector canopy_data_groups; - - //! Canopy origin - helios::vec3 canopy_origin = {0, 0, 0}; - - //! Vector of canopy origins for every canopy - std::vector canopy_origins; - - //! Plant count - helios::int2 plant_count = {1, 1}; - - //! Vector of plant counts for every canopy - std::vector plant_counts; - - //! Plant spacing - helios::vec2 plant_spacing = {0.5, 0.5}; - - //! Vector of plant spacings for every canopy - std::vector plant_spacings; - - //! Vector of plant locations relative to the canopy origin for every canopy - std::vector> individual_plant_locations; - - //! Plant library name - std::string plant_library_name = "cowpea"; - - //! Long plant library name - std::string plant_library_name_verbose = "Cowpea (Vigna unguiculata)"; - - //! Vector of plant library names for every canopy - std::vector plant_library_names; - - //! Vector of long plant library names for every canopy - std::vector plant_library_names_verbose; - - //! All available plant types - std::set plant_types = {"almond", "apple", "bindweed", "butterlettuce", "cheeseweed", "bean", "cowpea", "easternredbud", "grapevine_VSP", "maize", - "olive", "pistachio", "puncturevine", "rice", "sorghum", "soybean", "sugarbeet", "tomato", "walnut", "wheat"}; - - //! Long names for each plant type - std::set plant_types_verbose = {"Almond Tree (Prunus dulcis)", "Apple Tree (Malus pumila)", - "Bindweed (Convolvulus arvensis)", "Butter Lettuce (Lactuca sativa)", - "Cheeseweed (Malva neglecta)", "Common Bean (Phaseolus vulgaris)", - "Cowpea (Vigna unguiculata)", "Eastern Redbud (Cercis canadensis)", - "Grapevine (Vitis vinifera)", "Maize (Zea mays)", - "Olive Tree (Olea europaea)", "Pistachio Tree (Pistachia vera)", - "Puncturevine (Tribulus terrestris)", "Rice (Oryza sativa)", - "Sorghum (Sorghum bicolor)", "Soybean (Glycine max)", - "Sugar Beet (Beta vulgaris)", "Tomato (Solanum lycopersicum)", - "Walnut Tree (Juglans regia)", "Wheat (Triticum aestivum)"}; - - //! Map keyed by long plant type names that returns the plant type string argument for the plant architecture library - std::map plant_type_lookup = {{"Almond Tree (Prunus dulcis)", "almond"}, - {"Apple Tree (Malus pumila)", "apple"}, - {"Bindweed (Convolvulus arvensis)", "bindweed"}, - {"Butter Lettuce (Lactuca sativa)", "butterlettuce"}, - {"Cheeseweed (Malva neglecta)", "cheeseweed"}, - {"Common Bean (Phaseolus vulgaris)", "bean"}, - {"Cowpea (Vigna unguiculata)", "cowpea"}, - {"Eastern Redbud (Cercis canadensis)", "easternredbud"}, - {"Grapevine (Vitis vinifera)", "grapevine_VSP"}, - {"Maize (Zea mays)", "maize"}, - {"Olive Tree (Olea europaea)", "olive"}, - {"Pistachio Tree (Pistachia vera)", "pistachio"}, - {"Puncturevine (Tribulus terrestris)", "puncturevine"}, - {"Rice (Oryza sativa)", "rice"}, - {"Sorghum (Sorghum bicolor)", "sorghum"}, - {"Soybean (Glycine max)", "soybean"}, - {"Sugar Beet (Beta vulgaris)", "sugarbeet"}, - {"Tomato (Solanum lycopersicum)", "tomato"}, - {"Walnut Tree (Juglans regia)", "walnut"}, - {"Wheat (Triticum aestivum)", "wheat"}}; + //! Use ground texture file (0 = manually enter color, 1 = texture file, 2 = model file) + int ground_flag = 1; + + bool use_ground_texture = true; + + //! Ground color + float ground_color[3] = {0.0, 0.0, 0.0}; + + //! Ground model file + std::string ground_model_file; + + //! Vector of canopy labels + std::vector canopy_labels; + + //! Set of canopy labels + std::set canopy_labels_set; + + //! Vector of data labels for each canopy + std::vector canopy_data_groups; + + //! Canopy origin + helios::vec3 canopy_origin = {0, 0, 0}; + + //! Vector of canopy origins for every canopy + std::vector canopy_origins; + + //! Plant count + helios::int2 plant_count = {1, 1}; + + //! Vector of plant counts for every canopy + std::vector plant_counts; + + //! Plant spacing + helios::vec2 plant_spacing = {0.5, 0.5}; + + //! Vector of plant spacings for every canopy + std::vector plant_spacings; + + //! Vector of plant locations relative to the canopy origin for every canopy + std::vector> individual_plant_locations; + + //! Plant library name + std::string plant_library_name = "cowpea"; + + //! Long plant library name + std::string plant_library_name_verbose = "Cowpea (Vigna unguiculata)"; + + //! Vector of plant library names for every canopy + std::vector plant_library_names; + + //! Vector of long plant library names for every canopy + std::vector plant_library_names_verbose; + + //! All available plant types + std::set plant_types = {"almond", "apple", "bindweed", "butterlettuce", "cheeseweed", "bean", "cowpea", "easternredbud", "grapevine_VSP", "maize", + "olive", "pistachio", "puncturevine", "rice", "sorghum", "soybean", "sugarbeet", "tomato", "walnut", "wheat"}; + + //! Long names for each plant type + std::set plant_types_verbose = {"Almond Tree (Prunus dulcis)", "Apple Tree (Malus pumila)", + "Bindweed (Convolvulus arvensis)", "Butter Lettuce (Lactuca sativa)", + "Cheeseweed (Malva neglecta)", "Common Bean (Phaseolus vulgaris)", + "Cowpea (Vigna unguiculata)", "Eastern Redbud (Cercis canadensis)", + "Grapevine (Vitis vinifera)", "Maize (Zea mays)", + "Olive Tree (Olea europaea)", "Pistachio Tree (Pistachia vera)", + "Puncturevine (Tribulus terrestris)", "Rice (Oryza sativa)", + "Sorghum (Sorghum bicolor)", "Soybean (Glycine max)", + "Sugar Beet (Beta vulgaris)", "Tomato (Solanum lycopersicum)", + "Walnut Tree (Juglans regia)", "Wheat (Triticum aestivum)"}; + + //! Map keyed by long plant type names that returns the plant type string argument for the plant architecture library + std::map plant_type_lookup = {{"Almond Tree (Prunus dulcis)", "almond"}, + {"Apple Tree (Malus pumila)", "apple"}, + {"Bindweed (Convolvulus arvensis)", "bindweed"}, + {"Butter Lettuce (Lactuca sativa)", "butterlettuce"}, + {"Cheeseweed (Malva neglecta)", "cheeseweed"}, + {"Common Bean (Phaseolus vulgaris)", "bean"}, + {"Cowpea (Vigna unguiculata)", "cowpea"}, + {"Eastern Redbud (Cercis canadensis)", "easternredbud"}, + {"Grapevine (Vitis vinifera)", "grapevine_VSP"}, + {"Maize (Zea mays)", "maize"}, + {"Olive Tree (Olea europaea)", "olive"}, + {"Pistachio Tree (Pistachia vera)", "pistachio"}, + {"Puncturevine (Tribulus terrestris)", "puncturevine"}, + {"Rice (Oryza sativa)", "rice"}, + {"Sorghum (Sorghum bicolor)", "sorghum"}, + {"Soybean (Glycine max)", "soybean"}, + {"Sugar Beet (Beta vulgaris)", "sugarbeet"}, + {"Tomato (Solanum lycopersicum)", "tomato"}, + {"Walnut Tree (Juglans regia)", "walnut"}, + {"Wheat (Triticum aestivum)", "wheat"}}; - //! Map keyed by plant type string argument that returns the corresponding long plant name - std::map plant_type_verbose_lookup = {{"almond", "Almond Tree (Prunus dulcis)"}, - {"apple", "Apple Tree (Malus pumila)"}, - {"bindweed", "Bindweed (Convolvulus arvensis)"}, - {"butterlettuce", "Butter Lettuce (Lactuca sativa)"}, - {"cheeseweed", "Cheeseweed (Malva neglecta)"}, - {"bean", "Common Bean (Phaseolus vulgaris)"}, - {"cowpea", "Cowpea (Vigna unguiculata)"}, - {"easternredbud", "Eastern Redbud (Cercis canadensis)"}, - {"grapevine_VSP", "Grapevine (Vitis vinifera)"}, - {"maize", "Maize (Zea mays)"}, - {"olive", "Olive Tree (Olea europaea)"}, - {"pistachio", "Pistachio Tree (Pistachia vera)"}, - {"puncturevine", "Puncturevine (Tribulus terrestris)"}, - {"rice", "Rice (Oryza sativa)"}, - {"sorghum", "Sorghum (Sorghum bicolor)"}, - {"soybean", "Soybean (Glycine max)"}, - {"sugarbeet", "Sugar Beet (Beta vulgaris)"}, - {"tomato", "Tomato (Solanum lycopersicum)"}, - {"walnut", "Walnut Tree (Juglans regia)"}, - {"wheat", "Wheat (Triticum aestivum)"}}; + //! Map keyed by plant type string argument that returns the corresponding long plant name + std::map plant_type_verbose_lookup = {{"almond", "Almond Tree (Prunus dulcis)"}, + {"apple", "Apple Tree (Malus pumila)"}, + {"bindweed", "Bindweed (Convolvulus arvensis)"}, + {"butterlettuce", "Butter Lettuce (Lactuca sativa)"}, + {"cheeseweed", "Cheeseweed (Malva neglecta)"}, + {"bean", "Common Bean (Phaseolus vulgaris)"}, + {"cowpea", "Cowpea (Vigna unguiculata)"}, + {"easternredbud", "Eastern Redbud (Cercis canadensis)"}, + {"grapevine_VSP", "Grapevine (Vitis vinifera)"}, + {"maize", "Maize (Zea mays)"}, + {"olive", "Olive Tree (Olea europaea)"}, + {"pistachio", "Pistachio Tree (Pistachia vera)"}, + {"puncturevine", "Puncturevine (Tribulus terrestris)"}, + {"rice", "Rice (Oryza sativa)"}, + {"sorghum", "Sorghum (Sorghum bicolor)"}, + {"soybean", "Soybean (Glycine max)"}, + {"sugarbeet", "Sugar Beet (Beta vulgaris)"}, + {"tomato", "Tomato (Solanum lycopersicum)"}, + {"walnut", "Walnut Tree (Juglans regia)"}, + {"wheat", "Wheat (Triticum aestivum)"}}; - //! Plant age - float plant_age = 0; + //! Plant age + float plant_age = 0; - //! Vector of plant ages for all canopies - std::vector plant_ages; + //! Vector of plant ages for all canopies + std::vector plant_ages; - //! Ground clipping height - float ground_clipping_height = 0; + //! Ground clipping height + float ground_clipping_height = 0; - //! Vector of ground clipping heights for all canopies - std::vector ground_clipping_heights; + //! Vector of ground clipping heights for all canopies + std::vector ground_clipping_heights; - //! Map of canopy name to canopy index - std::map canopy_labels_dict; + //! Map of canopy name to canopy index + std::map canopy_labels_dict; - //! Vector of canopy UUIDs for each canopy - std::vector> canopy_IDs; + //! Vector of canopy UUIDs for each canopy + std::vector> canopy_IDs; - //! Direct ray count - int direct_ray_count = 100; + //! Direct ray count + int direct_ray_count = 100; - //! Diffuse ray count - int diffuse_ray_count = 1000; + //! Diffuse ray count + int diffuse_ray_count = 1000; - //! Scattering depth - int scattering_depth = 2; + //! Scattering depth + int scattering_depth = 2; - //! Air turbidity - float air_turbidity = 0.05; + //! Air turbidity + float air_turbidity = 0.05; - //! Obj / Ply files - std::vector obj_files; + //! Obj / Ply files + std::vector obj_files; - //! Object UUIDs - std::vector> obj_UUIDs; + //! Object UUIDs + std::vector> obj_UUIDs; - //! Object names - std::vector obj_names; + //! Object names + std::vector obj_names; - //! Object names set - std::set obj_names_set; + //! Object names set + std::set obj_names_set; - //! Currently selected object - std::string current_obj; + //! Currently selected object + std::string current_obj; - //! Object names map keyed by object name returning object index (e.g. in obj_UUIDs) - std::map obj_names_dict; + //! Object names map keyed by object name returning object index (e.g. in obj_UUIDs) + std::map obj_names_dict; - //! Object positions - std::vector obj_positions; + //! Object positions + std::vector obj_positions; - //! Previous object positions - std::vector prev_obj_positions; + //! Previous object positions + std::vector prev_obj_positions; - //! Object orientations - std::vector obj_orientations; + //! Object orientations + std::vector obj_orientations; - //! Previous object orientations - std::vector prev_obj_orientations; + //! Previous object orientations + std::vector prev_obj_orientations; - //! Object data groups - std::vector obj_data_groups; + //! Object data groups + std::vector obj_data_groups; - //! Previous object scales - std::vector prev_obj_scales; + //! Previous object scales + std::vector prev_obj_scales; - //! Object scales - std::vector obj_scales; + //! Object scales + std::vector obj_scales; - //! Object colors - std::vector obj_colors; + //! Object colors + std::vector obj_colors; - //! XML spectral library files - std::set xml_library_files = {"plugins/radiation/spectral_data/leaf_surface_spectral_library.xml", "plugins/radiation/spectral_data/soil_surface_spectral_library.xml"}; + //! XML spectral library files + std::set xml_library_files = {"plugins/radiation/spectral_data/leaf_surface_spectral_library.xml", "plugins/radiation/spectral_data/soil_surface_spectral_library.xml"}; - //! Possible spectra vector from spectral library files - std::set possible_spectra; + //! Possible spectra vector from spectral library files + std::set possible_spectra; - //! Camera XML library files - std::set camera_xml_library_files = {"plugins/radiation/spectral_data/camera_spectral_library.xml"}; + //! Camera XML library files + std::set camera_xml_library_files = {"plugins/radiation/spectral_data/camera_spectral_library.xml"}; - //! Possible camera calibrations vector from camera library files - std::vector possible_camera_calibrations; + //! Possible camera calibrations vector from camera library files + std::vector possible_camera_calibrations; - //! Camera calibration selection for each camera. Each entry is a map keyed by band name that returns the camera calibration for that band. - std::vector> camera_calibrations; + //! Camera calibration selection for each camera. Each entry is a map keyed by band name that returns the camera calibration for that band. + std::vector> camera_calibrations; - //! Currently selected band for editing camera calibration - std::string current_calibration_band; + //! Currently selected band for editing camera calibration + std::string current_calibration_band; - //! Light XML library files - std::set light_xml_library_files = {"plugins/radiation/spectral_data/light_spectral_library.xml"}; + //! Light XML library files + std::set light_xml_library_files = {"plugins/radiation/spectral_data/light_spectral_library.xml"}; - //! Possible light spectra vector from light library files - std::vector possible_light_spectra; + //! Possible light spectra vector from light library files + std::vector possible_light_spectra; - //! Spectra selection for each light - std::vector light_spectra; + //! Spectra selection for each light + std::vector light_spectra; - //! Solar direct spectrum - std::string solar_direct_spectrum = "solar_spectrum_direct_ASTMG173"; + //! Solar direct spectrum + std::string solar_direct_spectrum = "solar_spectrum_direct_ASTMG173"; - //! Reflectivity (apply to all) - float reflectivity = 0.0; + //! Reflectivity (apply to all) + float reflectivity = 0.0; - //! Transmissivity (apply to all) - float transmissivity = 0.0; + //! Transmissivity (apply to all) + float transmissivity = 0.0; - //! Emissivity (apply to all) - float emissivity = 1.0; + //! Emissivity (apply to all) + float emissivity = 1.0; - //! Leaf reflectivity - float leaf_reflectivity = 0.0; + //! Leaf reflectivity + float leaf_reflectivity = 0.0; - //! Leaf transmissivity - float leaf_transmissivity = 0.0; + //! Leaf transmissivity + float leaf_transmissivity = 0.0; - //! Leaf emissivity - float leaf_emissivity = 0.0; + //! Leaf emissivity + float leaf_emissivity = 0.0; - //! Ground reflectivity - float ground_reflectivity = 0.0; + //! Ground reflectivity + float ground_reflectivity = 0.0; - //! Ground transmissivity - float ground_transmissivity = 0.0; + //! Ground transmissivity + float ground_transmissivity = 0.0; - //! Ground emissivity - float ground_emissivity = 1.0; + //! Ground emissivity + float ground_emissivity = 1.0; - //! Petiolule reflectivity - float petiolule_reflectivity = 0.0; + //! Petiolule reflectivity + float petiolule_reflectivity = 0.0; - //! Petiolule transmissivity - float petiolule_transmissivity = 0.0; + //! Petiolule transmissivity + float petiolule_transmissivity = 0.0; - //! Petiolule emissivity - float petiolule_emissivity = 0.0; + //! Petiolule emissivity + float petiolule_emissivity = 0.0; - //! Petiole reflectivity - float petiole_reflectivity = 0.0; + //! Petiole reflectivity + float petiole_reflectivity = 0.0; - //! Petiole transmissivity - float petiole_transmissivity = 0.0; + //! Petiole transmissivity + float petiole_transmissivity = 0.0; - //! Petiole emissivity - float petiole_emissivity = 0.0; + //! Petiole emissivity + float petiole_emissivity = 0.0; - //! Internode reflectivity - float internode_reflectivity = 0.0; + //! Internode reflectivity + float internode_reflectivity = 0.0; - //! Internode transmissivity - float internode_transmissivity = 0.0; + //! Internode transmissivity + float internode_transmissivity = 0.0; - //! Internode emissivity - float internode_emissivity = 0.0; + //! Internode emissivity + float internode_emissivity = 0.0; - //! Peduncle reflectivity - float peduncle_reflectivity = 0.0; + //! Peduncle reflectivity + float peduncle_reflectivity = 0.0; - //! Peduncle transmissivity - float peduncle_transmissivity = 0.0; + //! Peduncle transmissivity + float peduncle_transmissivity = 0.0; - //! Peduncle emissivity - float peduncle_emissivity = 0.0; + //! Peduncle emissivity + float peduncle_emissivity = 0.0; - //! Petal reflectivity - float petal_reflectivity = 0.0; + //! Petal reflectivity + float petal_reflectivity = 0.0; - //! Petal transmissivity - float petal_transmissivity = 0.0; + //! Petal transmissivity + float petal_transmissivity = 0.0; - //! Petal emissivity - float petal_emissivity = 0.0; + //! Petal emissivity + float petal_emissivity = 0.0; - //! Pedicel reflectivity - float pedicel_reflectivity = 0.0; + //! Pedicel reflectivity + float pedicel_reflectivity = 0.0; - //! Pedicel transmissivity - float pedicel_transmissivity = 0.0; + //! Pedicel transmissivity + float pedicel_transmissivity = 0.0; - //! Pedicel emissivity - float pedicel_emissivity = 0.0; + //! Pedicel emissivity + float pedicel_emissivity = 0.0; - //! Fruit reflectivity - float fruit_reflectivity = 0.0; + //! Fruit reflectivity + float fruit_reflectivity = 0.0; - //! Fruit transmissivity - float fruit_transmissivity = 0.0; + //! Fruit transmissivity + float fruit_transmissivity = 0.0; - //! Fruit emissivity - float fruit_emissivity = 0.0; + //! Fruit emissivity + float fruit_emissivity = 0.0; - //! Reflectivity spectrum (applies to all) - std::string reflectivity_spectrum; + //! Reflectivity spectrum (applies to all) + std::string reflectivity_spectrum; - //! Transmissivity spectrum (applies to all) - std::string transmissivity_spectrum; + //! Transmissivity spectrum (applies to all) + std::string transmissivity_spectrum; - //! Emissivity spectrum (applies to all) - std::string emissivity_spectrum; + //! Emissivity spectrum (applies to all) + std::string emissivity_spectrum; - //! Leaf reflectivity spectrum - std::string leaf_reflectivity_spectrum = "grape_leaf_reflectivity_0000"; + //! Leaf reflectivity spectrum + std::string leaf_reflectivity_spectrum = "grape_leaf_reflectivity_0000"; - //! Leaf transmissivity spectrum - std::string leaf_transmissivity_spectrum = "grape_leaf_transmissivity_0000"; + //! Leaf transmissivity spectrum + std::string leaf_transmissivity_spectrum = "grape_leaf_transmissivity_0000"; - //! Leaf emissivity spectrum - std::string leaf_emissivity_spectrum; + //! Leaf emissivity spectrum + std::string leaf_emissivity_spectrum; - //! Ground reflectivity spectrum - std::string ground_reflectivity_spectrum = "soil_reflectivity_0000"; + //! Ground reflectivity spectrum + std::string ground_reflectivity_spectrum = "soil_reflectivity_0000"; - //! Ground transmissivity spectrum - std::string ground_transmissivity_spectrum; + //! Ground transmissivity spectrum + std::string ground_transmissivity_spectrum; - //! Ground emissivity spectrum - std::string ground_emissivity_spectrum; + //! Ground emissivity spectrum + std::string ground_emissivity_spectrum; - //! Petiolule reflectivity spectrum - std::string petiolule_reflectivity_spectrum; + //! Petiolule reflectivity spectrum + std::string petiolule_reflectivity_spectrum; - //! Petiolule transmissivity spectrum - std::string petiolule_transmissivity_spectrum; + //! Petiolule transmissivity spectrum + std::string petiolule_transmissivity_spectrum; - //! Petiolule emissivity spectrum - std::string petiolule_emissivity_spectrum; + //! Petiolule emissivity spectrum + std::string petiolule_emissivity_spectrum; - //! Petiole reflectivity spectrum - std::string petiole_reflectivity_spectrum; + //! Petiole reflectivity spectrum + std::string petiole_reflectivity_spectrum; - //! Petiole transmissivity spectrum - std::string petiole_transmissivity_spectrum; + //! Petiole transmissivity spectrum + std::string petiole_transmissivity_spectrum; - //! Petiole emissivity spectrum - std::string petiole_emissivity_spectrum; + //! Petiole emissivity spectrum + std::string petiole_emissivity_spectrum; - //! Internode reflectivity spectrum - std::string internode_reflectivity_spectrum; + //! Internode reflectivity spectrum + std::string internode_reflectivity_spectrum; - //! Internode transmissivity spectrum - std::string internode_transmissivity_spectrum; + //! Internode transmissivity spectrum + std::string internode_transmissivity_spectrum; - //! Internode emissivity spectrum - std::string internode_emissivity_spectrum; + //! Internode emissivity spectrum + std::string internode_emissivity_spectrum; - //! Peduncle reflectivity spectrum - std::string peduncle_reflectivity_spectrum; + //! Peduncle reflectivity spectrum + std::string peduncle_reflectivity_spectrum; - //! Peduncle transmissivity spectrum - std::string peduncle_transmissivity_spectrum; + //! Peduncle transmissivity spectrum + std::string peduncle_transmissivity_spectrum; - //! Peduncle emissivity spectrum - std::string peduncle_emissivity_spectrum; + //! Peduncle emissivity spectrum + std::string peduncle_emissivity_spectrum; - //! Petal reflectivity spectrum - std::string petal_reflectivity_spectrum; + //! Petal reflectivity spectrum + std::string petal_reflectivity_spectrum; - //! Petal transmissivity spectrum - std::string petal_transmissivity_spectrum; + //! Petal transmissivity spectrum + std::string petal_transmissivity_spectrum; - //! Petal emissivity spectrum - std::string petal_emissivity_spectrum; + //! Petal emissivity spectrum + std::string petal_emissivity_spectrum; - //! Pedicel reflectivity spectrum - std::string pedicel_reflectivity_spectrum; + //! Pedicel reflectivity spectrum + std::string pedicel_reflectivity_spectrum; - //! Pedicel transmissivity spectrum - std::string pedicel_transmissivity_spectrum; + //! Pedicel transmissivity spectrum + std::string pedicel_transmissivity_spectrum; - //! Pedicel emissivity spectrum - std::string pedicel_emissivity_spectrum; + //! Pedicel emissivity spectrum + std::string pedicel_emissivity_spectrum; - //! Fruit reflectivity spectrum - std::string fruit_reflectivity_spectrum; + //! Fruit reflectivity spectrum + std::string fruit_reflectivity_spectrum; - //! Fruit transmissivity spectrum - std::string fruit_transmissivity_spectrum; + //! Fruit transmissivity spectrum + std::string fruit_transmissivity_spectrum; - //! Fruit emissivity spectrum - std::string fruit_emissivity_spectrum; + //! Fruit emissivity spectrum + std::string fruit_emissivity_spectrum; - //! All possible visualization types for primitives - std::set visualization_types_primitive = {"radiation_flux_PAR", "radiation_flux_NIR", "radiation_flux_LW"}; + //! All possible visualization types for primitives + std::set visualization_types_primitive = {"radiation_flux_PAR", "radiation_flux_NIR", "radiation_flux_LW"}; - //! All possible visualization types for objects - std::set visualization_types_object = {}; + //! All possible visualization types for objects + std::set visualization_types_object = {}; - //! Primitive data types - std::map primitive_data_types; + //! Primitive data types + std::map primitive_data_types; - //! Object data types - std::map object_data_types; + //! Object data types + std::map object_data_types; - //! Visualization type - std::string visualization_type = "RGB"; + //! Visualization type + std::string visualization_type = "RGB"; - //! Currently selected canopy in the GUI - std::string current_canopy; + //! Currently selected canopy in the GUI + std::string current_canopy; - //! Currently selected rig in the GUI - std::string current_rig; + //! Currently selected rig in the GUI + std::string current_rig; - //! Currently selected camera in the GUI - std::string current_cam; + //! Currently selected camera in the GUI + std::string current_cam; - //! Currently selected light in the GUI - std::string current_light; + //! Currently selected light in the GUI + std::string current_light; - //! Currently selected keypoint in the GUI - std::string current_keypoint; + //! Currently selected keypoint in the GUI + std::string current_keypoint; - //! Currently selected primitive in the GUI - std::string current_primitive = "All"; + //! Currently selected primitive in the GUI + std::string current_primitive = "All"; - //! Currently selected data group in the GUI - std::string current_data_group = "All"; + //! Currently selected data group in the GUI + std::string current_data_group = "All"; - //! Currently selected band in the GUI - std::string current_band = "red"; + //! Currently selected band in the GUI + std::string current_band = "red"; - //! Currently selected radiation band for reflectivity in the GUI - std::string current_band_reflectivity = "red"; + //! Currently selected radiation band for reflectivity in the GUI + std::string current_band_reflectivity = "red"; - //! Currently selected radiation band for transmissivity in the GUI - std::string current_band_transmissivity = "red"; + //! Currently selected radiation band for transmissivity in the GUI + std::string current_band_transmissivity = "red"; - //! Currently selected radiation band for emissivity in the GUI - std::string current_band_emissivity = "red"; + //! Currently selected radiation band for emissivity in the GUI + std::string current_band_emissivity = "red"; - //! Dictionary containing UUIDs for every camera model - std::map> camera_models_dict; + //! Dictionary containing UUIDs for every camera model + std::map> camera_models_dict; - //! Function to delete arrows denoting rig movement - void deleteArrows(); + //! General tab + void generalTab(); - //! Function to delete the selected canopy - /** - * \param[in] canopy Canopy name to delete - */ - void deleteCanopy(const std::string &canopy); + //! Canopy tab + void canopyTab(); - //! Function to delete the selected object - /** - * \param[in] obj Object name to delete - */ - void deleteObject(const std::string &obj); + //! Camera tab + void cameraTab(); - //! Function to update the selected canopy - /** - * \param[in] canopy Canopy to update - */ - void updateCanopy(const std::string &canopy); + //! Calculation tab + void calculationTab(); + + //! Object tab + void objectTab(); + + //! Radiation tab + void radiationTab(); + + //! Rig tab + void rigTab(); + + //! Light tab + void lightTab(); + + //! Function to delete arrows denoting rig movement + void deleteArrows(); + + //! Function to delete the selected canopy + /** + * \param[in] canopy Canopy name to delete + */ + void deleteCanopy(const std::string &canopy); + + //! Function to delete the selected object + /** + * \param[in] obj Object name to delete + */ + void deleteObject(const std::string &obj); + + //! Function to update the selected canopy + /** + * \param[in] canopy Canopy to update + */ + void updateCanopy(const std::string &canopy); + + //! Function to add a new canopy + void addCanopy(); + + //! Function to update arrows for rig movement + void updateArrows(); - //! Function to add a new canopy - void addCanopy(); + //! Function to update camera models in visualization + void updateCameraModels(); - //! Function to update arrows for rig movement - void updateArrows(); + //! Function to delete camera models in visualization + void deleteCameraModels(); - //! Function to update camera models in visualization - void updateCameraModels(); + //! Function to update data groups + void updateDataGroups(); - //! Function to delete camera models in visualization - void deleteCameraModels(); + //! Function to update primitive types + void updatePrimitiveTypes(); - //! Function to update data groups - void updateDataGroups(); + //! Dragging start position + helios::int2 dragging_start_position{0, 0}; - //! Function to update primitive types - void updatePrimitiveTypes(); + //! Current tab being dragged + std::string currently_dragging; - //! Dragging start position - helios::int2 dragging_start_position{0, 0}; + //! Current type being dragged + std::string currently_dragging_type; - //! Current tab being dragged - std::string currently_dragging; + //! Bool to disable dragging in ImGUI + bool disable_dragging = false; - //! Current type being dragged - std::string currently_dragging_type; + //! Canopy tab + void canopyTab(std::string curr_canopy_name, int id); - //! Bool to disable dragging in ImGUI - bool disable_dragging = false; + //! Rig tab + void rigTab(std::string curr_rig_name, int id); - //! Canopy tab - void canopyTab(std::string curr_canopy_name, int id); + //! Object tab + void objectTab(std::string curr_obj_name, int id); - //! Rig tab - void rigTab(std::string curr_rig_name, int id); + //! Save object file + void saveObject(std::string file_name, std::vector obj_UUID_vec, std::string file_extension); - //! Object tab - void objectTab(std::string curr_obj_name, int id); + //! Save canopy to object file + void saveCanopy(std::string file_name, std::vector canopy_ID_vec, helios::vec3 position, std::string file_extension) const; - //! Save object file - void saveObject(std::string file_name, std::vector obj_UUID_vec, std::string file_extension); + //! Save plants in canopy individually to object file + void saveCanopy(std::string file_name_base, std::vector canopy_ID_vec, std::vector positions, std::string file_extension) const; - //! Save canopy to object file - void saveCanopy(std::string file_name, std::vector canopy_ID_vec, helios::vec3 position, std::string file_extension) const; + //! Determines whether plants are saved together (false) or individually to their own object file (true) when saving a canopy to file. + bool save_plants_individually = false; - //! Save plants in canopy individually to object file - void saveCanopy(std::string file_name_base, std::vector canopy_ID_vec, std::vector positions, std::string file_extension) const; + //! Add radiation band + void addBand(std::string label, float wavelength_min, float wavelength_max, bool enable_emission); - //! Determines whether plants are saved together (false) or individually to their own object file (true) when saving a canopy to file. - bool save_plants_individually = false; + //! Add radiation band with no specified wavelength + void addBand(std::string label, bool enable_emission); - //! Add radiation band - void addBand(std::string label, float wavelength_min, float wavelength_max, bool enable_emission); + //! Distribution types + std::map distribution_types; - //! Add radiation band with no specified wavelength - void addBand(std::string label, bool enable_emission); + //! Distribution parameters + std::map> distribution_params; - //! Distribution types - std::map distribution_types; + //! Distributions dictionary keyed by distribution name with a value of the index of the distribution in the distributions vector + std::map distribution_dict; - //! Distribution parameters - std::map> distribution_params; + //! Dictionary keyed by variable name with a value of the variable address + std::map randomized_variable_lookup; - //! Distributions dictionary keyed by distribution name with a value of the index of the distribution in the distributions vector - std::map distribution_dict; + //! Random generator + std::default_random_engine generator; - //! Dictionary keyed by variable name with a value of the variable address - std::map randomized_variable_lookup; + //! Random distributions + std::string current_distribution = "Normal (Gaussian)"; - //! Random generator - std::default_random_engine generator; + //! Current axis + std::string current_axis = "X"; - //! Random distributions - std::string current_distribution = "Normal (Gaussian)"; + //! Possible axes + std::set possible_axes = {"X", "Y", "Z"}; - //! Current axis - std::string current_axis = "X"; + //! Random distributions + std::vector distribution_names = {"N/A", "Normal (Gaussian)", "Uniform", "Weibull"}; - //! Possible axes - std::set possible_axes = {"X", "Y", "Z"}; + //! Distributions + std::vector distributions; - //! Random distributions - std::vector distribution_names = {"N/A", "Normal (Gaussian)", "Uniform", "Weibull"}; + //! Distribution parameters + std::vector curr_distribution_params = {0.0, 0.0}; - //! Distributions - std::vector distributions; + //! Randomize repeatedly + bool randomize_repeatedly = false; - //! Distribution parameters - std::vector curr_distribution_params = {0.0, 0.0}; + //! + std::streambuf *old_cout_stream_buf = std::cout.rdbuf(); - //! Randomize repeatedly - bool randomize_repeatedly = false; + //! Stdout + std::stringstream captured_cout; - //! - std::streambuf *old_cout_stream_buf = std::cout.rdbuf(); + std::size_t last_console_size = 0; - //! Stdout - std::stringstream captured_cout; + //! Number of recordings + int num_recordings = 1; - std::size_t last_console_size = 0; + //! Set of all object structs + std::map objects_dict; - //! Number of recordings - int num_recordings = 1; + //! Set of all canopy structs + std::map canopy_dict; - //! Set of all object structs - std::map objects_dict; + //! Object index, applies a unique index to each object + int obj_idx = 0; - //! Set of all canopy structs - std::map canopy_dict; + //! Canopy index, applies a unique index to each canopy + int canopy_idx = 0; - //! Object index, applies a unique index to each object - int obj_idx = 0; + //! Indices of objects that need to be updated + std::set dirty_objects = {}; - //! Canopy index, applies a unique index to each canopy - int canopy_idx = 0; + //! Indices of canopies that need to be updated + std::set dirty_canopies = {}; - //! Indices of objects that need to be updated - std::set dirty_objects = {}; + //! Possible lighting models + std::set lighting_models = {"None", "Phong", "Phong Shadowed"}; - //! Indices of canopies that need to be updated - std::set dirty_canopies = {}; + //! Lighting model + std::string lighting_model = "None"; - //! Possible lighting models - std::set lighting_models = {"None", "Phong", "Phong Shadowed"}; + //! Light direction in the visualizer + helios::vec3 light_direction{0, 0, 1}; - //! Lighting model - std::string lighting_model = "None"; + //! Light intensity factor in the visualizer + float light_intensity = 1.0; - //! Light direction in the visualizer - helios::vec3 light_direction{0, 0, 1}; + //! Number of tiles + helios::int2 num_tiles{5, 5}; - //! Light intensity factor in the visualizer - float light_intensity = 1.0; + //! Calculation type + std::string calculation_type = "primitive"; - //! Number of tiles - helios::int2 num_tiles{5, 5}; + //! Calculation types + std::vector calculation_types{"primitive", "object", "data group"}; + + //! Calculation selection + std::map calculation_selection_datagroup{{"All", false}}; + + //! Calculation selection primitive + std::map calculation_selection_primitive{{"All", false}}; + + //! Calculation labels + std::set calculation_variable_choices; + + //! Calculation label + std::string calculation_variable_global; + + //! Calculation labels global + std::vector calculation_variables_global = {""}; + + //! Calculation labels by primitive + std::vector calculation_variables_primitive = {""}; + + //! Calculation scalars global + std::vector calculation_scalars_global = {1.0}; + + //! Calculation scalars by primitive + std::vector calculation_scalars_primitive = {1.0}; + + //! Operators for global calculation + std::vector calculation_operators_global = {}; + + //! Operators for calculation by primitive + std::vector calculation_operators_primitive = {}; + + //! Caclulation operator choices + std::set calculation_operators_choices = {"+", "-", "/", "x"}; + + //! Operation Choices + std::set calculation_aggregation_choices = {"None", "Mean", "Sum", "Area Weighted Mean", "Area Weighted Sum"}; + + //! Helios numeric types + // std::set heliosNumericTypes = {helios::HELIOS_TYPE_INT, helios::HELIOS_TYPE_UINT, + // helios::HELIOS_TYPE_FLOAT, helios::HELIOS_TYPE_DOUBLE}; + std::set heliosNumericTypes = {helios::HELIOS_TYPE_FLOAT}; + + //! Current operation + std::string curr_aggregation = "Mean"; + + std::vector calculation_aggregations = {"Mean"}; + + bool by_primitive = false; + + std::string calculation_name_primitive = "saved prim data"; + + std::string calculation_name_global = "saved global data"; + + //! Calculation Result + float calculation_result_global = 0.0f; + + //! Refresh list of possible objects for bounding boxes + void refreshBoundingBoxObjectList(); + + //! Perform global calculation + void globalCalculation(); + + //! Save primitive calculation + void savePrimitiveCalculation(); + + //! Run radiation + void runRadiation(); public: //! Context @@ -1286,6 +1413,9 @@ class ProjectBuilder { //! Function to "record", or save camera images with bounding boxes for each rig void record(); + //! Function to "reload" (unused) + void reload(); + //! Function to build context from XML void buildFromXML(); @@ -1730,10 +1860,16 @@ class ProjectBuilder { //! Delete rig /** - * \param[in] curr_rig Rig to be deleted + * \param[in] curr_rig Name of rig to be deleted */ void deleteRig(std::string curr_rig); + //! Add rig + /** + * \param[in] new_rig_label Name of rig to be added + */ + void addRig(std::string new_rig_label); + #ifdef ENABLE_HELIOS_VISUALIZER //! Create dropdown widget /** diff --git a/plugins/projectbuilder/src/ProjectBuilder.cpp b/plugins/projectbuilder/src/ProjectBuilder.cpp index 51c47e010..87e394346 100644 --- a/plugins/projectbuilder/src/ProjectBuilder.cpp +++ b/plugins/projectbuilder/src/ProjectBuilder.cpp @@ -5,6 +5,7 @@ #define WIN32_LEAN_AND_MEAN #include #include +#include #elif defined(__APPLE__) #ifdef ENABLE_HELIOS_VISUALIZER #include @@ -31,6 +32,8 @@ #include "ProjectBuilder.h" + + #ifdef ENABLE_BOUNDARYLAYERCONDUCTANCEMODEL const bool enable_blconductance = true; #else @@ -503,28 +506,12 @@ void ProjectBuilder::updatePrimitiveTypes() { void ProjectBuilder::updateDataGroups() { + data_groups.clear(); + context->getUniqueObjectDataValues("data_group", data_groups); data_groups_set.clear(); data_groups_set.insert("All"); - std::vector all_UUIDs = context->getAllUUIDs(); - for (uint UUID: all_UUIDs) { - std::string curr_data_group = ""; - if (!context->doesPrimitiveDataExist(UUID, "data_group")) - continue; - context->getPrimitiveData(UUID, "data_group", curr_data_group); - if (!curr_data_group.empty()) { - data_groups_set.insert(curr_data_group); - } - } - for (std::string data_group: data_groups_set) { // initialize new data_groups if necessary - if (primitive_continuous_dict.find(data_group) == primitive_continuous_dict.end()) { - primitive_continuous_dict[data_group] = primitive_continuous; - } - if (primitive_spectra_dict.find(data_group) == primitive_spectra_dict.end()) { - primitive_spectra_dict[data_group] = primitive_spectra; - } - if (primitive_values_dict.find(data_group) == primitive_values_dict.end()) { - primitive_values_dict[data_group] = primitive_values; - } + for (auto &group : data_groups) { + data_groups_set.insert(group); } } @@ -580,11 +567,12 @@ void ProjectBuilder::updateSpectra() { } std::vector all_UUIDs = context->getAllUUIDs(); for (uint UUID: all_UUIDs) { - if (!context->doesPrimitiveDataExist(UUID, "data_group")) + uint parentObjID = context->getPrimitiveParentObjectID(UUID); + if ( !context->doesObjectExist(parentObjID) || !context->doesObjectDataExist(parentObjID, "data_group")) continue; // Get data group of UUID std::string curr_data_group; - context->getPrimitiveData(UUID, "data_group", curr_data_group); + context->getObjectData(parentObjID, "data_group", curr_data_group); // Get primitive type of UUID std::string curr_prim_type; if (context->doesPrimitiveDataExist(UUID, "object_label")) { @@ -689,12 +677,6 @@ void ProjectBuilder::record() { setBoundingBoxObjects(); for (int _ = 0; _ < num_recordings; _++) { updateContext(); - // std::time_t now = std::time(nullptr); - // std::tm* tm_ptr = std::localtime(&now); - // std::ostringstream oss; - // oss << std::put_time(tm_ptr, "%Y-%m-%d %H:%M:%S"); - // std::string image_dir = "./saved-" + oss.str() + "/"; - // std::filesystem::create_directory("saved-" + oss.str()); std::string image_dir = "./saved/"; std::string image_dir_base = "./saved_"; int image_dir_idx = 0; @@ -769,6 +751,11 @@ void ProjectBuilder::record() { // Write Images for (std::string band_group_name: band_group_names) { bandGroup curr_band_group = band_group_lookup[band_group_name]; + if (std::find(curr_band_group.bands.begin(), curr_band_group.bands.end(), "red") != curr_band_group.bands.end() && + std::find(curr_band_group.bands.begin(), curr_band_group.bands.end(), "green") != curr_band_group.bands.end() && + std::find(curr_band_group.bands.begin(), curr_band_group.bands.end(), "blue") != curr_band_group.bands.end()) { + radiation->applyImageProcessingPipeline(cameralabel, "red", "green", "blue", curr_band_group.hdr); + } std::vector band_group_vec; if (!curr_band_group.grayscale) { band_group_vec = curr_band_group.bands; @@ -792,8 +779,19 @@ void ProjectBuilder::record() { primitive_name[0] = std::tolower(static_cast(primitive_name[0])); } } - for (auto &box_pair: bounding_boxes_map) - radiation->writeImageBoundingBoxes(cameralabel, box_pair.first, box_pair.second, band_group_ + std::to_string(i), "classes.txt", image_dir + rig_label + '/'); + for (auto &box_pair: bounding_boxes_map) { + if (bounding_boxes_object.find(box_pair.first) != bounding_boxes_object.end() ) { + radiation->writeImageBoundingBoxes_ObjectData(cameralabel, box_pair.first, box_pair.second, band_group_ + std::to_string(i) + "_bbox", image_dir + rig_label + '/', true); + if (write_segmentation_mask[rig_dict[current_rig]]) { + radiation->writeImageSegmentationMasks_ObjectData(camera_label, box_pair.first, box_pair.second, band_group_ + std::to_string(i) + "_mask", image_dir + rig_label + '/', true); + } + } else if (bounding_boxes_primitive.find(box_pair.first) == bounding_boxes_object.end()) { + radiation->writeImageBoundingBoxes(cameralabel, box_pair.first, box_pair.second, band_group_ + std::to_string(i) + "_bbox", image_dir + rig_label + '/', true); + if (write_segmentation_mask[rig_dict[current_rig]]) { + radiation->writeImageSegmentationMasks(camera_label, box_pair.first, box_pair.second, band_group_ + std::to_string(i) + "_mask", image_dir + rig_label + '/', true); + } + } + } } // } @@ -813,9 +811,51 @@ void ProjectBuilder::record() { #endif // RADIATION_MODEL } + +void ProjectBuilder::reload() { + xmlSetValues(); + const char *font_name = "LCD"; + visualizer->addTextboxByCenter("LOADING...", vec3(.5, .5, 0), make_SphericalCoord(0, 0), RGB::red, 40, font_name, Visualizer::COORDINATES_WINDOW_NORMALIZED); + visualizer->plotUpdate(); + visualizer->clearGeometry(); + delete context; + #ifdef ENABLE_PLANT_ARCHITECTURE + delete plantarchitecture; + #endif // PLANT_ARCHITECTURE + #ifdef ENABLE_RADIATION_MODEL + delete radiation; + #endif // RADIATION_MODEL + #ifdef ENABLE_SOLARPOSITION + delete solarposition; + #endif // SOLARPOSITION + #ifdef ENABLE_ENERGYBALANCEMODEL + delete energybalancemodel; + #endif // ENERGYBALANCEMODEL + #ifdef ENABLE_BOUNDARYLAYERCONDUCTANCEMODEL + delete boundarylayerconductance; + #endif // BOUNDARYLAYERCONDUCTANCEMODEL + #ifdef ENABLE_RADIATION_MODEL + delete cameraproperties; + #endif // RADIATION_MODEL + buildFromXML(); + // #ifdef ENABLE_RADIATION_MODEL + // radiation->enableCameraModelVisualization(); + // #endif //RADIATION_MODEL + #ifdef ENABLE_PLANT_ARCHITECTURE + visualizer->buildContextGeometry(context); + #endif // PLANT_ARCHITECTURE + visualizer->addCoordinateAxes(helios::make_vec3(0, 0, 0.05), helios::make_vec3(1, 1, 1), "positive"); + visualizer->plotUpdate(); +} + + + void ProjectBuilder::buildFromXML() { context = new Context(); + context->enablePrimitiveDataValueCaching("object_label"); + context->enableObjectDataValueCaching("data_group"); + // if (enable_plantarchitecture){ #ifdef ENABLE_PLANT_ARCHITECTURE plantarchitecture = new PlantArchitecture(context); @@ -973,7 +1013,6 @@ void ProjectBuilder::buildFromXML() { } context->setPrimitiveData(context->getAllUUIDs(), "air_humidity", air_humidity); -// if (enable_solarposition && enable_radiation){ #ifdef ENABLE_RADIATION_MODEL sun_dir_vec = solarposition->getSunDirectionVector(); @@ -995,7 +1034,11 @@ void ProjectBuilder::buildFromXML() { // Run the radiation model radiation->runBand({"PAR", "NIR", "LW"}); -// } //SOLARPOSITION && RADIATION_MODEL + + std::vector new_band_group_vector = {"PAR", "NIR", "LW"}; + bandGroup new_band_group{new_band_group_vector, false, false, false}; + band_group_lookup.insert({"default", new_band_group}); + band_group_names.insert("default"); #endif // SOLARPOSITION && RADIATION_MODEL context->calculatePrimitiveDataAreaWeightedSum(leaf_UUIDs, "radiation_flux_PAR", PAR_absorbed); @@ -1883,6 +1926,7 @@ void ProjectBuilder::visualize() { visualizer->addCoordinateAxes(helios::make_vec3(0, 0, 0.05), helios::make_vec3(1, 1, 1), "positive"); visualizer->plotUpdate(); + updatePrimitiveTypes(); // Setup Dear ImGui context IMGUI_CHECKVERSION(); @@ -2176,13 +2220,8 @@ void ProjectBuilder::visualize() { ImGui::EndMenu(); } if (ImGui::BeginMenu("Visualization")) { - // ImGui::PushFont(font_awesome); - // io.FontDefault = font_awesome; - if (ImGui::MenuItem("! REFRESH LIST !")) { refreshVisualizationTypes(); - } - // ImGui::PopFont(); - // io.FontDefault = arial; + refreshVisualizationTypes(); if (ImGui::MenuItem("RGB (Default)") && visualization_type != "RGB") { visualization_type = "RGB"; switch_visualization = true; @@ -2190,10 +2229,16 @@ void ProjectBuilder::visualize() { std::set vis_types; std::set_union(visualization_types_primitive.begin(), visualization_types_primitive.end(), visualization_types_object.begin(), visualization_types_object.end(), std::inserter(vis_types, vis_types.begin())); for (auto &type: vis_types) { + if (visualization_types_primitive.find(type) != visualization_types_primitive.end()) { + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 165, 0, 255)); // orange text + } else { + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0, 0, 255, 255)); // blue text + } if (ImGui::MenuItem(type.c_str()) && visualization_type != type) { visualization_type = type; switch_visualization = true; } + ImGui::PopStyleColor(); } if (switch_visualization) { if (visualization_type != "RGB") { @@ -2212,41 +2257,6 @@ void ProjectBuilder::visualize() { } ImGui::EndMenuBar(); } - if (ImGui::Button("Reload")) { - xmlSetValues(); - const char *font_name = "LCD"; - visualizer->addTextboxByCenter("LOADING...", vec3(.5, .5, 0), make_SphericalCoord(0, 0), RGB::red, 40, font_name, Visualizer::COORDINATES_WINDOW_NORMALIZED); - visualizer->plotUpdate(); - visualizer->clearGeometry(); - delete context; -#ifdef ENABLE_PLANT_ARCHITECTURE - delete plantarchitecture; -#endif // PLANT_ARCHITECTURE -#ifdef ENABLE_RADIATION_MODEL - delete radiation; -#endif // RADIATION_MODEL -#ifdef ENABLE_SOLARPOSITION - delete solarposition; -#endif // SOLARPOSITION -#ifdef ENABLE_ENERGYBALANCEMODEL - delete energybalancemodel; -#endif // ENERGYBALANCEMODEL -#ifdef ENABLE_BOUNDARYLAYERCONDUCTANCEMODEL - delete boundarylayerconductance; -#endif // BOUNDARYLAYERCONDUCTANCEMODEL -#ifdef ENABLE_RADIATION_MODEL - delete cameraproperties; -#endif // RADIATION_MODEL - buildFromXML(); -// #ifdef ENABLE_RADIATION_MODEL -// radiation->enableCameraModelVisualization(); -// #endif //RADIATION_MODEL -#ifdef ENABLE_PLANT_ARCHITECTURE - visualizer->buildContextGeometry(context); -#endif // PLANT_ARCHITECTURE - visualizer->addCoordinateAxes(helios::make_vec3(0, 0, 0.05), helios::make_vec3(1, 1, 1), "positive"); - visualizer->plotUpdate(); - } std::string image_dir = "./saved/"; bool dir = std::filesystem::create_directories(image_dir); if (!dir && !std::filesystem::exists(image_dir)) { @@ -2256,7 +2266,6 @@ void ProjectBuilder::visualize() { // plant segmentation bounding boxes // plant ID bounding boxes (plant architecture->optional plant output data) #ifdef ENABLE_RADIATION_MODEL - ImGui::SameLine(); if (ImGui::Button("Record")) { if (band_group_names.empty()) { std::cout << "At least 1 band group (a group of 1 or 3 bands) must be defined to record images." << std::endl; @@ -2268,10 +2277,12 @@ void ProjectBuilder::visualize() { updatePrimitiveTypes(); updateSpectra(); updateCameras(); // TODO: figure out why this causes an error - record(); - visualizer->clearGeometry(); - visualizer->buildContextGeometry(context); - visualizer->plotUpdate(); + try { + record(); + } catch (const std::runtime_error &e) { + std::cerr << "Record failed due to exception: " << e.what() << std::endl; + visualizer->plotUpdate(); + } } } recordPopup(); @@ -2286,1985 +2297,63 @@ void ProjectBuilder::visualize() { if (ImGui::BeginTabBar("Settings#left_tabs_bar")) { if (ImGui::BeginTabItem("General")) { current_tab = "General"; - // ####### LOCATION ####### // - ImGui::SetWindowFontScale(1.25f); - ImGui::Text("Visualization:"); - ImGui::SetWindowFontScale(1.0f); - // ####### COORDINATE AXES ####### // - bool enable_coords_ = enable_coordinate_axes; - toggle_button("##coordinate_axes", &enable_coordinate_axes); - if (enable_coords_ != enable_coordinate_axes) { - if (enable_coordinate_axes) { - visualizer->addCoordinateAxes(helios::make_vec3(0, 0, 0.05), helios::make_vec3(1, 1, 1), "positive"); - is_dirty = true; - } else { - visualizer->disableCoordinateAxes(); - is_dirty = true; - } - } - ImGui::SameLine(); - if (enable_coordinate_axes) { - ImGui::Text("Coordinate Axes Enabled"); - } else { - ImGui::Text("Coordinate Axes Disabled"); - } - // ####### COLORBAR ####### // - bool enable_colorbar_ = enable_colorbar; - toggle_button("##colorbar", &enable_colorbar); - if (enable_colorbar_ != enable_colorbar) { - if (enable_colorbar) { - visualizer->enableColorbar(); - is_dirty = true; - } else { - visualizer->disableColorbar(); - is_dirty = true; - } - } - ImGui::SameLine(); - if (enable_colorbar) { - ImGui::Text("Colorbar Enabled"); - } else { - ImGui::Text("Colorbar Disabled"); - } - // ####### LIGHTING MODEL ####### // - std::string prev_lighting_model = lighting_model; - ImGui::SetNextItemWidth(120); - dropDown("Lighting Model", lighting_model, lighting_models); - if (prev_lighting_model != lighting_model) { - if (lighting_model == "None") - visualizer->setLightingModel(Visualizer::LIGHTING_NONE); - if (lighting_model == "Phong") - visualizer->setLightingModel(Visualizer::LIGHTING_PHONG); - if (lighting_model == "Phong Shadowed") - visualizer->setLightingModel(Visualizer::LIGHTING_PHONG_SHADOWED); - } - ImGui::SetNextItemWidth(120); - // ####### LIGHTING INTENSITY ####### // - ImGui::InputFloat("Light Intensity Factor", &light_intensity); - visualizer->setLightIntensityFactor(light_intensity); - // ####### LIGHTING DIRECTION ####### // - toggle_button("##light_coord_type", &light_coord_type); - ImGui::SameLine(); - if (light_coord_type) { - SphericalCoord light_dir_sphere_ = cart2sphere(light_direction); - vec2 light_dir_sphere; - light_dir_sphere.x = rad2deg(light_dir_sphere_.elevation); - light_dir_sphere.y = rad2deg(light_dir_sphere_.azimuth); - ImGui::Text("Elevation:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); - ImGui::InputFloat("##light_elevation", &light_dir_sphere.x); - ImGui::SameLine(); - ImGui::Text("Azimuth:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); - ImGui::InputFloat("##light_azimuth", &light_dir_sphere.y); - ImGui::SameLine(); - ImGui::Text("Light Direction (Spherical)"); - if (light_dir_sphere.x != light_dir_sphere_.elevation || light_dir_sphere.y != light_dir_sphere_.azimuth) { - SphericalCoord light_dir = make_SphericalCoord(deg2rad(light_dir_sphere.x), deg2rad(light_dir_sphere.y)); - light_direction = sphere2cart(light_dir); - } - } else { - float light_dir[3]; - light_dir[0] = light_direction.x; - light_dir[1] = light_direction.y; - light_dir[2] = light_direction.z; - ImGui::InputFloat3("Light Direction (Cartesian)", light_dir); - light_direction.x = light_dir[0]; - light_direction.y = light_dir[1]; - light_direction.z = light_dir[2]; - } - visualizer->setLightDirection(light_direction); - // ####### LOCATION ####### // - ImGui::SetWindowFontScale(1.25f); - ImGui::Text("Location:"); - ImGui::SetWindowFontScale(1.0f); - if (ImGui::Button("Update Location")) { - updateLocation(); - } - // ####### LATITUDE ####### // - ImGui::SetNextItemWidth(100); - ImGui::InputFloat("Latitude", &latitude); - randomizePopup("latitude", createTaggedPtr(&latitude)); - randomizerParams("latitude"); - ImGui::OpenPopupOnItemClick("randomize_latitude", ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - // ####### LONGITUDE ####### // - ImGui::SetNextItemWidth(100); - ImGui::InputFloat("Longitude", &longitude); - randomizePopup("longitude", createTaggedPtr(&longitude)); - randomizerParams("longitude"); - ImGui::OpenPopupOnItemClick("randomize_longitude", ImGuiPopupFlags_MouseButtonRight); - // ####### UTC OFFSET ####### // - ImGui::SetNextItemWidth(100); - ImGui::InputInt("UTC Offset", &UTC_offset); - randomizePopup("UTC_offset", createTaggedPtr(&UTC_offset)); - randomizerParams("UTC_offset"); - ImGui::OpenPopupOnItemClick("randomize_UTC_offset", ImGuiPopupFlags_MouseButtonRight); - // ####### Weather File ####### // - ImGui::SetNextItemWidth(60); - ImGui::RadioButton("CSV", is_weather_file_csv); - if (ImGui::IsItemClicked()) - is_weather_file_csv = true; - ImGui::SameLine(); - ImGui::RadioButton("CIMIS", !is_weather_file_csv); - if (ImGui::IsItemClicked()) - is_weather_file_csv = false; - std::string prev_weather_file; - std::string *weather_file; - if (is_weather_file_csv) { - ImGui::Text("CSV"); - weather_file = &csv_weather_file; - prev_weather_file = csv_weather_file; - } else { - ImGui::Text("CIMIS"); - weather_file = &cimis_weather_file; - prev_weather_file = cimis_weather_file; - } - ImGui::SameLine(); - if (ImGui::Button("Weather File")) { - std::string weather_file_ = file_dialog(); - if (!weather_file_.empty()) { - *weather_file = weather_file_; - try { - if (is_weather_file_csv) { - context->loadTabularTimeseriesData(*weather_file, {}, ",", "YYYYMMDD", 1); - } else { - context->loadTabularTimeseriesData(*weather_file, {"CIMIS"}, ","); - } - } catch (...) { - std::cout << "Failed to load weather file: " << *weather_file << std::endl; - *weather_file = prev_weather_file; - } - } else { - *weather_file = prev_weather_file; - } - } - ImGui::SameLine(); - std::string shorten_weather_file = *weather_file; - for (char &c: shorten_weather_file) { - if (c == '\\') { - c = '/'; - } - } - size_t last_weather_file = shorten_weather_file.rfind('/'); - if (last_weather_file != std::string::npos) { - shorten_weather_file = shorten_weather_file.substr(last_weather_file + 1); - } - ImGui::Text("%s", shorten_weather_file.c_str()); - // ####### GROUND ####### // - ImGui::SetWindowFontScale(1.25f); - ImGui::Text("Ground:"); - ImGui::SetWindowFontScale(1.0f); - if (ImGui::Button("Update Ground")) { - updateGround(); - updatePrimitiveTypes(); - updateSpectra(); - is_dirty = true; - // refreshVisualization(); - } - ImGui::SameLine(); - if (ImGui::Button("Delete Ground")) { - deleteGround(); - updatePrimitiveTypes(); - updateSpectra(); - is_dirty = true; - // refreshVisualization(); - } - // ImGui::RadioButton("Manually Set Color", ground_flag == 0); if (ImGui::IsItemClicked()) ground_flag = 0; - // ImGui::SameLine(); - ImGui::RadioButton("Use Texture File", ground_flag == 1); - if (ImGui::IsItemClicked()) - ground_flag = 1; - ImGui::SameLine(); - ImGui::RadioButton("Use Model File", ground_flag == 2); - if (ImGui::IsItemClicked()) - ground_flag = 2; - if (ground_flag == 0) { - // ####### GROUND COLOR ####### // - ImGui::ColorEdit3("##ground_color_edit", ground_color); - } else if (ground_flag == 1) { - // ####### GROUND TEXTURE File ####### // - ImGui::SetNextItemWidth(60); - if (ImGui::Button("Ground Texture File")) { - std::string ground_texture_file_ = file_dialog(); - if (!ground_texture_file_.empty()) { - ground_texture_file = ground_texture_file_; - } - } - ImGui::SameLine(); - std::string shorten = ground_texture_file; - for (char &c: shorten) { - if (c == '\\') { - c = '/'; - } - } - size_t last = shorten.rfind('/'); - if (last != std::string::npos) { - shorten = shorten.substr(last + 1); - } - ImGui::Text("%s", shorten.c_str()); - } else if (ground_flag == 2) { - // ####### GROUND Model File ####### // - ImGui::SetNextItemWidth(60); - if (ImGui::Button("Ground Model File")) { - std::string ground_model_file_ = file_dialog(); - if (!ground_model_file_.empty()) { - ground_model_file = ground_model_file_; - } - } - ImGui::SameLine(); - ImGui::Text("%s", shortenPath(ground_model_file).c_str()); - } - toggle_button("##use_ground_texture_color", &use_ground_texture); - // ####### GROUND COLOR ####### // - if (use_ground_texture) { - ImGui::SameLine(); - ImGui::Text("Use Ground Texture Color"); - } else { - ImGui::SameLine(); - ImGui::ColorEdit3("##ground_color_edit", ground_color); - ImGui::SameLine(); - ImGui::Text("Manually Set Ground Color"); - } - // ####### DOMAIN ORIGIN ####### // - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##domain_origin_x", &domain_origin.x); - randomizePopup("domain_origin_x", createTaggedPtr(&domain_origin.x)); - randomizerParams("domain_origin_x"); - ImGui::OpenPopupOnItemClick("randomize_domain_origin_x", ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##domain_origin_y", &domain_origin.y); - randomizePopup("domain_origin_y", createTaggedPtr(&domain_origin.y)); - randomizerParams("domain_origin_y"); - ImGui::OpenPopupOnItemClick("randomize_domain_origin_y", ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##domain_origin_z", &domain_origin.z); - randomizePopup("domain_origin_z", createTaggedPtr(&domain_origin.z)); - randomizerParams("domain_origin_z"); - ImGui::OpenPopupOnItemClick("randomize_domain_origin_z", ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Domain Origin"); - if (ground_flag == 1) { - // ####### GROUND RESOLUTION ####### // - ImGui::SetNextItemWidth(100); - ImGui::InputInt("##ground_resolution_x", &ground_resolution.x); - randomizePopup("ground_resolution_x", createTaggedPtr(&ground_resolution.x)); - randomizerParams("ground_resolution_x"); - ImGui::OpenPopupOnItemClick("randomize_ground_resolution_x", ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(100); - ImGui::InputInt("##ground_resolution_y", &ground_resolution.y); - randomizePopup("ground_resolution_y", createTaggedPtr(&ground_resolution.y)); - randomizerParams("ground_resolution_y"); - ImGui::OpenPopupOnItemClick("randomize_ground_resolution_y", ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Ground Resolution"); - // ####### DOMAIN EXTENT ####### // - ImGui::SetNextItemWidth(50); - ImGui::InputFloat("##domain_extent_x", &domain_extent.x); - randomizePopup("domain_extent_x", createTaggedPtr(&domain_extent.x)); - randomizerParams("domain_extent_x"); - ImGui::OpenPopupOnItemClick("randomize_domain_extent_x", ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(50); - ImGui::InputFloat("##domain_extent_y", &domain_extent.y); - randomizePopup("domain_extent_y", createTaggedPtr(&domain_extent.y)); - randomizerParams("domain_extent_y"); - ImGui::OpenPopupOnItemClick("randomize_domain_extent_y", ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Domain Extent"); - // ####### NUMBER OF TILES ####### // - ImGui::SetNextItemWidth(60); - int temp[2]; - temp[0] = num_tiles.x; - temp[1] = num_tiles.y; - ImGui::InputInt2("Number of Tiles", temp); - num_tiles.x = temp[0]; - num_tiles.y = temp[1]; - } + generalTab(); + + ImGui::EndTabItem(); + } + // Calculation Tab + if (ImGui::BeginTabItem("Calculation")) { + current_tab = "Calculation"; + calculationTab(); ImGui::EndTabItem(); } // OBJECT TAB if (ImGui::BeginTabItem("Object")) { current_tab = "Object"; - if (ImGui::Button("Load Object File")) { - std::string new_obj_file = file_dialog(); - if (!new_obj_file.empty() && std::filesystem::exists(new_obj_file)) { - if (std::filesystem::path(new_obj_file).extension() != ".obj" && std::filesystem::path(new_obj_file).extension() != ".ply") { - std::cout << "Object file must have .obj or .ply extension." << std::endl; - } else { - object new_obj; - std::vector new_UUIDs; - if (std::filesystem::path(new_obj_file).extension() == ".obj") { - new_UUIDs = context->loadOBJ(new_obj_file.c_str()); - } else if (std::filesystem::path(new_obj_file).extension() == ".ply") { - new_UUIDs = context->loadPLY(new_obj_file.c_str()); - } - // check for MTL file - std::filesystem::path mtl_path(new_obj_file); - mtl_path.replace_extension("mtl"); - if (std::filesystem::exists(mtl_path)) { - new_obj.use_texture_file = true; - } else { - new_obj.use_texture_file = false; - } - visualizer->buildContextGeometry(context); - visualizer->plotUpdate(); - std::string default_object_label = "object"; - std::string new_obj_label = "object_0"; - int count = 0; - while (objects_dict.find(new_obj_label) != objects_dict.end()) { - count++; - new_obj_label = default_object_label + "_" + std::to_string(count); - } - obj_names_set.insert(new_obj_label); - new_obj.index = obj_idx; - obj_idx++; - new_obj.name = new_obj_label; - new_obj.file = new_obj_file; - new_obj.UUIDs = new_UUIDs; - new_obj.position = vec3(0, 0, 0); - new_obj.prev_position = vec3(0, 0, 0); - new_obj.orientation = vec3(0, 0, 0); - new_obj.prev_orientation = vec3(0, 0, 0); - new_obj.scale = vec3(1, 1, 1); - new_obj.prev_scale = vec3(1, 1, 1); - new_obj.color = RGBcolor(0, 0, 1); - new_obj.prev_color = RGBcolor(0, 0, 1); - new_obj.data_group = ""; - new_obj.is_dirty = false; - current_obj = new_obj_label; - objects_dict[new_obj_label] = new_obj; - } - } - } - if (ImGui::BeginCombo("##obj_combo", current_obj.c_str())) { - for (std::string obj_name: obj_names_set) { - bool is_obj_selected = (current_obj == obj_name); - if (ImGui::Selectable(obj_name.c_str(), is_obj_selected)) - current_obj = obj_name; - if (is_obj_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Select Object"); - if (!current_obj.empty()) { - // if (ImGui::Button("Update Object")){ - // updateObject(current_obj); - // } - // ImGui::SameLine(); - if (ImGui::Button("Delete Object")) { - deleteObject(current_obj); - } - if (objects_dict[current_obj].is_dirty) { - ImGui::SameLine(); - ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255)); // Red text - ImGui::Text("update required"); - ImGui::PopStyleColor(); - } - ImGui::SetNextItemWidth(100); - std::string prev_obj_name = objects_dict[current_obj].name; - ImGui::InputText("##obj_name", &objects_dict[current_obj].name); - if (objects_dict[current_obj].name != prev_obj_name && !objects_dict[current_obj].name.empty() && obj_names_set.find(objects_dict[current_obj].name) == obj_names_set.end()) { - object temp_obj = objects_dict[prev_obj_name]; - current_obj = objects_dict[current_obj].name; - std::map::iterator delete_obj_iter = objects_dict.find(prev_obj_name); - if (delete_obj_iter != objects_dict.end()) { - objects_dict.erase(delete_obj_iter); - } - objects_dict[current_obj] = temp_obj; - obj_names_set.erase(prev_obj_name); - obj_names_set.insert(current_obj); - } else { - objects_dict[current_obj].name = prev_obj_name; - } - ImGui::SameLine(); - ImGui::Text("Object Name"); - if (!current_obj.empty()) { - // ####### OBJECT DATA GROUP ####### // - ImGui::SetNextItemWidth(100); - std::string prev_obj_data_group = objects_dict[current_obj].data_group; - ImGui::InputText("##obj_data_group", &objects_dict[current_obj].data_group); - if (objects_dict[current_obj].data_group == "All" || objects_dict[current_obj].data_group.empty()) { - objects_dict[current_obj].data_group = prev_obj_data_group; - } - if (!objects_dict[current_obj].data_group.empty() && prev_obj_data_group != objects_dict[current_obj].data_group) { - std::string new_data_group = objects_dict[current_obj].data_group; - context->setPrimitiveData(objects_dict[current_obj].UUIDs, "data_group", new_data_group); - } - ImGui::SameLine(); - ImGui::Text("Data Group"); - bool use_obj_texture = objects_dict[current_obj].use_texture_file; - toggle_button("##use_texture_file", &use_obj_texture); - if (use_obj_texture != objects_dict[current_obj].use_texture_file) { - objects_dict[current_obj].use_texture_file = use_obj_texture; - objects_dict[current_obj].is_dirty = true; - updateObject(current_obj); - is_dirty = true; - } - ImGui::SameLine(); - if (!use_obj_texture) { - // ####### OBJECT COLOR ####### // - float col[3]; - col[0] = objects_dict[current_obj].color.r; - col[1] = objects_dict[current_obj].color.g; - col[2] = objects_dict[current_obj].color.b; - ImGui::ColorEdit3("##obj_color_edit", col); - if (objects_dict[current_obj].color.r != col[0] || objects_dict[current_obj].color.g != col[1] || objects_dict[current_obj].color.b != col[2]) { - updateColor(current_obj, "obj", col); - } - ImGui::SameLine(); - ImGui::Text("Object Color"); - } else { - // ####### OBJECT TEXTURE FILE ####### // - ImGui::Text("Use Color from Texture File"); - } - // ####### OBJECT SCALE ####### // - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##obj_scale_x", &objects_dict[current_obj].scale.x); - randomizePopup("obj_scale_x_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].scale.x, &objects_dict[current_obj].is_dirty)); - randomizerParams("obj_scale_x_" + std::to_string(objects_dict[current_obj].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_scale_x_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##obj_scale_y", &objects_dict[current_obj].scale.y); - randomizePopup("obj_scale_y_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].scale.y, &objects_dict[current_obj].is_dirty)); - randomizerParams("obj_scale_y_" + std::to_string(objects_dict[current_obj].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_scale_y_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##obj_scale_z", &objects_dict[current_obj].scale.z); - randomizePopup("obj_scale_z_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].scale.z, &objects_dict[current_obj].is_dirty)); - randomizerParams("obj_scale_z_" + std::to_string(objects_dict[current_obj].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_scale_z_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Object Scale"); - // ####### OBJECT POSITION ####### // - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##obj_position_x", &objects_dict[current_obj].position.x); - randomizePopup("obj_position_x_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].position.x, &objects_dict[current_obj].is_dirty)); - randomizerParams("obj_position_x_" + std::to_string(objects_dict[current_obj].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_position_x_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##obj_position_y", &objects_dict[current_obj].position.y); - randomizePopup("obj_position_y_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].position.y, &objects_dict[current_obj].is_dirty)); - randomizerParams("obj_position_y_" + std::to_string(objects_dict[current_obj].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_position_y_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##obj_position_z", &objects_dict[current_obj].position.z); - randomizePopup("obj_position_z_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].position.z, &objects_dict[current_obj].is_dirty)); - randomizerParams("obj_position_z_" + std::to_string(objects_dict[current_obj].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_position_z_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Object Position"); - // ####### OBJECT ORIENTATION ####### // - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##obj_orientation_x", &objects_dict[current_obj].orientation.x); - randomizePopup("obj_orientation_x_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].orientation.x, &objects_dict[current_obj].is_dirty)); - randomizerParams("obj_orientation_x_" + std::to_string(objects_dict[current_obj].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_x_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##obj_orientation_y", &objects_dict[current_obj].orientation.y); - randomizePopup("obj_orientation_y_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].orientation.y, &objects_dict[current_obj].is_dirty)); - randomizerParams("obj_orientation_y_" + std::to_string(objects_dict[current_obj].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_y_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##obj_orientation_z", &objects_dict[current_obj].orientation.z); - randomizePopup("obj_orientation_z_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].orientation.z, &objects_dict[current_obj].is_dirty)); - randomizerParams("obj_orientation_z_" + std::to_string(objects_dict[current_obj].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_z_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Object Orientation"); - if (objects_dict[current_obj].position != objects_dict[current_obj].prev_position || objects_dict[current_obj].orientation != objects_dict[current_obj].prev_orientation || - objects_dict[current_obj].scale != objects_dict[current_obj].prev_scale || objects_dict[current_obj].color != objects_dict[current_obj].prev_color) { - objects_dict[current_obj].is_dirty = true; - } - if (objects_dict[current_obj].is_dirty && !ImGui::IsAnyItemActive() && !ImGui::IsAnyItemFocused()) { - updateObject(current_obj); - } - } - } + objectTab(); ImGui::EndTabItem(); } -// if (enable_plantarchitecture){ -#ifdef ENABLE_PLANT_ARCHITECTURE // CANOPY TAB if (ImGui::BeginTabItem("Canopy")) { current_tab = "Canopy"; - dropDown("##canopy_combo", current_canopy, canopy_labels_set); - ImGui::SameLine(); - if (ImGui::Button("Add Canopy")) { - addCanopy(); - } - if (!current_canopy.empty()) { - if (ImGui::Button("Update Canopy")) { - updateCanopy(current_canopy); - is_dirty = true; - canopy_dict[current_canopy].is_dirty = false; - } - ImGui::SameLine(); - if (ImGui::Button("Delete Canopy")) { - deleteCanopy(current_canopy); - updatePrimitiveTypes(); - is_dirty = true; - context->markGeometryDirty(); - // refreshVisualization(); - } - if (canopy_dict[current_canopy].is_dirty) { - ImGui::SameLine(); - ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255)); // Red text - ImGui::Text("update required"); - ImGui::PopStyleColor(); - } - ImGui::SetNextItemWidth(100); - std::string prev_canopy_name = canopy_dict[current_canopy].label; - ImGui::InputText("##canopy_name", &canopy_dict[current_canopy].label); - if (canopy_dict[current_canopy].label != prev_canopy_name && canopy_labels_set.find(canopy_dict[current_canopy].label) == canopy_labels_set.end() && !canopy_dict[current_canopy].label.empty()) { - canopy temp = canopy_dict[current_canopy]; - current_canopy = canopy_dict[prev_canopy_name].label; - std::map::iterator current_canopy_iter = canopy_dict.find(prev_canopy_name); - if (current_canopy_iter != canopy_dict.end()) { - canopy_dict.erase(current_canopy_iter); - } - canopy_dict[current_canopy] = temp; + canopyTab(); - canopy_labels_set.erase(prev_canopy_name); - canopy_labels_set.insert(current_canopy); - } else { - canopy_dict[current_canopy].label = prev_canopy_name; - } - ImGui::SameLine(); - ImGui::Text("Canopy Name"); - // ####### PLANT LIBRARY NAME ####### // - ImGui::SetNextItemWidth(250); - // ImGui::InputText("Plant Library", &plant_library_names[canopy_labels_dict[current_canopy]]); - std::string prev_lib = canopy_dict[current_canopy].library_name_verbose; - dropDown("Plant Library###dropdown", canopy_dict[current_canopy].library_name_verbose, plant_types_verbose); - if (canopy_dict[current_canopy].library_name_verbose != prev_lib) - canopy_dict[current_canopy].is_dirty = true; - canopy_dict[current_canopy].library_name = plant_type_lookup[canopy_dict[current_canopy].library_name_verbose]; - // ######### CANOPY DATA GROUP ####### // - ImGui::SetNextItemWidth(100); - std::string prev_canopy_data_group = canopy_dict[current_canopy].data_group; - ImGui::InputText("##canopy_data_group", &canopy_dict[current_canopy].data_group); - if (canopy_dict[current_canopy].data_group == "All" || canopy_dict[current_canopy].data_group.empty()) { - canopy_dict[current_canopy].data_group = prev_canopy_data_group; - } - if (!canopy_dict[current_canopy].data_group.empty() && prev_canopy_data_group != canopy_dict[current_canopy].data_group) { - std::string new_data_group = canopy_dict[current_canopy].data_group; - std::vector canopy_primID_vec; - for (int i = 0; i < canopy_dict[current_canopy].IDs.size(); i++) { - std::vector new_canopy_primIDs = plantarchitecture->getAllPlantUUIDs(canopy_dict[current_canopy].IDs[i]); - canopy_primID_vec.insert(canopy_primID_vec.end(), new_canopy_primIDs.begin(), new_canopy_primIDs.end()); - } - context->setPrimitiveData(canopy_primID_vec, "data_group", new_data_group); - } - ImGui::SameLine(); - ImGui::Text("Data Group"); - // ####### CANOPY ORIGIN ####### // - vec3 prev_canopy_origin_ = vec3(canopy_dict[current_canopy].origin); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##canopy_origin_x", &canopy_dict[current_canopy].origin.x); - randomizePopup("canopy_origin_x_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].origin.x)); - randomizerParams("canopy_origin_x_" + std::to_string(canopy_dict[current_canopy].idx)); - ImGui::OpenPopupOnItemClick(("randomize_canopy_origin_x_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##canopy_origin_y", &canopy_dict[current_canopy].origin.y); - randomizePopup("canopy_origin_y_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].origin.y)); - randomizerParams("canopy_origin_y_" + std::to_string(canopy_dict[current_canopy].idx)); - ImGui::OpenPopupOnItemClick(("randomize_canopy_origin_y_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##canopy_origin_z", &canopy_dict[current_canopy].origin.z); - randomizePopup("canopy_origin_z_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].origin.z)); - randomizerParams("canopy_origin_z_" + std::to_string(canopy_dict[current_canopy].idx)); - ImGui::OpenPopupOnItemClick(("randomize_canopy_origin_z_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Canopy Origin"); - if (prev_canopy_origin_ != canopy_dict[current_canopy].origin) { - canopy_dict[current_canopy].is_dirty = true; - } - // ####### PLANT COUNT ####### // - int2 prev_plant_count_ = int2(canopy_dict[current_canopy].plant_count); - ImGui::SetNextItemWidth(100); - ImGui::InputInt("##plant_count_x", &canopy_dict[current_canopy].plant_count.x); - canopy_dict[current_canopy].plant_count.x = std::max(canopy_dict[current_canopy].plant_count.x, 1); - randomizePopup("plant_count_x_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].plant_count.x)); - randomizerParams("plant_count_x_" + std::to_string(canopy_dict[current_canopy].idx)); - ImGui::OpenPopupOnItemClick(("randomize_plant_count_x_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(100); - ImGui::InputInt("##plant_count_y", &canopy_dict[current_canopy].plant_count.y); - canopy_dict[current_canopy].plant_count.y = std::max(canopy_dict[current_canopy].plant_count.y, 1); - randomizePopup("plant_count_y_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].plant_count.y)); - randomizerParams("plant_count_y_" + std::to_string(canopy_dict[current_canopy].idx)); - ImGui::OpenPopupOnItemClick(("randomize_plant_count_y_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Plant Count"); - if (prev_plant_count_ != canopy_dict[current_canopy].plant_count) { - canopy_dict[current_canopy].is_dirty = true; - } - // ####### PLANT SPACING ####### // - vec2 prev_plant_spacing_ = vec2(canopy_dict[current_canopy].plant_spacing); - ImGui::SetNextItemWidth(50); - ImGui::InputFloat("##plant_spacing_x", &canopy_dict[current_canopy].plant_spacing.x); - randomizePopup("plant_spacing_x_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].plant_spacing.x)); - randomizerParams("plant_spacing_x_" + std::to_string(canopy_dict[current_canopy].idx)); - ImGui::OpenPopupOnItemClick(("randomize_plant_spacing_x_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(50); - ImGui::InputFloat("##plant_spacing_y", &canopy_dict[current_canopy].plant_spacing.y); - randomizePopup("plant_spacing_y_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].plant_spacing.y)); - randomizerParams("plant_spacing_y_" + std::to_string(canopy_dict[current_canopy].idx)); - ImGui::OpenPopupOnItemClick(("randomize_plant_spacing_y_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Plant Spacing"); - if (prev_plant_spacing_ != canopy_dict[current_canopy].plant_spacing) { - canopy_dict[current_canopy].is_dirty = true; - } - // ####### PLANT AGE ####### // - float prev_age_ = canopy_dict[current_canopy].age; - ImGui::SetNextItemWidth(80); - ImGui::InputFloat("Plant Age", &canopy_dict[current_canopy].age); - randomizePopup("plant_age_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].age)); - randomizerParams("plant_age_" + std::to_string(canopy_dict[current_canopy].idx)); - ImGui::OpenPopupOnItemClick(("randomize_plant_age_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); - if (prev_age_ != canopy_dict[current_canopy].age) { - canopy_dict[current_canopy].is_dirty = true; - } - // ####### GROUND CLIPPING HEIGHT ####### // - float prev_ground_clipping_height_ = canopy_dict[current_canopy].ground_clipping_height; - ImGui::SetNextItemWidth(80); - ImGui::InputFloat("Ground Clipping Height", &canopy_dict[current_canopy].ground_clipping_height); - randomizePopup("ground_clipping_height_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].ground_clipping_height)); - randomizerParams("ground_clipping_height_" + std::to_string(canopy_dict[current_canopy].idx)); - ImGui::OpenPopupOnItemClick(("randomize_ground_clipping_height_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); - if (prev_ground_clipping_height_ != canopy_dict[current_canopy].ground_clipping_height) { - canopy_dict[current_canopy].is_dirty = true; - } - if (ImGui::Button("Save Canopy to OBJ/PLY File")) { - std::string new_obj_file = save_as_file_dialog(std::vector{"OBJ", "PLY"}); - if (!new_obj_file.empty()) { - std::string file_extension = new_obj_file; - size_t last_obj_file = file_extension.rfind('.'); - if (last_obj_file != std::string::npos) { - file_extension = file_extension.substr(last_obj_file + 1); - } - if (file_extension == "obj" || file_extension == "ply") { - if (!std::filesystem::exists(new_obj_file)) { - // Create file - std::ofstream outFile(new_obj_file); - } - if (!save_plants_individually) { - saveCanopy(new_obj_file, canopy_dict[current_canopy].IDs, canopy_dict[current_canopy].origin, file_extension); - } else { - saveCanopy(new_obj_file, canopy_dict[current_canopy].IDs, canopy_dict[current_canopy].individual_plant_locations, file_extension); - } - } else { - // Needs to be a obj or ply file - std::cout << "Not a valid file type. Object must be saved to .obj or .ply file." << std::endl; - } - } else { - // Not a valid file - std::cout << "Not a valid file." << std::endl; - } - } - ImGui::SameLine(); - ImGui::Checkbox("Save plants individually", &save_plants_individually); - } ImGui::EndTabItem(); } -// } //PLANT_ARCHITECTURE -#endif // PLANT_ARCHITECTURE -#ifdef ENABLE_RADIATION_MODEL if (enable_radiation) { if (ImGui::BeginTabItem("Radiation")) { current_tab = "Radiation"; - // LOAD XML LIBRARY FILE - ImGui::SetNextItemWidth(60); - if (ImGui::Button("Load XML Library File")) { - std::string new_xml_library_file = file_dialog(); - if (!new_xml_library_file.empty() && std::filesystem::exists(new_xml_library_file)) { - if (xml_library_files.find(new_xml_library_file) == xml_library_files.end()) { - xml_library_files.insert(new_xml_library_file); - std::vector current_spectra_file = get_xml_node_values(new_xml_library_file, "label", "globaldata_vec2"); - for (int i = 0; i < current_spectra_file.size(); i++) { - possible_spectra.insert(current_spectra_file[i]); - } - } - context->loadXML(new_xml_library_file.c_str()); - } - } - // ####### GLOBAL PROPERTIES ####### // - ImGui::SetWindowFontScale(1.25f); - ImGui::Text("Global Properties:"); - ImGui::SetWindowFontScale(1.0f); - // ####### ENFORCE PERIODIC BOUNDARY CONDITION ####### // - ImGui::Text("Enforce Periodic Boundary Condition:"); - ImGui::SameLine(); - bool prev_cond_x = enforce_periodic_boundary_x; - ImGui::Checkbox("x###periodic_boundary_x", &enforce_periodic_boundary_x); - ImGui::SameLine(); - bool prev_cond_y = enforce_periodic_boundary_y; - ImGui::Checkbox("y###periodic_boundary_y", &enforce_periodic_boundary_y); - if (prev_cond_x != enforce_periodic_boundary_x || prev_cond_y != enforce_periodic_boundary_y) { - if (enforce_periodic_boundary_x && enforce_periodic_boundary_y) - radiation->enforcePeriodicBoundary("xy"); - else if (enforce_periodic_boundary_x) - radiation->enforcePeriodicBoundary("x"); - else if (enforce_periodic_boundary_y) - radiation->enforcePeriodicBoundary("y"); - else - radiation->enforcePeriodicBoundary(""); - } - // ####### DIFFUSE EXTINCTION COEFFICIENT ####### // - ImGui::SetNextItemWidth(60); - float prev_value = diffuse_extinction_coeff; - ImGui::InputFloat("Diffuse Extinction Coefficient", &diffuse_extinction_coeff); - if (prev_value != diffuse_extinction_coeff) { - context->setGlobalData("diffuse_extinction_coeff", diffuse_extinction_coeff); - } - randomizePopup("diffuse_extinction_coeff", createTaggedPtr(&diffuse_extinction_coeff)); - randomizerParams("diffuse_extinction_coeff"); - ImGui::OpenPopupOnItemClick("randomize_diffuse_extinction_coeff", ImGuiPopupFlags_MouseButtonRight); - // ####### AIR TURBIDITY ####### // - ImGui::SetNextItemWidth(60); - prev_value = air_turbidity; - ImGui::InputFloat("Air Turbidity", &air_turbidity); - if (prev_value != air_turbidity) { - if (air_turbidity > 0) { - context->setGlobalData("air_turbidity", air_turbidity); - } else if (air_turbidity < 0) { // try calibration - if (context->doesTimeseriesVariableExist("net_radiation")) { - air_turbidity = solarposition->calibrateTurbidityFromTimeseries("net_radiation"); - if (air_turbidity > 0 && air_turbidity < 1) { - context->setGlobalData("air_turbidity", air_turbidity); - } - } - } - } - randomizePopup("air_turbidity", createTaggedPtr(&air_turbidity)); - randomizerParams("air_turbidity"); - ImGui::OpenPopupOnItemClick("randomize_air_turbidity", ImGuiPopupFlags_MouseButtonRight); - // ####### SOLAR DIRECT SPECTRUM ####### // - ImGui::SetNextItemWidth(250); - // ImGui::InputText("Solar Direct Spectrum", &solar_direct_spectrum); - if (ImGui::BeginCombo("##combo_solar_direct_spectrum", solar_direct_spectrum.c_str())) { - for (auto &spectra: possible_spectra) { - bool is_solar_direct_spectrum_selected = (solar_direct_spectrum == spectra); - if (ImGui::Selectable(spectra.c_str(), is_solar_direct_spectrum_selected)) - solar_direct_spectrum = spectra; - if (is_solar_direct_spectrum_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Solar Direct Spectrum"); - // ####### BAND PROPERTIES ####### // - ImGui::SetWindowFontScale(1.25f); - ImGui::Text("Add Band:"); - ImGui::SetWindowFontScale(1.0f); - // ####### ADD BAND ####### // - toggle_button("##enable_wavelength", &enable_wavelength); - ImGui::SameLine(); - if (enable_wavelength) { - ImGui::Text("Wavelength Min:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##wavelength_min", &wavelength_min); - ImGui::SameLine(); - ImGui::Text("Max:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##wavelength_max", &wavelength_max); - } else { - ImGui::Text("No Specified Wavelength"); - } - // - ImGui::Text("Label:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(100); - ImGui::InputText("##new_band_label", &new_band_label); - ImGui::SameLine(); - ImGui::Text("Emission:"); - ImGui::SameLine(); - ImGui::Checkbox("##enable_emission", &enable_emission); - ImGui::SameLine(); - if (ImGui::Button("Add Band")) { - if (enable_wavelength) { - addBand(new_band_label, wavelength_min, wavelength_max, enable_emission); - } else { - addBand(new_band_label, enable_emission); - bandlabels_set_wavelength.insert(new_band_label); - } - } - // ####### BAND PROPERTIES ####### // - ImGui::SetWindowFontScale(1.25f); - ImGui::Text("Band Properties:"); - ImGui::SetWindowFontScale(1.0f); - // ####### SELECT BAND ####### // - if (ImGui::BeginCombo("##combo_current_band", current_band.c_str())) { - for (std::string band: bandlabels_set) { - bool is_current_band_selected = (current_band == band); - if (ImGui::Selectable(band.c_str(), is_current_band_selected)) - current_band = band; - if (is_current_band_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Select Band"); - // ####### DIRECT RAY COUNT ####### // - int prev_direct_ray_count; - ImGui::SetNextItemWidth(100); - if (current_band == "All") { - prev_direct_ray_count = direct_ray_count; - ImGui::InputInt("Direct Ray Count", &direct_ray_count); - randomizePopup("direct_ray_count", createTaggedPtr(&direct_ray_count)); - randomizerParams("direct_ray_count"); - ImGui::OpenPopupOnItemClick("randomize_direct_ray_count", ImGuiPopupFlags_MouseButtonRight); - if (direct_ray_count != prev_direct_ray_count) { - for (std::string band: bandlabels) { - radiation->setDirectRayCount(band, direct_ray_count); - direct_ray_count_dict[band] = direct_ray_count; - } - } - } else { - prev_direct_ray_count = direct_ray_count_dict[current_band]; - ImGui::InputInt("Direct Ray Count", &direct_ray_count_dict[current_band]); - randomizePopup("direct_ray_count_" + current_band, createTaggedPtr(&direct_ray_count_dict[current_band])); - randomizerParams("direct_ray_count_" + current_band); - ImGui::OpenPopupOnItemClick(("randomize_direct_ray_count_" + current_band).c_str(), ImGuiPopupFlags_MouseButtonRight); - if (direct_ray_count_dict[current_band] != prev_direct_ray_count) { - radiation->setDirectRayCount(current_band, direct_ray_count_dict[current_band]); - } - } - // ####### DIFFUSE RAY COUNT ####### // - ImGui::SetNextItemWidth(100); - int prev_diffuse_ray_count; - if (current_band == "All") { - prev_diffuse_ray_count = diffuse_ray_count; - ImGui::InputInt("Diffuse Ray Count", &diffuse_ray_count); - randomizePopup("diffuse_ray_count", createTaggedPtr(&diffuse_ray_count)); - randomizerParams("diffuse_ray_count"); - ImGui::OpenPopupOnItemClick("randomize_diffuse_ray_count", ImGuiPopupFlags_MouseButtonRight); - if (diffuse_ray_count != prev_diffuse_ray_count) { - for (std::string band: bandlabels) { - radiation->setDiffuseRayCount(band, diffuse_ray_count); - diffuse_ray_count_dict[band] = diffuse_ray_count; - } - } - } else { - prev_diffuse_ray_count = diffuse_ray_count_dict[current_band]; - ImGui::InputInt("Diffuse Ray Count", &diffuse_ray_count_dict[current_band]); - randomizePopup("diffuse_ray_count_" + current_band, createTaggedPtr(&diffuse_ray_count_dict[current_band])); - randomizerParams("diffuse_ray_count_" + current_band); - ImGui::OpenPopupOnItemClick(("randomize_diffuse_ray_count_" + current_band).c_str(), ImGuiPopupFlags_MouseButtonRight); - if (diffuse_ray_count_dict[current_band] != prev_diffuse_ray_count) { - radiation->setDiffuseRayCount(current_band, diffuse_ray_count_dict[current_band]); - } - } - // ####### SCATTERING DEPTH ####### // - ImGui::SetNextItemWidth(100); - int prev_scattering_depth; - if (current_band == "All") { - prev_scattering_depth = scattering_depth; - ImGui::InputInt("Scattering Depth", &scattering_depth); - randomizePopup("scattering_depth", createTaggedPtr(&scattering_depth)); - randomizerParams("scattering_depth"); - ImGui::OpenPopupOnItemClick("randomize_scattering_depth", ImGuiPopupFlags_MouseButtonRight); - if (scattering_depth <= 0) { - scattering_depth = prev_scattering_depth; - } - if (prev_scattering_depth != scattering_depth) { - for (std::string band: bandlabels) { - radiation->setScatteringDepth(band, scattering_depth); - scattering_depth_dict[band] = scattering_depth; - } - } - } else { - prev_scattering_depth = scattering_depth_dict[current_band]; - ImGui::InputInt("Scattering Depth", &scattering_depth_dict[current_band]); - randomizePopup("scattering_depth_" + current_band, createTaggedPtr(&scattering_depth_dict[current_band])); - randomizerParams("scattering_depth_" + current_band); - ImGui::OpenPopupOnItemClick(("randomize_scattering_depth_" + current_band).c_str(), ImGuiPopupFlags_MouseButtonRight); - if (scattering_depth_dict[current_band] <= 0) { // scattering depth must be >0 - scattering_depth_dict[current_band] = prev_scattering_depth; - } - if (prev_scattering_depth != scattering_depth_dict[current_band]) { - radiation->setScatteringDepth(current_band, scattering_depth_dict[current_band]); - } - } - // ####### RADIATIVE PROPERTIES ####### // - ImGui::SetWindowFontScale(1.25f); - ImGui::Text("Radiative Properties:"); - ImGui::SetWindowFontScale(1.0f); - ImGui::SetNextItemWidth(100); - // ######### SELECT DATA GROUP ############// - if (ImGui::Button("Refresh###data_groups_refresh")) { - updatePrimitiveTypes(); - updateDataGroups(); - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(150); - if (ImGui::BeginCombo("##data_group_primitive", current_data_group.c_str())) { - for (std::string data_group: data_groups_set) { - bool is_data_group_selected = (current_data_group == data_group); - if (ImGui::Selectable(data_group.c_str(), is_data_group_selected)) - current_data_group = data_group; - if (is_data_group_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(100); - ImGui::Text("Select Data Group"); - // default primitive data group - // ######### SELECT PRIMITIVE ############// - if (ImGui::Button("Refresh")) { - updatePrimitiveTypes(); - updateDataGroups(); - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(150); - if (ImGui::BeginCombo("##combo_primitive", current_primitive.c_str())) { - for (int m = 0; m < primitive_names.size(); m++) { - bool is_primitive_selected = (current_primitive == primitive_names[m]); - if (ImGui::Selectable(primitive_names[m].c_str(), is_primitive_selected)) - current_primitive = primitive_names[m]; - if (is_primitive_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(100); - ImGui::Text("Select Primitive Type"); - if (current_data_group == "All") { - // REFLECTIVITY - ImGui::Text("Reflectivity:"); - std::string toggle_display_reflectivity = "Manual Entry"; - bool reflectivity_continuous = primitive_continuous[current_primitive][0]; - toggle_button("##reflectivity_toggle", &reflectivity_continuous); - if (reflectivity_continuous != primitive_continuous[current_primitive][0]) { - if (current_primitive == "All") { - for (auto &prim_values: primitive_continuous) { - primitive_continuous[prim_values.first][0] = reflectivity_continuous; - } - } - primitive_continuous[current_primitive][0] = reflectivity_continuous; - } - if (primitive_continuous[current_primitive][0]) { - toggle_display_reflectivity = "File Entry"; - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(250); - if (!primitive_continuous[current_primitive][0]) { - ImGui::Text("Select band:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - if (ImGui::BeginCombo("##combo_band_reflectivity", current_band_reflectivity.c_str())) { - for (int n = 0; n < bandlabels.size(); n++) { - bool is_band_selected = (current_band_reflectivity == bandlabels[n]); - if (ImGui::Selectable(bandlabels[n].c_str(), is_band_selected)) - current_band_reflectivity = bandlabels[n]; - if (is_band_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Enter value:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); - if (current_primitive == "All") { - float prev_reflectivity = reflectivity; - ImGui::InputFloat("##reflectivity_all", &reflectivity); - if (reflectivity != prev_reflectivity) { - for (auto &prim_values: primitive_values[current_band_reflectivity]) { - primitive_values[current_band_reflectivity][prim_values.first][0] = reflectivity; - } - } - } else { - ImGui::InputFloat("##reflectivity", &primitive_values[current_band_reflectivity][current_primitive][0]); - } - } else { - std::string reflectivity_prev = primitive_spectra[current_primitive][0]; - if (ImGui::BeginCombo("##reflectivity_combo_all", reflectivity_prev.c_str())) { - for (auto &spectra: possible_spectra) { - bool is_spectra_selected = (primitive_spectra[current_primitive][0] == spectra); - if (ImGui::Selectable(spectra.c_str(), is_spectra_selected)) - primitive_spectra[current_primitive][0] = spectra; - if (is_spectra_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - if (current_primitive == "All" && reflectivity_prev != primitive_spectra[current_primitive][0]) { - for (auto &prim_spectrum: primitive_spectra) { - primitive_spectra[prim_spectrum.first][0] = primitive_spectra[current_primitive][0]; - } - } - } - ImGui::SameLine(); - ImGui::Text("%s", toggle_display_reflectivity.c_str()); - // TRANSMISSIVITY - ImGui::Text("Transmissivity:"); - std::string toggle_display_transmissivity = "Manual Entry"; - bool transmissivity_continuous = primitive_continuous[current_primitive][1]; - toggle_button("##transmissivity_toggle", &transmissivity_continuous); - if (transmissivity_continuous != primitive_continuous[current_primitive][1]) { - if (current_primitive == "All") { - for (auto &prim_values: primitive_continuous) { - primitive_continuous[prim_values.first][1] = transmissivity_continuous; - } - } - primitive_continuous[current_primitive][1] = transmissivity_continuous; - } - if (primitive_continuous[current_primitive][1]) { - toggle_display_transmissivity = "File Entry"; - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(250); - if (!primitive_continuous[current_primitive][1]) { - ImGui::Text("Select band:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - if (ImGui::BeginCombo("##combo_band_transmissivity", current_band_transmissivity.c_str())) { - for (int n = 0; n < bandlabels.size(); n++) { - bool is_band_selected = (current_band_transmissivity == bandlabels[n]); - if (ImGui::Selectable(bandlabels[n].c_str(), is_band_selected)) - current_band_transmissivity = bandlabels[n]; - if (is_band_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Enter value:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); - if (current_primitive == "All") { - float prev_transmissivity = transmissivity; - ImGui::InputFloat("##transmissivity_all", &transmissivity); - if (transmissivity != prev_transmissivity) { - for (auto &prim_values: primitive_values[current_band_transmissivity]) { - primitive_values[current_band_transmissivity][prim_values.first][1] = transmissivity; - } - } - } else { - ImGui::InputFloat("##transmissivity", &primitive_values[current_band_transmissivity][current_primitive][1]); - } - } else { - std::string transmissivity_prev = primitive_spectra[current_primitive][1]; - if (ImGui::BeginCombo("##transmissivity_combo", transmissivity_prev.c_str())) { - for (auto &spectra: possible_spectra) { - bool is_spectra_selected = (primitive_spectra[current_primitive][1] == spectra); - if (ImGui::Selectable(spectra.c_str(), is_spectra_selected)) - primitive_spectra[current_primitive][1] = spectra; - if (is_spectra_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - if (current_primitive == "All" && transmissivity_prev != primitive_spectra[current_primitive][1]) { - for (auto &prim_spectrum: primitive_spectra) { - primitive_spectra[prim_spectrum.first][1] = primitive_spectra[current_primitive][1]; - } - } - } - ImGui::SameLine(); - ImGui::Text("%s", toggle_display_transmissivity.c_str()); - // EMISSIVITY - ImGui::Text("Emissivity:"); - // ImGui::SetNextItemWidth(250); - // ImGui::Text(""); - ImGui::Dummy(ImVec2(35.f, 0.f)); - ImGui::SameLine(); - ImGui::Text("Select band:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - if (ImGui::BeginCombo("##combo_band_emissivity", current_band_emissivity.c_str())) { - for (std::string band: bandlabels_set_emissivity) { - bool is_band_selected = (current_band_emissivity == band); - if (ImGui::Selectable(band.c_str(), is_band_selected)) - current_band_emissivity = band; - if (is_band_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Enter value:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); - if (current_primitive == "All") { - float prev_emissivity = emissivity; - ImGui::InputFloat("##emissivity_all", &emissivity); - if (emissivity != prev_emissivity) { - for (auto &prim_values: primitive_values[current_band_emissivity]) { - primitive_values[current_band_emissivity][prim_values.first][2] = emissivity; - } - } - } else { - ImGui::InputFloat("##emissivity", &primitive_values[current_band_emissivity][current_primitive][2]); - } - ImGui::SameLine(); - ImGui::Text("Manual Entry"); - } else { // specific data group - // REFLECTIVITY - ImGui::Text("Reflectivity:"); - std::string toggle_display_reflectivity = "Manual Entry"; - bool reflectivity_continuous = primitive_continuous_dict[current_data_group][current_primitive][0]; - toggle_button("##reflectivity_toggle", &reflectivity_continuous); - if (reflectivity_continuous != primitive_continuous_dict[current_data_group][current_primitive][0]) { - if (current_primitive == "All") { - for (auto &prim_values: primitive_continuous_dict[current_data_group]) { - primitive_continuous_dict[current_data_group][prim_values.first][0] = reflectivity_continuous; - } - } - primitive_continuous_dict[current_data_group][current_primitive][0] = reflectivity_continuous; - } - if (primitive_continuous_dict[current_data_group][current_primitive][0]) { - toggle_display_reflectivity = "File Entry"; - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(250); - if (!primitive_continuous_dict[current_data_group][current_primitive][0]) { - ImGui::Text("Select band:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - if (ImGui::BeginCombo("##combo_band_reflectivity", current_band_reflectivity.c_str())) { - for (int n = 0; n < bandlabels.size(); n++) { - bool is_band_selected = (current_band_reflectivity == bandlabels[n]); - if (ImGui::Selectable(bandlabels[n].c_str(), is_band_selected)) - current_band_reflectivity = bandlabels[n]; - if (is_band_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Enter value:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); - if (current_primitive == "All") { - float prev_reflectivity = reflectivity; - ImGui::InputFloat("##reflectivity_all", &reflectivity); - if (reflectivity != prev_reflectivity) { - for (auto &prim_values: primitive_values_dict[current_data_group][current_band_reflectivity]) { - primitive_values_dict[current_data_group][current_band_reflectivity][prim_values.first][0] = reflectivity; - } - } - } else { - ImGui::InputFloat("##reflectivity", &primitive_values_dict[current_data_group][current_band_reflectivity][current_primitive][0]); - } - } else { - std::string reflectivity_prev = primitive_spectra_dict[current_data_group][current_primitive][0]; - if (ImGui::BeginCombo("##reflectivity_combo", reflectivity_prev.c_str())) { - for (auto &spectra: possible_spectra) { - bool is_spectra_selected = (primitive_spectra_dict[current_data_group][current_primitive][0] == spectra); - if (ImGui::Selectable(spectra.c_str(), is_spectra_selected)) - primitive_spectra_dict[current_data_group][current_primitive][0] = spectra; - if (is_spectra_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - if (current_primitive == "All" && reflectivity_prev != primitive_spectra_dict[current_data_group][current_primitive][0]) { - for (auto &prim_spectrum: primitive_spectra_dict[current_data_group]) { - primitive_spectra_dict[current_data_group][prim_spectrum.first][0] = primitive_spectra_dict[current_data_group][current_primitive][0]; - } - } - } - ImGui::SameLine(); - ImGui::TextUnformatted("%s", toggle_display_reflectivity.c_str()); - // TRANSMISSIVITY - ImGui::Text("Transmissivity:"); - std::string toggle_display_transmissivity = "Manual Entry"; - bool transmissivity_continuous = primitive_continuous_dict[current_data_group][current_primitive][1]; - toggle_button("##transmissivity_toggle", &transmissivity_continuous); - if (transmissivity_continuous != primitive_continuous_dict[current_data_group][current_primitive][1]) { - if (current_primitive == "All") { - for (auto &prim_values: primitive_continuous_dict[current_data_group]) { - primitive_continuous_dict[current_data_group][prim_values.first][1] = transmissivity_continuous; - } - } - primitive_continuous_dict[current_data_group][current_primitive][1] = transmissivity_continuous; - } - if (primitive_continuous_dict[current_data_group][current_primitive][1]) { - toggle_display_transmissivity = "File Entry"; - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(250); - if (!primitive_continuous_dict[current_data_group][current_primitive][1]) { - ImGui::Text("Select band:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - if (ImGui::BeginCombo("##combo_band_transmissivity", current_band_transmissivity.c_str())) { - for (int n = 0; n < bandlabels.size(); n++) { - bool is_band_selected = (current_band_transmissivity == bandlabels[n]); - if (ImGui::Selectable(bandlabels[n].c_str(), is_band_selected)) - current_band_transmissivity = bandlabels[n]; - if (is_band_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Enter value:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); - if (current_primitive == "All") { - float prev_transmissivity = transmissivity; - ImGui::InputFloat("##transmissivity_all", &transmissivity); - if (transmissivity != prev_transmissivity) { - for (auto &prim_values: primitive_values_dict[current_data_group][current_band_transmissivity]) { - primitive_values_dict[current_data_group][current_band_transmissivity][prim_values.first][1] = transmissivity; - } - } - } else { - ImGui::InputFloat("##transmissivity", &primitive_values_dict[current_data_group][current_band_transmissivity][current_primitive][1]); - } - } else { - std::string transmissivity_prev = primitive_spectra_dict[current_data_group][current_primitive][1]; - if (ImGui::BeginCombo("##transmissivity_combo", transmissivity_prev.c_str())) { - for (auto &spectra: possible_spectra) { - bool is_spectra_selected = (primitive_spectra_dict[current_data_group][current_primitive][1] == spectra); - if (ImGui::Selectable(spectra.c_str(), is_spectra_selected)) - primitive_spectra_dict[current_data_group][current_primitive][1] = spectra; - if (is_spectra_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - if (current_primitive == "All" && transmissivity_prev != primitive_spectra_dict[current_data_group][current_primitive][1]) { - for (auto &prim_spectrum: primitive_spectra_dict[current_data_group]) { - primitive_spectra_dict[current_data_group][prim_spectrum.first][1] = primitive_spectra_dict[current_data_group][current_primitive][1]; - } - } - } - ImGui::SameLine(); - ImGui::TextUnformatted("%s", toggle_display_transmissivity.c_str()); - // EMISSIVITY - ImGui::Text("Emissivity:"); - // ImGui::SetNextItemWidth(250); - // ImGui::Text(""); - ImGui::Dummy(ImVec2(35.f, 0.f)); - ImGui::SameLine(); - ImGui::Text("Select band:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - if (ImGui::BeginCombo("##combo_band_emissivity", current_band_emissivity.c_str())) { - for (std::string band: bandlabels_set_emissivity) { - bool is_band_selected = (current_band_emissivity == band); - if (ImGui::Selectable(band.c_str(), is_band_selected)) - current_band_emissivity = band; - if (is_band_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Enter value:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(80); - if (current_primitive == "All") { - float prev_emissivity = emissivity; - ImGui::InputFloat("##emissivity_all", &emissivity); - if (emissivity != prev_emissivity) { - for (auto &prim_values: primitive_values_dict[current_data_group][current_band_emissivity]) { - primitive_values_dict[current_data_group][current_band_emissivity][prim_values.first][2] = emissivity; - } - } - } else { - ImGui::InputFloat("##emissivity", &primitive_values_dict[current_data_group][current_band_emissivity][current_primitive][2]); - } - ImGui::SameLine(); - ImGui::Text("Manual Entry"); - } + radiationTab(); ImGui::EndTabItem(); } - } // RADIATION_MODEL -#endif // RADIATION_MODEL + } if (enable_radiation) { // RIG TAB if (ImGui::BeginTabItem("Rig")) { current_tab = "Rig"; - if (ImGui::BeginCombo("##rig_combo", current_rig.c_str())) { - for (auto rig_label: rig_labels_set) { - bool is_rig_selected = (current_rig == rig_label); - if (ImGui::Selectable(rig_label.c_str(), is_rig_selected)) - current_rig = rig_label; - current_cam_position = "0"; - if (is_rig_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - if (ImGui::Button("Add Rig")) { - std::string default_rig_label = "rig"; - std::string new_rig_label = "rig_0"; - int count = 0; - while (rig_dict.find(new_rig_label) != rig_dict.end()) { - count++; - new_rig_label = default_rig_label + "_" + std::to_string(count); - } - rig_dict.insert({new_rig_label, scast(rig_labels.size())}); - camera_positions.push_back(camera_position); - camera_lookats.push_back(camera_lookat); - camera_labels.push_back(camera_label); - camera_position_vec.push_back(camera_position_vec[rig_dict[current_rig]]); - camera_lookat_vec.push_back(camera_lookat_vec[rig_dict[current_rig]]); - rig_labels.push_back(new_rig_label); - rig_labels_set.insert(new_rig_label); - rig_camera_labels.push_back(rig_camera_labels[rig_dict[current_rig]]); - rig_light_labels.push_back(rig_light_labels[rig_dict[current_rig]]); - keypoint_frames.push_back(keypoint_frames[rig_dict[current_rig]]); - num_images_vec.push_back(num_images_vec[rig_dict[current_rig]]); - rig_colors.push_back(rig_colors[rig_dict[current_rig]]); - rig_position_noise.push_back(std::vector{distribution{}, distribution{}, distribution{}}); - rig_lookat_noise.push_back(std::vector{distribution{}, distribution{}, distribution{}}); - // current_rig = new_rig_label; - std::string parent = "rig"; - pugi::xml_node rig_block = helios.child(parent.c_str()); - pugi::xml_node new_rig_node = helios.append_copy(rig_block); - std::string name = "label"; - pugi::xml_attribute node_label = new_rig_node.attribute(name.c_str()); - node_label.set_value(new_rig_label.c_str()); - current_rig = new_rig_label; - } - if (!current_rig.empty()) { - // ##### UPDATE RIG ######// - // if (ImGui::Button("Update Rig")){ - // updateRigs(); - // } - // ImGui::SameLine(); - if (ImGui::Button("Delete Rig")) { - deleteRig(current_rig); - } - // ##### RIG NAME ######// - ImGui::SetNextItemWidth(100); - std::string prev_rig_name = rig_labels[rig_dict[current_rig]]; - ImGui::InputText("##rig_name", &rig_labels[rig_dict[current_rig]]); - if (rig_labels[rig_dict[current_rig]] != prev_rig_name && rig_dict.find(rig_labels[rig_dict[current_rig]]) == rig_dict.end() && !rig_labels[rig_dict[current_rig]].empty()) { - int temp = rig_dict[current_rig]; - current_rig = rig_labels[rig_dict[current_rig]]; - std::map::iterator current_rig_iter = rig_dict.find(prev_rig_name); - if (current_rig_iter != rig_dict.end()) { - rig_dict.erase(current_rig_iter); - } - rig_dict[current_rig] = temp; - rig_labels_set.erase(prev_rig_name); - rig_labels_set.insert(rig_labels[rig_dict[current_rig]]); - } else { - rig_labels[rig_dict[current_rig]] = prev_rig_name; - } - ImGui::SameLine(); - ImGui::Text("Rig Name"); - // ####### WRITE DEPTH ####### // - bool write_depth_ = write_depth[rig_dict[current_rig]]; - ImGui::Checkbox("Write Depth Images", &write_depth_); - write_depth[rig_dict[current_rig]] = write_depth_; - ImGui::SameLine(); - bool write_norm_depth_ = write_norm_depth[rig_dict[current_rig]]; - ImGui::Checkbox("Write Norm Depth Images", &write_norm_depth_); - write_norm_depth[rig_dict[current_rig]] = write_norm_depth_; - // ####### BOUNDING BOXES ####### // - if (ImGui::BeginPopup("multi_select_popup")) { - for (auto &box_pair: bounding_boxes) { - ImGui::Selectable(box_pair.first.c_str(), &box_pair.second, ImGuiSelectableFlags_DontClosePopups); - } - ImGui::EndPopup(); - } - if (ImGui::Button("Select Bounding Box Objects")) { - ImGui::OpenPopup("multi_select_popup"); - } - // ImGui::OpenPopupOnItemClick(("rig_position_noise_" + std::to_string(rig_dict[current_rig])).c_str(), ImGuiPopupFlags_MouseButtonLeft); - // Display selected items - ImGui::Text("Objects:"); - int idx = 0; - for (auto &box_pair: bounding_boxes) { - if (box_pair.second) { - ImGui::SameLine(), ImGui::Text("%i. %s", idx, box_pair.first.c_str()); - idx++; - } - } - // ####### RIG COLOR ####### // - float col[3]; - col[0] = rig_colors[rig_dict[current_rig]].r; - col[1] = rig_colors[rig_dict[current_rig]].g; - col[2] = rig_colors[rig_dict[current_rig]].b; - ImGui::ColorEdit3("##rig_color_edit", col); - updateColor(current_rig, "rig", col); - ImGui::SameLine(); - ImGui::Text("Rig Color"); - // ####### CAMERA LABEL ####### // - /* SINGLE CAMERA VERSION - ImGui::SetNextItemWidth(60); - // ImGui::InputText("Camera Label", &camera_labels[rig_dict[(std::string) current_rig]]); - if (ImGui::BeginCombo("##cam_label_combo", camera_labels[rig_dict[(std::string) current_rig]].c_str())){ - for (int n = 0; n < camera_names.size(); n++){ - bool is_cam_label_selected = (camera_labels[rig_dict[(std::string) current_rig]] == camera_names[n]); // You can store your selection however you want, outside or inside your objects - if (ImGui::Selectable(camera_names[n].c_str(), is_cam_label_selected)){ - camera_labels[rig_dict[(std::string) current_rig]] = camera_names[n]; - } - if (is_cam_label_selected) - ImGui::SetItemDefaultFocus(); // You may set the initial focus when opening the combo (scrolling + for keyboard navigation support) - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Camera Label"); - ImGui::EndTabItem(); - */ - // ####### CAMERA CHECKBOX ####### // - ImGui::Text("Cameras:"); - for (int i = 0; i < camera_names.size(); i++) { - std::string &camera_name = camera_names[i]; - - ImGui::SetNextItemWidth(60); - - std::set curr_set = rig_camera_labels[rig_dict[current_rig]]; - // if (i % 3 != 0){ - // ImGui::SameLine(); - // } - bool isCameraSelected = curr_set.find(camera_name) != curr_set.end(); - ImGui::PushID(i); - if (ImGui::Checkbox(camera_name.c_str(), &isCameraSelected)) { - if (isCameraSelected) { - rig_camera_labels[rig_dict[current_rig]].insert(camera_name); - } else { - rig_camera_labels[rig_dict[current_rig]].erase(camera_name); - } - } - ImGui::PopID(); - } - // ####### LIGHT CHECKBOX ####### // - ImGui::Text("Lights:"); - for (int i = 0; i < light_names.size(); i++) { - std::string &light_name = light_names[i]; - - ImGui::SetNextItemWidth(60); - - std::set curr_rig_light = rig_light_labels[rig_dict[current_rig]]; - bool isLightSelected = curr_rig_light.find(light_name) != curr_rig_light.end(); - ImGui::PushID(i); - if (ImGui::Checkbox(light_name.c_str(), &isLightSelected)) { - if (isLightSelected) { - rig_light_labels[rig_dict[current_rig]].insert(light_name); - } else { - rig_light_labels[rig_dict[current_rig]].erase(light_name); - } - } - ImGui::PopID(); - } - // ####### ADD KEYPOINT ####### // - std::stringstream cam_pos_value; - cam_pos_value << current_cam_position.c_str(); - int current_cam_position_; - cam_pos_value >> current_cam_position_; - current_keypoint = std::to_string(keypoint_frames[rig_dict[current_rig]][current_cam_position_]); - std::string modified_current_keypoint = std::to_string(keypoint_frames[rig_dict[current_rig]][current_cam_position_] + 1); // 1-indexed value - if (ImGui::BeginCombo("##cam_combo", modified_current_keypoint.c_str())) { - for (int n = 1; n <= camera_position_vec[rig_dict[current_rig]].size(); n++) { - std::string select_cam_position = std::to_string(n - 1); - std::string selected_keypoint = std::to_string(keypoint_frames[rig_dict[current_rig]][n - 1]); - bool is_pos_selected = (current_cam_position == select_cam_position); - std::string modified_selected_keypoint = std::to_string(keypoint_frames[rig_dict[current_rig]][n - 1] + 1); // 1-indexed value - if (ImGui::Selectable(modified_selected_keypoint.c_str(), is_pos_selected)) { - current_cam_position = std::to_string(n - 1); - } - if (is_pos_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - cam_pos_value << current_cam_position.c_str(); - cam_pos_value >> current_cam_position_; - ImGui::SameLine(); - if (ImGui::Button("Add Keypoint")) { - camera_position_vec[rig_dict[current_rig]].push_back(camera_position_vec[rig_dict[current_rig]][current_cam_position_]); - camera_lookat_vec[rig_dict[current_rig]].push_back(camera_lookat_vec[rig_dict[current_rig]][current_cam_position_]); - keypoint_frames[rig_dict[current_rig]].push_back(keypoint_frames[rig_dict[current_rig]].back() + 1); - is_dirty = true; - } - // ####### KEYPOINT FRAME ####### // - ImGui::SetNextItemWidth(80); - int modified_keypoint_frame = keypoint_frames[rig_dict[current_rig]][current_cam_position_] + 1; // 1-indexed value - ImGui::InputInt("Keypoint Frame", &modified_keypoint_frame); - if (modified_keypoint_frame != keypoint_frames[rig_dict[current_rig]][current_cam_position_] + 1) { - keypoint_frames[rig_dict[current_rig]][current_cam_position_] = modified_keypoint_frame - 1; - } - // ####### CAMERA POSITION ####### // - vec3 prev_rig_position_ = camera_position_vec[rig_dict[current_rig]][current_cam_position_]; - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##camera_position_x", &camera_position_vec[rig_dict[current_rig]][current_cam_position_].x); - randomizePopup("camera_position_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_position_vec[rig_dict[current_rig]][current_cam_position_].x)); - randomizerParams("camera_position_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); - ImGui::OpenPopupOnItemClick(("randomize_camera_position_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##camera_position_y", &camera_position_vec[rig_dict[current_rig]][current_cam_position_].y); - randomizePopup("camera_position_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_position_vec[rig_dict[current_rig]][current_cam_position_].y)); - randomizerParams("camera_position_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); - ImGui::OpenPopupOnItemClick(("randomize_camera_position_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##camera_position_z", &camera_position_vec[rig_dict[current_rig]][current_cam_position_].z); - randomizePopup("camera_position_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_position_vec[rig_dict[current_rig]][current_cam_position_].z)); - randomizerParams("camera_position_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); - ImGui::OpenPopupOnItemClick(("randomize_camera_position_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Rig Position"); - ImGui::SameLine(); - ImGui::Button("Add Noise###position"); - noisePopup("rig_position_noise_" + std::to_string(rig_dict[current_rig]), rig_lookat_noise[rig_dict[current_rig]]); - ImGui::OpenPopupOnItemClick(("rig_position_noise_" + std::to_string(rig_dict[current_rig])).c_str(), ImGuiPopupFlags_MouseButtonLeft); - // ####### CAMERA LOOKAT ####### // - vec3 prev_rig_lookat_ = camera_lookat_vec[rig_dict[current_rig]][current_cam_position_]; - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##camera_lookat_x", &camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].x); - randomizePopup("camera_lookat_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].x)); - randomizerParams("camera_lookat_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); - ImGui::OpenPopupOnItemClick(("randomize_camera_lookat_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##camera_lookat_y", &camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].y); - randomizePopup("camera_lookat_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].y)); - randomizerParams("camera_lookat_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); - ImGui::OpenPopupOnItemClick(("randomize_camera_lookat_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat("##camera_lookat_z", &camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].z); - randomizePopup("camera_lookat_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].z)); - randomizerParams("camera_lookat_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); - ImGui::OpenPopupOnItemClick(("randomize_camera_lookat_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Rig Lookat"); - ImGui::SameLine(); - ImGui::Button("Add Noise###lookat"); - noisePopup("rig_lookat_noise_" + std::to_string(rig_dict[current_rig]), rig_lookat_noise[rig_dict[current_rig]]); - ImGui::OpenPopupOnItemClick(("rig_lookat_noise_" + std::to_string(rig_dict[current_rig])).c_str(), ImGuiPopupFlags_MouseButtonLeft); - // ####### NUMBER OF IMAGES ####### // - ImGui::SetNextItemWidth(80); - ImGui::InputInt("Total Number of Frames", &num_images_vec[rig_dict[current_rig]]); - num_images_vec[rig_dict[current_rig]] = std::max(num_images_vec[rig_dict[current_rig]], *std::max_element(keypoint_frames[rig_dict[current_rig]].begin(), keypoint_frames[rig_dict[(std::string) current_rig]].end()) + 1); - - if (prev_rig_position_ != camera_position_vec[rig_dict[current_rig]][current_cam_position_] || prev_rig_lookat_ != camera_lookat_vec[rig_dict[current_rig]][current_cam_position_]) { - updateRigs(); - } - } + rigTab(); + ImGui::EndTabItem(); } // CAMERA TAB if (ImGui::BeginTabItem("Camera")) { current_tab = "Camera"; - // LOAD XML LIBRARY FILE - ImGui::SetNextItemWidth(60); - if (ImGui::Button("Load XML Library File")) { - std::string new_xml_library_file = file_dialog(); - if (!new_xml_library_file.empty() && std::filesystem::exists(new_xml_library_file)) { - if (camera_xml_library_files.find(new_xml_library_file) == camera_xml_library_files.end()) { - camera_xml_library_files.insert(new_xml_library_file); - std::vector current_camera_file = get_xml_node_values(new_xml_library_file, "label", "globaldata_vec2"); - possible_camera_calibrations.insert(possible_camera_calibrations.end(), current_camera_file.begin(), current_camera_file.end()); - } - context->loadXML(new_xml_library_file.c_str()); - } - } + cameraTab(); - // ####### ADD BAND GROUP ####### // - ImGui::SetWindowFontScale(1.25f); - ImGui::Text("Band Groups:"); - ImGui::SetWindowFontScale(1.0f); - dropDown("##band_group_combo", current_band_group, band_group_names); - ImGui::SameLine(); - if (ImGui::Button("Add Band Group")) { - std::string default_band_group_label = "band_group"; - std::string new_band_group_label = "band_group_0"; - int count = 0; - while (band_group_lookup.find(new_band_group_label) != band_group_lookup.end()) { - count++; - new_band_group_label = default_band_group_label + "_" + std::to_string(count); - } - std::vector new_band_group_vector; - new_band_group_vector.push_back("red"); - new_band_group_vector.push_back("green"); - new_band_group_vector.push_back("blue"); - bandGroup new_band_group{new_band_group_vector, false, false}; - band_group_lookup[new_band_group_label] = new_band_group; - band_group_names.insert(new_band_group_label); - current_band_group = new_band_group_label; - } - if (!current_band_group.empty()) { - ImGui::SetNextItemWidth(100); - std::string prev_group_name = current_band_group; - ImGui::InputText("Group Name", ¤t_band_group); - if (current_band_group.empty() || band_group_lookup.find(current_band_group) != band_group_lookup.end()) { - current_band_group = prev_group_name; - } - if (current_band_group != prev_group_name) { - bandGroup temp = band_group_lookup[prev_group_name]; - std::map::iterator current_band_group_iter = band_group_lookup.find(prev_group_name); - if (current_band_group_iter != band_group_lookup.end()) { - band_group_lookup.erase(current_band_group_iter); - } - band_group_lookup[current_band_group] = temp; - band_group_names.erase(prev_group_name); - band_group_names.insert(current_band_group); - } - ImGui::SameLine(); - if (ImGui::Button("Delete Group")) { - band_group_names.erase(current_band_group); - band_group_lookup.erase(current_band_group); - current_band_group = ""; - } - ImGui::Checkbox("Grayscale", &band_group_lookup[current_band_group].grayscale); - ImGui::SameLine(); - ImGui::Checkbox("Norm", &band_group_lookup[current_band_group].norm); - // Band 1 - ImGui::SetNextItemWidth(100); - dropDown("##band_1_combo", band_group_lookup[current_band_group].bands[0], bandlabels); - if (!band_group_lookup[current_band_group].grayscale) { - // Band 2 - ImGui::SameLine(); - ImGui::SetNextItemWidth(100); - dropDown("##band_2_combo", band_group_lookup[current_band_group].bands[1], bandlabels); - // Band 3 - ImGui::SameLine(); - ImGui::SetNextItemWidth(100); - dropDown("##band_3_combo", band_group_lookup[current_band_group].bands[2], bandlabels); - ImGui::SameLine(); - ImGui::Text("Select Bands"); - } else { - ImGui::SameLine(); - ImGui::Text("Select Band"); - } - } - ImGui::SetWindowFontScale(1.25f); - ImGui::Text("Edit Camera:"); - ImGui::SetWindowFontScale(1.0f); - if (ImGui::BeginCombo("##camera_combo", current_cam.c_str())) { - for (int n = 0; n < camera_names.size(); n++) { - bool is_cam_selected = (current_cam == camera_names[n]); - if (ImGui::Selectable(camera_names[n].c_str(), is_cam_selected)) - current_cam = camera_names[n]; - if (is_cam_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - if (ImGui::Button("Add New Camera")) { - std::string default_cam_name = "camera"; - std::string new_cam_name = "camera_0"; - int count = 0; - while (camera_dict.find(new_cam_name) != camera_dict.end()) { - count++; - new_cam_name = default_cam_name + "_" + std::to_string(count); - } - camera_dict.insert({new_cam_name, scast(camera_names.size())}); - camera_resolutions.push_back(camera_resolution); - camera_calibrations.push_back(camera_calibrations[camera_dict[current_cam]]); - focal_plane_distances.push_back(focal_plane_distance); - lens_diameters.push_back(lens_diameter); - FOV_aspect_ratios.push_back(FOV_aspect_ratio); - HFOVs.push_back(HFOV); - camera_names.push_back(new_cam_name); - std::string parent = "camera"; - pugi::xml_node camera_block = helios.child(parent.c_str()); - pugi::xml_node new_cam_node = helios.append_copy(camera_block); - std::string name = "label"; - pugi::xml_attribute node_label = new_cam_node.attribute(name.c_str()); - node_label.set_value(new_cam_name.c_str()); - current_cam = new_cam_name; - } - ImGui::SetNextItemWidth(100); - std::string prev_cam_name = camera_names[camera_dict[current_cam]]; - ImGui::InputText("##cam_name", &camera_names[camera_dict[current_cam]]); - if (camera_names[camera_dict[current_cam]] != prev_cam_name) { - int temp = camera_dict[current_cam]; - current_cam = camera_names[camera_dict[current_cam]]; - std::map::iterator current_cam_iter = camera_dict.find(prev_cam_name); - if (current_cam_iter != camera_dict.end()) { - camera_dict.erase(current_cam_iter); - } - camera_dict[current_cam] = temp; - } - ImGui::SameLine(); - ImGui::Text("Camera Label"); - // ####### CAMERA CALIBRATION ####### // - ImGui::SetNextItemWidth(100); - dropDown("##camera_calibration_band", current_calibration_band, bandlabels); - ImGui::SameLine(); - ImGui::Text("Band"); - ImGui::SetNextItemWidth(250); - ImGui::SameLine(); - dropDown("##camera_band_group_combo", camera_calibrations[camera_dict[current_cam]][current_calibration_band], possible_camera_calibrations); - ImGui::SameLine(); - ImGui::Text("Calibration"); - // ####### CAMERA CALIBRATION ####### // - // std::string prev_cam_calibration = camera_calibrations[camera_dict[current_cam]]; - // if (ImGui::BeginCombo("##camera_calibration_combo", camera_calibrations[camera_dict[current_cam]].c_str())){ - // for (int n = 0; n < possible_camera_calibrations.size(); n++){ - // bool is_cam_calibration_selected = (camera_calibrations[camera_dict[current_cam]] == possible_camera_calibrations[n]); - // if (ImGui::Selectable(possible_camera_calibrations[n].c_str(), is_cam_calibration_selected)) - // camera_calibrations[camera_dict[current_cam]] = possible_camera_calibrations[n]; - // if (is_cam_calibration_selected) - // ImGui::SetItemDefaultFocus(); - // } - // ImGui::EndCombo(); - // } - // ImGui::SameLine(); - // ImGui::Text("Camera Calibration"); - // ####### CAMERA RESOLUTION ####### // - ImGui::SetNextItemWidth(90); - ImGui::InputInt("##camera_resolution_x", &camera_resolutions[camera_dict[current_cam]].x); - randomizePopup("camera_resolution_x_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&camera_resolutions[camera_dict[current_cam]].x)); - randomizerParams("camera_resolution_x_" + std::to_string(camera_dict[current_cam])); - ImGui::OpenPopupOnItemClick(("randomize_camera_resolution_x_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(90); - ImGui::InputInt("##camera_resolution_y", &camera_resolutions[camera_dict[current_cam]].y); - randomizePopup("camera_resolution_y_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&camera_resolutions[camera_dict[current_cam]].y)); - randomizerParams("camera_resolution_y_" + std::to_string(camera_dict[current_cam])); - ImGui::OpenPopupOnItemClick(("randomize_camera_resolution_y_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Camera Resolution"); - // ####### FOCAL PLANE DISTANCE ####### // - ImGui::SetNextItemWidth(50); - ImGui::InputFloat("Focal Plane Distance", &focal_plane_distances[camera_dict[current_cam]]); - randomizePopup("focal_plane_distance_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&focal_plane_distances[camera_dict[current_cam]])); - randomizerParams("focal_plane_distance_" + std::to_string(camera_dict[current_cam])); - ImGui::OpenPopupOnItemClick(("randomize_focal_plane_distance_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); - // ####### LENS DIAMETER ####### // - ImGui::SetNextItemWidth(50); - ImGui::InputFloat("Lens Diameter", &lens_diameters[camera_dict[current_cam]]); - randomizePopup("lens_diameter_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&lens_diameters[camera_dict[current_cam]])); - randomizerParams("lens_diameter_" + std::to_string(camera_dict[current_cam])); - ImGui::OpenPopupOnItemClick(("randomize_lens_diameter_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); - // ####### FOV ASPECT RATIO ####### // - ImGui::SetNextItemWidth(50); - ImGui::InputFloat("FOV Aspect Ratio", &FOV_aspect_ratios[camera_dict[current_cam]]); - randomizePopup("FOV_aspect_ratio_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&FOV_aspect_ratios[camera_dict[current_cam]])); - randomizerParams("FOV_aspect_ratio_" + std::to_string(camera_dict[current_cam])); - ImGui::OpenPopupOnItemClick(("randomize_FOV_aspect_ratio_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); - // ####### HFOV ####### // - ImGui::SetNextItemWidth(50); - ImGui::InputFloat("HFOV", &HFOVs[camera_dict[current_cam]]); - randomizePopup("HFOV_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&HFOVs[camera_dict[current_cam]])); - randomizerParams("HFOV_" + std::to_string(camera_dict[current_cam])); - ImGui::OpenPopupOnItemClick(("HFOV_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); - // ImGui::EndTabItem(); } // LIGHT TAB if (ImGui::BeginTabItem("Light")) { current_tab = "Light"; - // LOAD XML LIBRARY FILE - ImGui::SetNextItemWidth(60); - if (ImGui::Button("Load XML Library File")) { - std::string new_xml_library_file = file_dialog(); - if (!new_xml_library_file.empty() && std::filesystem::exists(new_xml_library_file)) { - if (light_xml_library_files.find(new_xml_library_file) == light_xml_library_files.end()) { - light_xml_library_files.insert(new_xml_library_file); - std::vector current_light_file = get_xml_node_values(new_xml_library_file, "label", "globaldata_vec2"); - possible_light_spectra.insert(possible_light_spectra.end(), current_light_file.begin(), current_light_file.end()); - } - context->loadXML(new_xml_library_file.c_str()); - } - } - if (ImGui::BeginCombo("##light_combo", current_light.c_str())) { - for (int n = 0; n < light_names.size(); n++) { - bool is_light_selected = (current_light == light_names[n]); - if (ImGui::Selectable(light_names[n].c_str(), is_light_selected)) - current_light = light_names[n]; - if (is_light_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - if (ImGui::Button("Add Light")) { - std::string default_light_name = "light"; - std::string new_light_name = "light_0"; - int count = 0; - while (light_dict.find(new_light_name) != light_dict.end()) { - count++; - new_light_name = default_light_name + "_" + std::to_string(count); - } - light_dict.insert({new_light_name, scast(light_names.size())}); - light_spectra.push_back(light_spectra[light_dict[current_light]]); - light_types.push_back(light_types[light_dict[current_light]]); - light_direction_vec.push_back(light_direction_vec[light_dict[current_light]]); - light_direction_sph_vec.push_back(light_direction_sph_vec[light_dict[current_light]]); - light_rotation_vec.push_back(light_rotation_vec[light_dict[current_light]]); - light_size_vec.push_back(light_size_vec[light_dict[current_light]]); - light_radius_vec.push_back(light_radius_vec[light_dict[current_light]]); - light_names.push_back(new_light_name); - light_flux_vec.push_back(light_flux_vec[light_dict[current_light]]); - std::string parent = "light"; - pugi::xml_node light_block = helios.child(parent.c_str()); - pugi::xml_node new_light_node = helios.append_copy(light_block); - std::string name = "label"; - pugi::xml_attribute node_label = new_light_node.attribute(name.c_str()); - node_label.set_value(new_light_name.c_str()); - current_light = new_light_name; - } - ImGui::SetNextItemWidth(100); - std::string prev_light_name = light_names[light_dict[current_light]]; - ImGui::InputText("##light_name", &light_names[light_dict[current_light]]); - if (light_names[light_dict[current_light]] != prev_light_name) { - int temp = light_dict[current_light]; - current_light = light_names[light_dict[current_light]]; - std::map::iterator current_light_iter = light_dict.find(prev_light_name); - if (current_light_iter != light_dict.end()) { - light_dict.erase(current_light_iter); - } - light_dict[current_light] = temp; - } - ImGui::SameLine(); - ImGui::Text("Light Label"); - // ####### LIGHT SPECTRA ####### // - std::string prev_light_spectra = light_spectra[light_dict[current_light]]; - if (ImGui::BeginCombo("##light_spectra_combo", light_spectra[light_dict[current_light]].c_str())) { - for (int n = 0; n < possible_light_spectra.size(); n++) { - bool is_light_spectra_selected = (light_spectra[light_dict[current_light]] == possible_light_spectra[n]); - if (ImGui::Selectable(possible_light_spectra[n].c_str(), is_light_spectra_selected)) - light_spectra[light_dict[current_light]] = possible_light_spectra[n]; - if (is_light_spectra_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Light Spectrum"); - // ####### LIGHT TYPE ############ // - if (ImGui::BeginCombo("##light_type_combo", light_types[light_dict[current_light]].c_str())) { - for (int n = 0; n < all_light_types.size(); n++) { - bool is_type_selected = (light_types[light_dict[current_light]] == all_light_types[n]); - if (ImGui::Selectable(all_light_types[n].c_str(), is_type_selected)) { - light_types[light_dict[current_light]] = all_light_types[n]; - } - if (is_type_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - ImGui::SameLine(); - ImGui::Text("Light Type"); - // collimated -> direction - // disk -> position, radius, rotation - // sphere -> position, radius - // sunsphere -> direction - // rectangle -> position, size, rotation - // ####### LIGHT DIRECTION ####### // - if (light_types[light_dict[(std::string) current_light]] == "collimated" || light_types[light_dict[(std::string) current_light]] == "sunsphere") { - ImGui::SetNextItemWidth(90); - ImGui::InputFloat("##light_direction_x", &light_direction_vec[light_dict[current_light]].x); - randomizePopup("light_direction_x_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_direction_vec[light_dict[current_light]].x)); - randomizerParams("light_direction_x_" + std::to_string(light_dict[current_light])); - ImGui::OpenPopupOnItemClick(("light_direction_x_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(90); - ImGui::InputFloat("##light_direction_y", &light_direction_vec[light_dict[current_light]].y); - randomizePopup("light_direction_y_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_direction_vec[light_dict[current_light]].y)); - randomizerParams("light_direction_y_" + std::to_string(light_dict[current_light])); - ImGui::OpenPopupOnItemClick(("light_direction_y_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(90); - ImGui::InputFloat("##light_direction_z", &light_direction_vec[light_dict[current_light]].z); - randomizePopup("light_direction_z_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_direction_vec[light_dict[current_light]].z)); - randomizerParams("light_direction_z_" + std::to_string(light_dict[current_light])); - ImGui::OpenPopupOnItemClick(("light_direction_z_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Light Direction"); - } - // ####### LIGHT SOURCE FLUX ####### // - ImGui::SetNextItemWidth(90); - ImGui::InputFloat("##source_flux", &light_flux_vec[light_dict[current_light]]); - randomizePopup("source_flux_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_flux_vec[light_dict[current_light]])); - randomizerParams("source_flux_" + std::to_string(light_dict[current_light])); - ImGui::OpenPopupOnItemClick(("source_flux_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Source Flux"); - // radiation->setSourceFlux(light_UUID, band, flux_value); - // ####### LIGHT ROTATION ####### // - if (light_types[light_dict[current_light]] == "disk" || light_types[light_dict[current_light]] == "rectangle") { - ImGui::SetNextItemWidth(90); - ImGui::InputFloat("##light_rotation_x", &light_rotation_vec[light_dict[current_light]].x); - randomizePopup("light_rotation_x_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_rotation_vec[light_dict[current_light]].x)); - randomizerParams("light_rotation_x_" + std::to_string(light_dict[current_light])); - ImGui::OpenPopupOnItemClick(("light_rotation_x_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(90); - ImGui::InputFloat("##light_rotation_y", &light_rotation_vec[light_dict[current_light]].y); - randomizePopup("light_rotation_y_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_rotation_vec[light_dict[current_light]].y)); - randomizerParams("light_rotation_y_" + std::to_string(light_dict[current_light])); - ImGui::OpenPopupOnItemClick(("light_rotation_y_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(90); - ImGui::InputFloat("##light_rotation_z", &light_rotation_vec[light_dict[current_light]].z); - randomizePopup("light_rotation_z_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_rotation_vec[light_dict[current_light]].z)); - randomizerParams("light_rotation_z_" + std::to_string(light_dict[current_light])); - ImGui::OpenPopupOnItemClick(("light_rotation_z_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Light Rotation"); - } - // ####### LIGHT SIZE ####### // - if (light_types[light_dict[current_light]] == "rectangle") { - ImGui::SetNextItemWidth(90); - ImGui::InputFloat("##light_size_x", &light_size_vec[light_dict[current_light]].x); - randomizePopup("light_size_x_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_size_vec[light_dict[current_light]].x)); - randomizerParams("light_size_x_" + std::to_string(light_dict[current_light])); - ImGui::OpenPopupOnItemClick(("light_size_x_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(90); - ImGui::InputFloat("##light_size_y", &light_size_vec[light_dict[current_light]].y); - randomizePopup("light_size_y_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_size_vec[light_dict[current_light]].y)); - randomizerParams("light_size_y_" + std::to_string(light_dict[current_light])); - ImGui::OpenPopupOnItemClick(("light_size_y_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Light Size"); - } - // ####### LIGHT RADIUS ####### // - if (light_types[light_dict[current_light]] == "disk" || light_types[light_dict[current_light]] == "sphere") { - ImGui::SetNextItemWidth(90); - ImGui::InputFloat("##light_radius", &light_radius_vec[light_dict[current_light]]); - randomizePopup("light_radius_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_radius_vec[light_dict[current_light]])); - randomizerParams("light_radius_" + std::to_string(light_dict[current_light])); - ImGui::OpenPopupOnItemClick(("light_radius_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Light Radius"); - } - // LIGHT END + lightTab(); + ImGui::EndTabItem(); } } ImGui::EndTabBar(); } - // ImGui::Text("Hello, world %d", 123); - // ImGui::Button("Save"); - // if (ImGui::Button("Save")) - // std::cout << "here" << std::endl; last_position = current_position; previously_collapsed = currently_collapsed; ImGui::End(); @@ -4274,6 +2363,7 @@ void ProjectBuilder::visualize() { // TODO: requery primitive types here // updatePrimitiveTypes(); // refreshVisualizationTypes(); + updatePrimitiveTypes(); context->markGeometryClean(); is_dirty = false; } @@ -4766,10 +2856,13 @@ void ProjectBuilder::xmlGetValues() { xmlGetValues("images", "rig", num_images_vec); write_depth.clear(); write_norm_depth.clear(); + write_segmentation_mask.clear(); std::vector write_depth_{}; std::vector write_norm_depth_{}; + std::vector write_segmentation_mask_{}; xmlGetValues("depth", "rig", write_depth_); - xmlGetValues("depth", "rig", write_norm_depth_); + xmlGetValues("normdepth", "rig", write_norm_depth_); + xmlGetValues("segmentation", "rig", write_segmentation_mask_); for (int i = 0; i < write_depth_.size(); i++) { if (write_depth_[i] == 1) { write_depth.push_back(true); @@ -4781,6 +2874,11 @@ void ProjectBuilder::xmlGetValues() { } else { write_norm_depth.push_back(false); } + if (write_segmentation_mask_[i] == 1) { + write_segmentation_mask.push_back(true); + } else { + write_segmentation_mask.push_back(false); + } } // CAMERA BLOCK camera_names.clear(); @@ -4899,118 +2997,2136 @@ void ProjectBuilder::xmlGetValues() { } else { primitive_continuous[prim][1] = false; } - for (std::string band: bandlabels) { - if (band == "All") - continue; - xmlGetValue(prim + "_reflectivity", "radiation", primitive_values[band][prim][0]); - xmlGetValue(prim + "_transmissivity", "radiation", primitive_values[band][prim][1]); - xmlGetValue(prim + "_emissivity", "radiation", primitive_values[band][prim][2]); + for (std::string band: bandlabels) { + if (band == "All") + continue; + xmlGetValue(prim + "_reflectivity", "radiation", primitive_values[band][prim][0]); + xmlGetValue(prim + "_transmissivity", "radiation", primitive_values[band][prim][1]); + xmlGetValue(prim + "_emissivity", "radiation", primitive_values[band][prim][2]); + } + } +#endif +} + +void ProjectBuilder::xmlGetValues(std::string xml_path) { + xml_input_file = xml_path; + if (!open_xml_file(xml_input_file, xmldoc, xml_error_string)) { + helios_runtime_error(xml_error_string); + } + xmlGetValues(); +} + +void ProjectBuilder::calculationTab() { +#ifdef ENABLE_HELIOS_VISUALIZER + // prim + for(auto &prim_name : primitive_names_set) { + if (calculation_selection_primitive.find(prim_name) == calculation_selection_primitive.end()) { + calculation_selection_primitive[prim_name] = false; + } + } + std::vector primitive_labels = context->listAllPrimitiveDataLabels(); + calculation_variable_choices.clear(); + for (auto &label : primitive_labels) { + HeliosDataType dtype = context->getPrimitiveDataType(label.c_str()); + if (heliosNumericTypes.find(dtype) != heliosNumericTypes.end()) + calculation_variable_choices.insert(label); + } + std::vector global_data = context->listGlobalData(); + for (auto &data : global_data) { + HeliosDataType dtype = context->getGlobalDataType(data.c_str()); + if (heliosNumericTypes.find(dtype) != heliosNumericTypes.end()) + calculation_variable_choices.insert(data); + } + + // data group + for (auto &data_group : data_groups_set) { + if (calculation_selection_datagroup.find(data_group) == calculation_selection_datagroup.end()) { + calculation_selection_datagroup[data_group] = false; + } + } + // data group popup + if (ImGui::BeginPopup("calculation_select_popup_datagroup")) { + for (auto &calculation_pair: calculation_selection_datagroup) { + ImGui::Selectable(calculation_pair.first.c_str(), &calculation_pair.second, ImGuiSelectableFlags_DontClosePopups); + } + ImGui::EndPopup(); + } + if (ImGui::Button("Select Data Groups")) { + ImGui::OpenPopup("calculation_select_popup_datagroup"); + } + ImGui::SameLine(); + ImGui::Text("Data Groups:"); + int idx = 0; + if (calculation_selection_datagroup["All"]) { + ImGui::SameLine(); + ImGui::Text("All"); + } else { + for (auto &calculation_pair: calculation_selection_datagroup) { + if (calculation_pair.second) { + ImGui::SameLine(), ImGui::Text("%i. %s", idx, calculation_pair.first.c_str()); + idx++; + } + } + } + + // prim popup + if (ImGui::BeginPopup("calculation_select_popup_prim")) { + for (auto &calculation_pair: calculation_selection_primitive) { + ImGui::Selectable(calculation_pair.first.c_str(), &calculation_pair.second, ImGuiSelectableFlags_DontClosePopups); + } + ImGui::EndPopup(); + } + if (ImGui::Button("Select Primitives")) { + ImGui::OpenPopup("calculation_select_popup_prim"); + } + ImGui::SameLine(); + ImGui::Text("Primitive Types:"); + idx = 0; + if (calculation_selection_primitive["All"]) { + ImGui::SameLine(); + ImGui::Text("All"); + } else { + for (auto &calculation_pair: calculation_selection_primitive) { + if (calculation_pair.second) { + ImGui::SameLine(), ImGui::Text("%i. %s", idx, calculation_pair.first.c_str()); + idx++; + } + } + } + // Global Data Calculation + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Global Data:"); + ImGui::SetWindowFontScale(1.0f); + for (int i = 0; i < calculation_variables_global.size(); i++) { + if (i > 0) { + ImGui::SetNextItemWidth(40); + dropDown("##operator" + std::to_string(i), calculation_operators_global[i - 1], calculation_operators_choices); + } + ImGui::Text("Scalar:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(50); + std::string scalar_label = "##Scalar" + std::to_string(i); + ImGui::InputFloat(scalar_label.c_str(), &calculation_scalars_global[i]); + ImGui::SameLine(); + ImGui::Text("Variable:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + dropDown("##Variable" + std::to_string(i), calculation_variables_global[i], calculation_variable_choices); + ImGui::SameLine(); + ImGui::Text("Aggregate:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + dropDown("##Operation" + std::to_string(i), calculation_aggregations[i], calculation_aggregation_choices); + if (i == calculation_variables_global.size() - 1) { + ImGui::SameLine(); + if (ImGui::Button("Add Operand")) { + calculation_variables_global.push_back(""); + calculation_scalars_global.push_back(1.0); + calculation_operators_global.push_back("+"); + calculation_aggregations.push_back("Mean"); + } + if (i > 0) { + ImGui::SameLine(); + if (ImGui::Button("Remove")) { + calculation_variables_global.pop_back(); + calculation_scalars_global.pop_back(); + calculation_operators_global.pop_back(); + calculation_aggregations.pop_back(); + } + } + } + } + if (ImGui::Button("Calculate Result:")) { + globalCalculation(); + } + ImGui::SameLine(); + ImGui::Text(std::to_string(calculation_result_global).c_str()); + ImGui::SameLine(); + if (ImGui::Button("Save to Global Data")) { + context->setGlobalData(calculation_name_global.c_str(), calculation_result_global); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + ImGui::InputText("##global_data_name", &calculation_name_global); + + // Primitive Data Calculation + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Primitive Data:"); + ImGui::SetWindowFontScale(1.0f); + for (int i = 0; i < calculation_variables_primitive.size(); i++) { + if (i > 0) { + ImGui::SetNextItemWidth(40); + dropDown("##operator_primitive" + std::to_string(i), calculation_operators_primitive[i - 1], calculation_operators_choices); + } + ImGui::Text("Scalar:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(50); + std::string scalar_label = "##Scalar_primitive-" + std::to_string(i); + ImGui::InputFloat(scalar_label.c_str(), &calculation_scalars_primitive[i]); + ImGui::SameLine(); + ImGui::Text("Variable:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + dropDown("##Variable_primitive" + std::to_string(i), calculation_variables_primitive[i], calculation_variable_choices); + if (i == calculation_variables_primitive.size() - 1) { + ImGui::SameLine(); + if (ImGui::Button("Add Operand##primitive")) { + calculation_variables_primitive.push_back(""); + calculation_scalars_primitive.push_back(1.0); + calculation_operators_primitive.push_back("+"); + } + if (i > 0) { + ImGui::SameLine(); + if (ImGui::Button("Remove##primitive")) { + calculation_variables_primitive.pop_back(); + calculation_scalars_primitive.pop_back(); + calculation_operators_primitive.pop_back(); + } + } + } + } + ImGui::Text("Save Primitive Data:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80); + ImGui::InputText("##save_data_name", &calculation_name_primitive); + ImGui::SameLine(); + if (ImGui::Button("Save to Primitive Data")) { + savePrimitiveCalculation(); + } +#endif +} + +void ProjectBuilder::cameraTab() { +#if defined(ENABLE_HELIOS_VISUALIZER) && defined(ENABLE_RADIATION_MODEL) + // LOAD XML LIBRARY FILE + ImGui::SetNextItemWidth(60); + if (ImGui::Button("Load XML Library File")) { + std::string new_xml_library_file = file_dialog(); + if (!new_xml_library_file.empty() && std::filesystem::exists(new_xml_library_file)) { + if (camera_xml_library_files.find(new_xml_library_file) == camera_xml_library_files.end()) { + camera_xml_library_files.insert(new_xml_library_file); + std::vector current_camera_file = get_xml_node_values(new_xml_library_file, "label", "globaldata_vec2"); + possible_camera_calibrations.insert(possible_camera_calibrations.end(), current_camera_file.begin(), current_camera_file.end()); + } + context->loadXML(new_xml_library_file.c_str()); + } + } + + // ####### ADD BAND GROUP ####### // + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Band Groups:"); + ImGui::SetWindowFontScale(1.0f); + dropDown("##band_group_combo", current_band_group, band_group_names); + ImGui::SameLine(); + if (ImGui::Button("Add Band Group")) { + std::string default_band_group_label = "band_group"; + std::string new_band_group_label = "band_group_0"; + int count = 0; + while (band_group_lookup.find(new_band_group_label) != band_group_lookup.end()) { + count++; + new_band_group_label = default_band_group_label + "_" + std::to_string(count); + } + std::vector new_band_group_vector; + new_band_group_vector.push_back("red"); + new_band_group_vector.push_back("green"); + new_band_group_vector.push_back("blue"); + bandGroup new_band_group{new_band_group_vector, false, false, false}; + band_group_lookup[new_band_group_label] = new_band_group; + band_group_names.insert(new_band_group_label); + current_band_group = new_band_group_label; + } + if (!current_band_group.empty()) { + ImGui::SetNextItemWidth(100); + std::string prev_group_name = current_band_group; + ImGui::InputText("Group Name", ¤t_band_group); + if (current_band_group.empty() || band_group_lookup.find(current_band_group) != band_group_lookup.end()) { + current_band_group = prev_group_name; + } + if (current_band_group != prev_group_name) { + bandGroup temp = band_group_lookup[prev_group_name]; + std::map::iterator current_band_group_iter = band_group_lookup.find(prev_group_name); + if (current_band_group_iter != band_group_lookup.end()) { + band_group_lookup.erase(current_band_group_iter); + } + band_group_lookup[current_band_group] = temp; + band_group_names.erase(prev_group_name); + band_group_names.insert(current_band_group); + } + ImGui::SameLine(); + if (ImGui::Button("Delete Group")) { + band_group_names.erase(current_band_group); + band_group_lookup.erase(current_band_group); + current_band_group = ""; + } + ImGui::Checkbox("Grayscale", &band_group_lookup[current_band_group].grayscale); + ImGui::SameLine(); + ImGui::Checkbox("Norm", &band_group_lookup[current_band_group].norm); + if (std::find(band_group_lookup[current_band_group].bands.begin(), band_group_lookup[current_band_group].bands.end(), "red") != band_group_lookup[current_band_group].bands.end() && + std::find(band_group_lookup[current_band_group].bands.begin(), band_group_lookup[current_band_group].bands.end(), "green") != band_group_lookup[current_band_group].bands.end() && + std::find(band_group_lookup[current_band_group].bands.begin(), band_group_lookup[current_band_group].bands.end(), "blue") != band_group_lookup[current_band_group].bands.end()) { + band_group_lookup[current_band_group].hdr = true; + } + // Band 1 + ImGui::SetNextItemWidth(100); + dropDown("##band_1_combo", band_group_lookup[current_band_group].bands[0], bandlabels); + if (!band_group_lookup[current_band_group].grayscale) { + // Band 2 + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + dropDown("##band_2_combo", band_group_lookup[current_band_group].bands[1], bandlabels); + // Band 3 + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + dropDown("##band_3_combo", band_group_lookup[current_band_group].bands[2], bandlabels); + ImGui::SameLine(); + ImGui::Text("Select Bands"); + } else { + ImGui::SameLine(); + ImGui::Text("Select Band"); + } + } + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Edit Camera:"); + ImGui::SetWindowFontScale(1.0f); + if (ImGui::BeginCombo("##camera_combo", current_cam.c_str())) { + for (int n = 0; n < camera_names.size(); n++) { + bool is_cam_selected = (current_cam == camera_names[n]); + if (ImGui::Selectable(camera_names[n].c_str(), is_cam_selected)) + current_cam = camera_names[n]; + if (is_cam_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + if (ImGui::Button("Add New Camera")) { + std::string default_cam_name = "camera"; + std::string new_cam_name = "camera_0"; + int count = 0; + while (camera_dict.find(new_cam_name) != camera_dict.end()) { + count++; + new_cam_name = default_cam_name + "_" + std::to_string(count); + } + camera_dict.insert({new_cam_name, scast(camera_names.size())}); + camera_resolutions.push_back(camera_resolution); + camera_calibrations.push_back(camera_calibrations[camera_dict[current_cam]]); + focal_plane_distances.push_back(focal_plane_distance); + lens_diameters.push_back(lens_diameter); + FOV_aspect_ratios.push_back(FOV_aspect_ratio); + HFOVs.push_back(HFOV); + camera_names.push_back(new_cam_name); + std::string parent = "camera"; + pugi::xml_node camera_block = helios.child(parent.c_str()); + pugi::xml_node new_cam_node = helios.append_copy(camera_block); + std::string name = "label"; + pugi::xml_attribute node_label = new_cam_node.attribute(name.c_str()); + node_label.set_value(new_cam_name.c_str()); + current_cam = new_cam_name; + } + ImGui::SetNextItemWidth(100); + std::string prev_cam_name = camera_names[camera_dict[current_cam]]; + ImGui::InputText("##cam_name", &camera_names[camera_dict[current_cam]]); + if (camera_names[camera_dict[current_cam]] != prev_cam_name) { + int temp = camera_dict[current_cam]; + current_cam = camera_names[camera_dict[current_cam]]; + std::map::iterator current_cam_iter = camera_dict.find(prev_cam_name); + if (current_cam_iter != camera_dict.end()) { + camera_dict.erase(current_cam_iter); + } + camera_dict[current_cam] = temp; + } + ImGui::SameLine(); + ImGui::Text("Camera Label"); + // ####### CAMERA CALIBRATION ####### // + ImGui::SetNextItemWidth(100); + dropDown("##camera_calibration_band", current_calibration_band, bandlabels); + ImGui::SameLine(); + ImGui::Text("Band"); + ImGui::SetNextItemWidth(250); + ImGui::SameLine(); + dropDown("##camera_band_group_combo", camera_calibrations[camera_dict[current_cam]][current_calibration_band], possible_camera_calibrations); + ImGui::SameLine(); + ImGui::Text("Calibration"); + // ####### CAMERA CALIBRATION ####### // + // std::string prev_cam_calibration = camera_calibrations[camera_dict[current_cam]]; + // if (ImGui::BeginCombo("##camera_calibration_combo", camera_calibrations[camera_dict[current_cam]].c_str())){ + // for (int n = 0; n < possible_camera_calibrations.size(); n++){ + // bool is_cam_calibration_selected = (camera_calibrations[camera_dict[current_cam]] == possible_camera_calibrations[n]); + // if (ImGui::Selectable(possible_camera_calibrations[n].c_str(), is_cam_calibration_selected)) + // camera_calibrations[camera_dict[current_cam]] = possible_camera_calibrations[n]; + // if (is_cam_calibration_selected) + // ImGui::SetItemDefaultFocus(); + // } + // ImGui::EndCombo(); + // } + // ImGui::SameLine(); + // ImGui::Text("Camera Calibration"); + // ####### CAMERA RESOLUTION ####### // + ImGui::SetNextItemWidth(90); + ImGui::InputInt("##camera_resolution_x", &camera_resolutions[camera_dict[current_cam]].x); + randomizePopup("camera_resolution_x_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&camera_resolutions[camera_dict[current_cam]].x)); + randomizerParams("camera_resolution_x_" + std::to_string(camera_dict[current_cam])); + ImGui::OpenPopupOnItemClick(("randomize_camera_resolution_x_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(90); + ImGui::InputInt("##camera_resolution_y", &camera_resolutions[camera_dict[current_cam]].y); + randomizePopup("camera_resolution_y_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&camera_resolutions[camera_dict[current_cam]].y)); + randomizerParams("camera_resolution_y_" + std::to_string(camera_dict[current_cam])); + ImGui::OpenPopupOnItemClick(("randomize_camera_resolution_y_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Camera Resolution"); + // ####### FOCAL PLANE DISTANCE ####### // + ImGui::SetNextItemWidth(50); + ImGui::InputFloat("Focal Plane Distance", &focal_plane_distances[camera_dict[current_cam]]); + randomizePopup("focal_plane_distance_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&focal_plane_distances[camera_dict[current_cam]])); + randomizerParams("focal_plane_distance_" + std::to_string(camera_dict[current_cam])); + ImGui::OpenPopupOnItemClick(("randomize_focal_plane_distance_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); + // ####### LENS DIAMETER ####### // + ImGui::SetNextItemWidth(50); + ImGui::InputFloat("Lens Diameter", &lens_diameters[camera_dict[current_cam]]); + randomizePopup("lens_diameter_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&lens_diameters[camera_dict[current_cam]])); + randomizerParams("lens_diameter_" + std::to_string(camera_dict[current_cam])); + ImGui::OpenPopupOnItemClick(("randomize_lens_diameter_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); + // ####### FOV ASPECT RATIO ####### // + ImGui::SetNextItemWidth(50); + ImGui::InputFloat("FOV Aspect Ratio", &FOV_aspect_ratios[camera_dict[current_cam]]); + randomizePopup("FOV_aspect_ratio_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&FOV_aspect_ratios[camera_dict[current_cam]])); + randomizerParams("FOV_aspect_ratio_" + std::to_string(camera_dict[current_cam])); + ImGui::OpenPopupOnItemClick(("randomize_FOV_aspect_ratio_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); + // ####### HFOV ####### // + ImGui::SetNextItemWidth(50); + ImGui::InputFloat("HFOV", &HFOVs[camera_dict[current_cam]]); + randomizePopup("HFOV_" + std::to_string(camera_dict[current_cam]), createTaggedPtr(&HFOVs[camera_dict[current_cam]])); + randomizerParams("HFOV_" + std::to_string(camera_dict[current_cam])); + ImGui::OpenPopupOnItemClick(("HFOV_" + std::to_string(camera_dict[current_cam])).c_str(), ImGuiPopupFlags_MouseButtonRight); + // +#endif +} + + +void ProjectBuilder::canopyTab() { +#if defined(ENABLE_HELIOS_VISUALIZER) && defined(ENABLE_PLANT_ARCHITECTURE) + dropDown("##canopy_combo", current_canopy, canopy_labels_set); + ImGui::SameLine(); + if (ImGui::Button("Add Canopy")) { + addCanopy(); + } + if (!current_canopy.empty()) { + if (ImGui::Button("Update Canopy")) { + updateCanopy(current_canopy); + is_dirty = true; + canopy_dict[current_canopy].is_dirty = false; + } + ImGui::SameLine(); + if (ImGui::Button("Delete Canopy")) { + deleteCanopy(current_canopy); + updatePrimitiveTypes(); + is_dirty = true; + context->markGeometryDirty(); + } + if (canopy_dict[current_canopy].is_dirty) { + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255)); // Red text + ImGui::Text("update required"); + ImGui::PopStyleColor(); + } + ImGui::SetNextItemWidth(100); + std::string prev_canopy_name = canopy_dict[current_canopy].label; + ImGui::InputText("##canopy_name", &canopy_dict[current_canopy].label); + if (canopy_dict[current_canopy].label != prev_canopy_name && canopy_labels_set.find(canopy_dict[current_canopy].label) == canopy_labels_set.end() && !canopy_dict[current_canopy].label.empty()) { + canopy temp = canopy_dict[current_canopy]; + current_canopy = canopy_dict[prev_canopy_name].label; + std::map::iterator current_canopy_iter = canopy_dict.find(prev_canopy_name); + if (current_canopy_iter != canopy_dict.end()) { + canopy_dict.erase(current_canopy_iter); + } + canopy_dict[current_canopy] = temp; + + canopy_labels_set.erase(prev_canopy_name); + canopy_labels_set.insert(current_canopy); + } else { + canopy_dict[current_canopy].label = prev_canopy_name; + } + ImGui::SameLine(); + ImGui::Text("Canopy Name"); + // ####### PLANT LIBRARY NAME ####### // + ImGui::SetNextItemWidth(250); + // ImGui::InputText("Plant Library", &plant_library_names[canopy_labels_dict[current_canopy]]); + std::string prev_lib = canopy_dict[current_canopy].library_name_verbose; + dropDown("Plant Library###dropdown", canopy_dict[current_canopy].library_name_verbose, plant_types_verbose); + if (canopy_dict[current_canopy].library_name_verbose != prev_lib) + canopy_dict[current_canopy].is_dirty = true; + canopy_dict[current_canopy].library_name = plant_type_lookup[canopy_dict[current_canopy].library_name_verbose]; + // ######### CANOPY DATA GROUP ####### // + ImGui::SetNextItemWidth(100); + std::string prev_canopy_data_group = canopy_dict[current_canopy].data_group; + ImGui::InputText("##canopy_data_group", &canopy_dict[current_canopy].data_group); + if (canopy_dict[current_canopy].data_group == "All" || canopy_dict[current_canopy].data_group.empty()) { + canopy_dict[current_canopy].data_group = prev_canopy_data_group; + } + if (!canopy_dict[current_canopy].data_group.empty() && prev_canopy_data_group != canopy_dict[current_canopy].data_group) { + std::string new_data_group = canopy_dict[current_canopy].data_group; + for (int i = 0; i < canopy_dict[current_canopy].IDs.size(); i++) { + std::vector new_canopy_objIDs = plantarchitecture->getAllPlantObjectIDs(canopy_dict[current_canopy].IDs[i]); + for (auto &obj : new_canopy_objIDs) { + context->clearObjectData(obj, prev_canopy_data_group.c_str()); + context->setObjectData(obj, "data_group", new_data_group); + context->setObjectData(obj, new_data_group.c_str(), 1); + } + // context->clearObjectData(new_canopy_objIDs, prev_canopy_data_group.c_str()); + // context->setObjectData(new_canopy_objIDs, "data_group", new_data_group); + // context->setObjectData(new_canopy_objIDs, new_data_group.c_str(), new_canopy_objIDs); + } + updateDataGroups(); + } + ImGui::SameLine(); + ImGui::Text("Data Group"); + // ####### CANOPY ORIGIN ####### // + vec3 prev_canopy_origin_ = vec3(canopy_dict[current_canopy].origin); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##canopy_origin_x", &canopy_dict[current_canopy].origin.x); + randomizePopup("canopy_origin_x_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].origin.x)); + randomizerParams("canopy_origin_x_" + std::to_string(canopy_dict[current_canopy].idx)); + ImGui::OpenPopupOnItemClick(("randomize_canopy_origin_x_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##canopy_origin_y", &canopy_dict[current_canopy].origin.y); + randomizePopup("canopy_origin_y_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].origin.y)); + randomizerParams("canopy_origin_y_" + std::to_string(canopy_dict[current_canopy].idx)); + ImGui::OpenPopupOnItemClick(("randomize_canopy_origin_y_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##canopy_origin_z", &canopy_dict[current_canopy].origin.z); + randomizePopup("canopy_origin_z_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].origin.z)); + randomizerParams("canopy_origin_z_" + std::to_string(canopy_dict[current_canopy].idx)); + ImGui::OpenPopupOnItemClick(("randomize_canopy_origin_z_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Canopy Origin"); + if (prev_canopy_origin_ != canopy_dict[current_canopy].origin) { + canopy_dict[current_canopy].is_dirty = true; + } + // ####### PLANT COUNT ####### // + int2 prev_plant_count_ = int2(canopy_dict[current_canopy].plant_count); + ImGui::SetNextItemWidth(100); + ImGui::InputInt("##plant_count_x", &canopy_dict[current_canopy].plant_count.x); + canopy_dict[current_canopy].plant_count.x = std::max(canopy_dict[current_canopy].plant_count.x, 1); + randomizePopup("plant_count_x_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].plant_count.x)); + randomizerParams("plant_count_x_" + std::to_string(canopy_dict[current_canopy].idx)); + ImGui::OpenPopupOnItemClick(("randomize_plant_count_x_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + ImGui::InputInt("##plant_count_y", &canopy_dict[current_canopy].plant_count.y); + canopy_dict[current_canopy].plant_count.y = std::max(canopy_dict[current_canopy].plant_count.y, 1); + randomizePopup("plant_count_y_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].plant_count.y)); + randomizerParams("plant_count_y_" + std::to_string(canopy_dict[current_canopy].idx)); + ImGui::OpenPopupOnItemClick(("randomize_plant_count_y_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Plant Count"); + if (prev_plant_count_ != canopy_dict[current_canopy].plant_count) { + canopy_dict[current_canopy].is_dirty = true; + } + // ####### PLANT SPACING ####### // + vec2 prev_plant_spacing_ = vec2(canopy_dict[current_canopy].plant_spacing); + ImGui::SetNextItemWidth(50); + ImGui::InputFloat("##plant_spacing_x", &canopy_dict[current_canopy].plant_spacing.x); + randomizePopup("plant_spacing_x_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].plant_spacing.x)); + randomizerParams("plant_spacing_x_" + std::to_string(canopy_dict[current_canopy].idx)); + ImGui::OpenPopupOnItemClick(("randomize_plant_spacing_x_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(50); + ImGui::InputFloat("##plant_spacing_y", &canopy_dict[current_canopy].plant_spacing.y); + randomizePopup("plant_spacing_y_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].plant_spacing.y)); + randomizerParams("plant_spacing_y_" + std::to_string(canopy_dict[current_canopy].idx)); + ImGui::OpenPopupOnItemClick(("randomize_plant_spacing_y_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Plant Spacing"); + if (prev_plant_spacing_ != canopy_dict[current_canopy].plant_spacing) { + canopy_dict[current_canopy].is_dirty = true; + } + // ####### PLANT AGE ####### // + float prev_age_ = canopy_dict[current_canopy].age; + ImGui::SetNextItemWidth(80); + ImGui::InputFloat("Plant Age", &canopy_dict[current_canopy].age); + randomizePopup("plant_age_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].age)); + randomizerParams("plant_age_" + std::to_string(canopy_dict[current_canopy].idx)); + ImGui::OpenPopupOnItemClick(("randomize_plant_age_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); + if (prev_age_ != canopy_dict[current_canopy].age) { + canopy_dict[current_canopy].is_dirty = true; + } + // ####### GROUND CLIPPING HEIGHT ####### // + float prev_ground_clipping_height_ = canopy_dict[current_canopy].ground_clipping_height; + ImGui::SetNextItemWidth(80); + ImGui::InputFloat("Ground Clipping Height", &canopy_dict[current_canopy].ground_clipping_height); + randomizePopup("ground_clipping_height_" + std::to_string(canopy_dict[current_canopy].idx), createTaggedPtr(&canopy_dict[current_canopy].ground_clipping_height)); + randomizerParams("ground_clipping_height_" + std::to_string(canopy_dict[current_canopy].idx)); + ImGui::OpenPopupOnItemClick(("randomize_ground_clipping_height_" + std::to_string(canopy_dict[current_canopy].idx)).c_str(), ImGuiPopupFlags_MouseButtonRight); + if (prev_ground_clipping_height_ != canopy_dict[current_canopy].ground_clipping_height) { + canopy_dict[current_canopy].is_dirty = true; + } + if (ImGui::Button("Save Canopy to OBJ/PLY File")) { + std::string new_obj_file = save_as_file_dialog(std::vector{"OBJ", "PLY"}); + if (!new_obj_file.empty()) { + std::string file_extension = new_obj_file; + size_t last_obj_file = file_extension.rfind('.'); + if (last_obj_file != std::string::npos) { + file_extension = file_extension.substr(last_obj_file + 1); + } + if (file_extension == "obj" || file_extension == "ply") { + if (!std::filesystem::exists(new_obj_file)) { + // Create file + std::ofstream outFile(new_obj_file); + } + if (!save_plants_individually) { + saveCanopy(new_obj_file, canopy_dict[current_canopy].IDs, canopy_dict[current_canopy].origin, file_extension); + } else { + saveCanopy(new_obj_file, canopy_dict[current_canopy].IDs, canopy_dict[current_canopy].individual_plant_locations, file_extension); + } + } else { + // Needs to be a obj or ply file + std::cout << "Not a valid file type. Object must be saved to .obj or .ply file." << std::endl; + } + } else { + // Not a valid file + std::cout << "Not a valid file." << std::endl; + } + } + ImGui::SameLine(); + ImGui::Checkbox("Save plants individually", &save_plants_individually); + } +#endif +} + + +void ProjectBuilder::generalTab() { +#ifdef ENABLE_HELIOS_VISUALIZER + // ####### LOCATION ####### // + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Visualization:"); + ImGui::SetWindowFontScale(1.0f); + // ####### COORDINATE AXES ####### // + bool enable_coords_ = enable_coordinate_axes; + toggle_button("##coordinate_axes", &enable_coordinate_axes); + if (enable_coords_ != enable_coordinate_axes) { + if (enable_coordinate_axes) { + visualizer->addCoordinateAxes(helios::make_vec3(0, 0, 0.05), helios::make_vec3(1, 1, 1), "positive"); + is_dirty = true; + } else { + visualizer->disableCoordinateAxes(); + is_dirty = true; + } + } + ImGui::SameLine(); + if (enable_coordinate_axes) { + ImGui::Text("Coordinate Axes Enabled"); + } else { + ImGui::Text("Coordinate Axes Disabled"); + } + // ####### COLORBAR ####### // + bool enable_colorbar_ = enable_colorbar; + toggle_button("##colorbar", &enable_colorbar); + if (enable_colorbar_ != enable_colorbar) { + if (enable_colorbar) { + visualizer->enableColorbar(); + is_dirty = true; + } else { + visualizer->disableColorbar(); + is_dirty = true; + } + } + ImGui::SameLine(); + if (enable_colorbar) { + ImGui::Text("Colorbar Enabled"); + } else { + ImGui::Text("Colorbar Disabled"); + } + // ####### LIGHTING MODEL ####### // + std::string prev_lighting_model = lighting_model; + ImGui::SetNextItemWidth(120); + dropDown("Lighting Model", lighting_model, lighting_models); + if (prev_lighting_model != lighting_model) { + if (lighting_model == "None") + visualizer->setLightingModel(Visualizer::LIGHTING_NONE); + if (lighting_model == "Phong") + visualizer->setLightingModel(Visualizer::LIGHTING_PHONG); + if (lighting_model == "Phong Shadowed") + visualizer->setLightingModel(Visualizer::LIGHTING_PHONG_SHADOWED); + } + ImGui::SetNextItemWidth(120); + // ####### LIGHTING INTENSITY ####### // + ImGui::InputFloat("Light Intensity Factor", &light_intensity); + visualizer->setLightIntensityFactor(light_intensity); + // ####### LIGHTING DIRECTION ####### // + toggle_button("##light_coord_type", &light_coord_type); + ImGui::SameLine(); + if (light_coord_type) { + SphericalCoord light_dir_sphere_ = cart2sphere(light_direction); + vec2 light_dir_sphere; + light_dir_sphere.x = rad2deg(light_dir_sphere_.elevation); + light_dir_sphere.y = rad2deg(light_dir_sphere_.azimuth); + ImGui::Text("Elevation:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80); + ImGui::InputFloat("##light_elevation", &light_dir_sphere.x); + ImGui::SameLine(); + ImGui::Text("Azimuth:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80); + ImGui::InputFloat("##light_azimuth", &light_dir_sphere.y); + ImGui::SameLine(); + ImGui::Text("Light Direction (Spherical)"); + if (light_dir_sphere.x != light_dir_sphere_.elevation || light_dir_sphere.y != light_dir_sphere_.azimuth) { + SphericalCoord light_dir = make_SphericalCoord(deg2rad(light_dir_sphere.x), deg2rad(light_dir_sphere.y)); + light_direction = sphere2cart(light_dir); + } + } else { + float light_dir[3]; + light_dir[0] = light_direction.x; + light_dir[1] = light_direction.y; + light_dir[2] = light_direction.z; + ImGui::InputFloat3("Light Direction (Cartesian)", light_dir); + light_direction.x = light_dir[0]; + light_direction.y = light_dir[1]; + light_direction.z = light_dir[2]; + } + visualizer->setLightDirection(light_direction); + // ####### LOCATION ####### // + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Location:"); + ImGui::SetWindowFontScale(1.0f); + if (ImGui::Button("Update Location")) { + updateLocation(); + } + // ####### LATITUDE ####### // + ImGui::SetNextItemWidth(100); + ImGui::InputFloat("Latitude", &latitude); + randomizePopup("latitude", createTaggedPtr(&latitude)); + randomizerParams("latitude"); + ImGui::OpenPopupOnItemClick("randomize_latitude", ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + // ####### LONGITUDE ####### // + ImGui::SetNextItemWidth(100); + ImGui::InputFloat("Longitude", &longitude); + randomizePopup("longitude", createTaggedPtr(&longitude)); + randomizerParams("longitude"); + ImGui::OpenPopupOnItemClick("randomize_longitude", ImGuiPopupFlags_MouseButtonRight); + // ####### UTC OFFSET ####### // + ImGui::SetNextItemWidth(100); + ImGui::InputInt("UTC Offset", &UTC_offset); + randomizePopup("UTC_offset", createTaggedPtr(&UTC_offset)); + randomizerParams("UTC_offset"); + ImGui::OpenPopupOnItemClick("randomize_UTC_offset", ImGuiPopupFlags_MouseButtonRight); + // ####### Weather File ####### // + ImGui::SetNextItemWidth(60); + ImGui::RadioButton("CSV", is_weather_file_csv); + if (ImGui::IsItemClicked()) + is_weather_file_csv = true; + ImGui::SameLine(); + ImGui::RadioButton("CIMIS", !is_weather_file_csv); + if (ImGui::IsItemClicked()) + is_weather_file_csv = false; + std::string prev_weather_file; + std::string *weather_file; + if (is_weather_file_csv) { + ImGui::Text("CSV"); + weather_file = &csv_weather_file; + prev_weather_file = csv_weather_file; + } else { + ImGui::Text("CIMIS"); + weather_file = &cimis_weather_file; + prev_weather_file = cimis_weather_file; + } + ImGui::SameLine(); + if (ImGui::Button("Weather File")) { + std::string weather_file_ = file_dialog(); + if (!weather_file_.empty()) { + *weather_file = weather_file_; + try { + if (is_weather_file_csv) { + context->loadTabularTimeseriesData(*weather_file, {}, ",", "YYYYMMDD", 1); + } else { + context->loadTabularTimeseriesData(*weather_file, {"CIMIS"}, ","); + } + } catch (...) { + std::cout << "Failed to load weather file: " << *weather_file << std::endl; + *weather_file = prev_weather_file; + } + } else { + *weather_file = prev_weather_file; + } + } + ImGui::SameLine(); + std::string shorten_weather_file = *weather_file; + for (char &c: shorten_weather_file) { + if (c == '\\') { + c = '/'; + } + } + size_t last_weather_file = shorten_weather_file.rfind('/'); + if (last_weather_file != std::string::npos) { + shorten_weather_file = shorten_weather_file.substr(last_weather_file + 1); + } + ImGui::Text("%s", shorten_weather_file.c_str()); + // ####### GROUND ####### // + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Ground:"); + ImGui::SetWindowFontScale(1.0f); + if (ImGui::Button("Update Ground")) { + updateGround(); + updatePrimitiveTypes(); + updateSpectra(); + is_dirty = true; + } + ImGui::SameLine(); + if (ImGui::Button("Delete Ground")) { + deleteGround(); + updatePrimitiveTypes(); + updateSpectra(); + is_dirty = true; + } + // ImGui::RadioButton("Manually Set Color", ground_flag == 0); if (ImGui::IsItemClicked()) ground_flag = 0; + // ImGui::SameLine(); + ImGui::RadioButton("Use Texture File", ground_flag == 1); + if (ImGui::IsItemClicked()) + ground_flag = 1; + ImGui::SameLine(); + ImGui::RadioButton("Use Model File", ground_flag == 2); + if (ImGui::IsItemClicked()) + ground_flag = 2; + if (ground_flag == 0) { + // ####### GROUND COLOR ####### // + ImGui::ColorEdit3("##ground_color_edit", ground_color); + } else if (ground_flag == 1) { + // ####### GROUND TEXTURE File ####### // + ImGui::SetNextItemWidth(60); + if (ImGui::Button("Ground Texture File")) { + std::string ground_texture_file_ = file_dialog(); + if (!ground_texture_file_.empty()) { + ground_texture_file = ground_texture_file_; + } + } + ImGui::SameLine(); + std::string shorten = ground_texture_file; + for (char &c: shorten) { + if (c == '\\') { + c = '/'; + } + } + size_t last = shorten.rfind('/'); + if (last != std::string::npos) { + shorten = shorten.substr(last + 1); + } + ImGui::Text("%s", shorten.c_str()); + } else if (ground_flag == 2) { + // ####### GROUND Model File ####### // + ImGui::SetNextItemWidth(60); + if (ImGui::Button("Ground Model File")) { + std::string ground_model_file_ = file_dialog(); + if (!ground_model_file_.empty()) { + ground_model_file = ground_model_file_; + } + } + ImGui::SameLine(); + ImGui::Text("%s", shortenPath(ground_model_file).c_str()); + } + toggle_button("##use_ground_texture_color", &use_ground_texture); + // ####### GROUND COLOR ####### // + if (use_ground_texture) { + ImGui::SameLine(); + ImGui::Text("Use Ground Texture Color"); + } else { + ImGui::SameLine(); + ImGui::ColorEdit3("##ground_color_edit", ground_color); + ImGui::SameLine(); + ImGui::Text("Manually Set Ground Color"); + } + // ####### DOMAIN ORIGIN ####### // + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##domain_origin_x", &domain_origin.x); + randomizePopup("domain_origin_x", createTaggedPtr(&domain_origin.x)); + randomizerParams("domain_origin_x"); + ImGui::OpenPopupOnItemClick("randomize_domain_origin_x", ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##domain_origin_y", &domain_origin.y); + randomizePopup("domain_origin_y", createTaggedPtr(&domain_origin.y)); + randomizerParams("domain_origin_y"); + ImGui::OpenPopupOnItemClick("randomize_domain_origin_y", ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##domain_origin_z", &domain_origin.z); + randomizePopup("domain_origin_z", createTaggedPtr(&domain_origin.z)); + randomizerParams("domain_origin_z"); + ImGui::OpenPopupOnItemClick("randomize_domain_origin_z", ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Domain Origin"); + if (ground_flag == 1) { + // ####### GROUND RESOLUTION ####### // + ImGui::SetNextItemWidth(100); + ImGui::InputInt("##ground_resolution_x", &ground_resolution.x); + randomizePopup("ground_resolution_x", createTaggedPtr(&ground_resolution.x)); + randomizerParams("ground_resolution_x"); + ImGui::OpenPopupOnItemClick("randomize_ground_resolution_x", ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + ImGui::InputInt("##ground_resolution_y", &ground_resolution.y); + randomizePopup("ground_resolution_y", createTaggedPtr(&ground_resolution.y)); + randomizerParams("ground_resolution_y"); + ImGui::OpenPopupOnItemClick("randomize_ground_resolution_y", ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Ground Resolution"); + // ####### DOMAIN EXTENT ####### // + ImGui::SetNextItemWidth(50); + ImGui::InputFloat("##domain_extent_x", &domain_extent.x); + randomizePopup("domain_extent_x", createTaggedPtr(&domain_extent.x)); + randomizerParams("domain_extent_x"); + ImGui::OpenPopupOnItemClick("randomize_domain_extent_x", ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(50); + ImGui::InputFloat("##domain_extent_y", &domain_extent.y); + randomizePopup("domain_extent_y", createTaggedPtr(&domain_extent.y)); + randomizerParams("domain_extent_y"); + ImGui::OpenPopupOnItemClick("randomize_domain_extent_y", ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Domain Extent"); + // ####### NUMBER OF TILES ####### // + ImGui::SetNextItemWidth(60); + int temp[2]; + temp[0] = num_tiles.x; + temp[1] = num_tiles.y; + ImGui::InputInt2("Number of Tiles", temp); + num_tiles.x = temp[0]; + num_tiles.y = temp[1]; + } +#endif +} + + +void ProjectBuilder::objectTab() { +#ifdef ENABLE_HELIOS_VISUALIZER + if (ImGui::Button("Load Object File")) { + std::string new_obj_file = file_dialog(); + if (!new_obj_file.empty() && std::filesystem::exists(new_obj_file)) { + if (std::filesystem::path(new_obj_file).extension() != ".obj" && std::filesystem::path(new_obj_file).extension() != ".ply") { + std::cout << "Object file must have .obj or .ply extension." << std::endl; + } else { + object new_obj; + std::vector new_UUIDs; + if (std::filesystem::path(new_obj_file).extension() == ".obj") { + new_UUIDs = context->loadOBJ(new_obj_file.c_str()); + } else if (std::filesystem::path(new_obj_file).extension() == ".ply") { + new_UUIDs = context->loadPLY(new_obj_file.c_str()); + } + // check for MTL file + std::filesystem::path mtl_path(new_obj_file); + mtl_path.replace_extension("mtl"); + if (std::filesystem::exists(mtl_path)) { + new_obj.use_texture_file = true; + } else { + new_obj.use_texture_file = false; + } + // visualizer->buildContextGeometry(context); + // visualizer->plotUpdate(); + std::string default_object_label = "object"; + std::string new_obj_label = "object_0"; + int count = 0; + while (objects_dict.find(new_obj_label) != objects_dict.end()) { + count++; + new_obj_label = default_object_label + "_" + std::to_string(count); + } + obj_names_set.insert(new_obj_label); + new_obj.index = obj_idx; + obj_idx++; + new_obj.name = new_obj_label; + new_obj.file = new_obj_file; + new_obj.UUIDs = new_UUIDs; + new_obj.objID = context->addPolymeshObject(new_UUIDs); // TODO: change transformations to object level + new_obj.position = vec3(0, 0, 0); + new_obj.prev_position = vec3(0, 0, 0); + new_obj.orientation = vec3(0, 0, 0); + new_obj.prev_orientation = vec3(0, 0, 0); + new_obj.scale = vec3(1, 1, 1); + new_obj.prev_scale = vec3(1, 1, 1); + new_obj.color = RGBcolor(0, 0, 1); + new_obj.prev_color = RGBcolor(0, 0, 1); + new_obj.data_group = ""; + new_obj.is_dirty = false; + current_obj = new_obj_label; + objects_dict[new_obj_label] = new_obj; + + is_dirty = true; + } + } + } + if (ImGui::BeginCombo("##obj_combo", current_obj.c_str())) { + for (std::string obj_name: obj_names_set) { + bool is_obj_selected = (current_obj == obj_name); + if (ImGui::Selectable(obj_name.c_str(), is_obj_selected)) + current_obj = obj_name; + if (is_obj_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Select Object"); + if (!current_obj.empty()) { + if (ImGui::Button("Delete Object")) { + deleteObject(current_obj); + } + if (objects_dict[current_obj].is_dirty) { + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255)); // Red text + ImGui::Text("update required"); + ImGui::PopStyleColor(); + } + ImGui::SetNextItemWidth(100); + std::string prev_obj_name = objects_dict[current_obj].name; + ImGui::InputText("##obj_name", &objects_dict[current_obj].name); + if (objects_dict[current_obj].name != prev_obj_name && !objects_dict[current_obj].name.empty() && obj_names_set.find(objects_dict[current_obj].name) == obj_names_set.end()) { + object temp_obj = objects_dict[prev_obj_name]; + current_obj = objects_dict[current_obj].name; + std::map::iterator delete_obj_iter = objects_dict.find(prev_obj_name); + if (delete_obj_iter != objects_dict.end()) { + objects_dict.erase(delete_obj_iter); + } + objects_dict[current_obj] = temp_obj; + obj_names_set.erase(prev_obj_name); + obj_names_set.insert(current_obj); + } else { + objects_dict[current_obj].name = prev_obj_name; + } + ImGui::SameLine(); + ImGui::Text("Object Name"); + if (!current_obj.empty()) { + // ####### OBJECT DATA GROUP ####### // + ImGui::SetNextItemWidth(100); + std::string prev_obj_data_group = objects_dict[current_obj].data_group; + ImGui::InputText("##obj_data_group", &objects_dict[current_obj].data_group); + if (objects_dict[current_obj].data_group == "All" || objects_dict[current_obj].data_group.empty()) { + objects_dict[current_obj].data_group = prev_obj_data_group; + } + if (!objects_dict[current_obj].data_group.empty() && prev_obj_data_group != objects_dict[current_obj].data_group) { + if ( context->doesObjectDataExist(objects_dict[current_obj].objID, prev_obj_data_group.c_str()) ) { + context->clearObjectData(objects_dict[current_obj].objID, prev_obj_data_group.c_str()); + } + std::string new_data_group = objects_dict[current_obj].data_group; + context->setObjectData(objects_dict[current_obj].objID, "data_group", new_data_group); + int index = objects_dict[current_obj].index; + context->setObjectData(objects_dict[current_obj].objID, new_data_group.c_str(), index); + updateDataGroups(); + } + ImGui::SameLine(); + ImGui::Text("Data Group"); + bool use_obj_texture = objects_dict[current_obj].use_texture_file; + toggle_button("##use_texture_file", &use_obj_texture); + if (use_obj_texture != objects_dict[current_obj].use_texture_file) { + objects_dict[current_obj].use_texture_file = use_obj_texture; + objects_dict[current_obj].is_dirty = true; + updateObject(current_obj); + is_dirty = true; + } + ImGui::SameLine(); + if (!use_obj_texture) { + // ####### OBJECT COLOR ####### // + float col[3]; + col[0] = objects_dict[current_obj].color.r; + col[1] = objects_dict[current_obj].color.g; + col[2] = objects_dict[current_obj].color.b; + ImGui::ColorEdit3("##obj_color_edit", col); + if (objects_dict[current_obj].color.r != col[0] || objects_dict[current_obj].color.g != col[1] || objects_dict[current_obj].color.b != col[2]) { + updateColor(current_obj, "obj", col); + } + ImGui::SameLine(); + ImGui::Text("Object Color"); + } else { + // ####### OBJECT TEXTURE FILE ####### // + ImGui::Text("Use Color from Texture File"); + } + // ####### OBJECT SCALE ####### // + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##obj_scale_x", &objects_dict[current_obj].scale.x); + randomizePopup("obj_scale_x_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].scale.x, &objects_dict[current_obj].is_dirty)); + randomizerParams("obj_scale_x_" + std::to_string(objects_dict[current_obj].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_scale_x_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##obj_scale_y", &objects_dict[current_obj].scale.y); + randomizePopup("obj_scale_y_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].scale.y, &objects_dict[current_obj].is_dirty)); + randomizerParams("obj_scale_y_" + std::to_string(objects_dict[current_obj].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_scale_y_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##obj_scale_z", &objects_dict[current_obj].scale.z); + randomizePopup("obj_scale_z_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].scale.z, &objects_dict[current_obj].is_dirty)); + randomizerParams("obj_scale_z_" + std::to_string(objects_dict[current_obj].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_scale_z_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Object Scale"); + // ####### OBJECT POSITION ####### // + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##obj_position_x", &objects_dict[current_obj].position.x); + randomizePopup("obj_position_x_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].position.x, &objects_dict[current_obj].is_dirty)); + randomizerParams("obj_position_x_" + std::to_string(objects_dict[current_obj].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_position_x_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##obj_position_y", &objects_dict[current_obj].position.y); + randomizePopup("obj_position_y_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].position.y, &objects_dict[current_obj].is_dirty)); + randomizerParams("obj_position_y_" + std::to_string(objects_dict[current_obj].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_position_y_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##obj_position_z", &objects_dict[current_obj].position.z); + randomizePopup("obj_position_z_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].position.z, &objects_dict[current_obj].is_dirty)); + randomizerParams("obj_position_z_" + std::to_string(objects_dict[current_obj].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_position_z_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Object Position"); + // ####### OBJECT ORIENTATION ####### // + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##obj_orientation_x", &objects_dict[current_obj].orientation.x); + randomizePopup("obj_orientation_x_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].orientation.x, &objects_dict[current_obj].is_dirty)); + randomizerParams("obj_orientation_x_" + std::to_string(objects_dict[current_obj].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_x_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##obj_orientation_y", &objects_dict[current_obj].orientation.y); + randomizePopup("obj_orientation_y_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].orientation.y, &objects_dict[current_obj].is_dirty)); + randomizerParams("obj_orientation_y_" + std::to_string(objects_dict[current_obj].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_y_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##obj_orientation_z", &objects_dict[current_obj].orientation.z); + randomizePopup("obj_orientation_z_" + std::to_string(objects_dict[current_obj].index), createTaggedPtr(&objects_dict[current_obj].orientation.z, &objects_dict[current_obj].is_dirty)); + randomizerParams("obj_orientation_z_" + std::to_string(objects_dict[current_obj].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_z_" + std::to_string(objects_dict[current_obj].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Object Orientation"); + if (objects_dict[current_obj].position != objects_dict[current_obj].prev_position || objects_dict[current_obj].orientation != objects_dict[current_obj].prev_orientation || + objects_dict[current_obj].scale != objects_dict[current_obj].prev_scale || objects_dict[current_obj].color != objects_dict[current_obj].prev_color) { + objects_dict[current_obj].is_dirty = true; + } + if (objects_dict[current_obj].is_dirty && !ImGui::IsAnyItemActive() && !ImGui::IsAnyItemFocused()) { + updateObject(current_obj); + } + } + } +#endif +} + + +void ProjectBuilder::objectTab(std::string curr_obj_name, int id) { +#ifdef ENABLE_HELIOS_VISUALIZER + if (ImGui::Button("Delete Object")) { + deleteObject(curr_obj_name); + is_dirty = true; + } + ImGui::SetNextItemWidth(100); + std::string prev_obj_name = objects_dict[curr_obj_name].name; + ImGui::InputText(("##obj_name_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].name); + if (objects_dict[curr_obj_name].name != prev_obj_name && objects_dict.find(curr_obj_name) == objects_dict.end() && !objects_dict[curr_obj_name].name.empty()) { + object temp_obj = objects_dict[curr_obj_name]; + curr_obj_name = objects_dict[curr_obj_name].name; + std::map::iterator delete_obj_iter = objects_dict.find(prev_obj_name); + if (delete_obj_iter != objects_dict.end()) { + objects_dict.erase(delete_obj_iter); + } + + objects_dict[objects_dict[curr_obj_name].name] = temp_obj; + + obj_names_set.erase(prev_obj_name); + obj_names_set.insert(objects_dict[curr_obj_name].name); + } else { + objects_dict[curr_obj_name].name = prev_obj_name; + } + ImGui::SameLine(); + ImGui::Text("Object Name"); + // ####### OBJECT SCALE ####### // + vec3 prev_obj_scale = vec3(objects_dict[curr_obj_name].scale); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat(("##obj_scale_x_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].scale.x); + randomizePopup("obj_scale_x_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].scale.x, &objects_dict[curr_obj_name].is_dirty)); + randomizerParams("obj_scale_x_" + std::to_string(objects_dict[curr_obj_name].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_scale_x_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat(("##obj_scale_y_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].scale.y); + randomizePopup("obj_scale_y_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].scale.y, &objects_dict[curr_obj_name].is_dirty)); + randomizerParams("obj_scale_y_" + std::to_string(objects_dict[curr_obj_name].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_scale_y_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat(("##obj_scale_z_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].scale.z); + randomizePopup("obj_scale_z_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].scale.z, &objects_dict[curr_obj_name].is_dirty)); + randomizerParams("obj_scale_z_" + std::to_string(objects_dict[curr_obj_name].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_scale_z_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Object Scale"); + if (prev_obj_scale != objects_dict[curr_obj_name].scale) { + objects_dict[curr_obj_name].is_dirty = true; + } + // ####### OBJECT POSITION ####### // + ImGui::SetNextItemWidth(60); + vec3 prev_obj_pos = vec3(objects_dict[curr_obj_name].scale); + ImGui::InputFloat(("##obj_position_x_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].position.x); + randomizePopup("obj_position_x_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].position.x, &objects_dict[curr_obj_name].is_dirty)); + randomizerParams("obj_position_x_" + std::to_string(objects_dict[curr_obj_name].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_position_x_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat(("##obj_position_y_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].position.y); + randomizePopup("obj_position_y_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].position.y, &objects_dict[curr_obj_name].is_dirty)); + randomizerParams("obj_position_y_" + std::to_string(objects_dict[curr_obj_name].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_position_y_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat(("##obj_position_z_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].position.z); + randomizePopup("obj_position_z_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].position.z, &objects_dict[curr_obj_name].is_dirty)); + randomizerParams("obj_position_z_" + std::to_string(objects_dict[curr_obj_name].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_position_z_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Object Position"); + if (prev_obj_pos != objects_dict[curr_obj_name].position) { + objects_dict[curr_obj_name].is_dirty = true; + } + // ####### OBJECT ORIENTATION ####### // + ImGui::SetNextItemWidth(60); + vec3 prev_obj_orientation = vec3(objects_dict[curr_obj_name].orientation); + ImGui::InputFloat(("##obj_orientation_x_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].orientation.x); + randomizePopup("obj_orientation_x_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].orientation.x, &objects_dict[curr_obj_name].is_dirty)); + randomizerParams("obj_orientation_x_" + std::to_string(objects_dict[curr_obj_name].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_x_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat(("##obj_orientation_y_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].orientation.y); + randomizePopup("obj_orientation_y_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].orientation.y, &objects_dict[curr_obj_name].is_dirty)); + randomizerParams("obj_orientation_y_" + std::to_string(objects_dict[curr_obj_name].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_y_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat(("##obj_orientation_z_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].orientation.z); + randomizePopup("obj_orientation_z_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].orientation.z, &objects_dict[curr_obj_name].is_dirty)); + randomizerParams("obj_orientation_z_" + std::to_string(objects_dict[curr_obj_name].index)); + ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_z_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Object Orientation"); + if (prev_obj_orientation != objects_dict[curr_obj_name].orientation) { + objects_dict[curr_obj_name].is_dirty = true; + } + if (objects_dict[current_obj].is_dirty && !ImGui::IsAnyItemActive() && !ImGui::IsAnyItemFocused()) { + updateObject(current_obj); + } +#endif +} + +void ProjectBuilder::radiationTab() { +#if defined(ENABLE_HELIOS_VISUALIZER) && defined(ENABLE_RADIATION_MODEL) + // LOAD XML LIBRARY FILE + ImGui::SetNextItemWidth(60); + if (ImGui::Button("Load XML Library File")) { + std::string new_xml_library_file = file_dialog(); + if (!new_xml_library_file.empty() && std::filesystem::exists(new_xml_library_file)) { + if (xml_library_files.find(new_xml_library_file) == xml_library_files.end()) { + xml_library_files.insert(new_xml_library_file); + std::vector current_spectra_file = get_xml_node_values(new_xml_library_file, "label", "globaldata_vec2"); + for (int i = 0; i < current_spectra_file.size(); i++) { + possible_spectra.insert(current_spectra_file[i]); + } + } + context->loadXML(new_xml_library_file.c_str()); + } + } + // ####### GLOBAL PROPERTIES ####### // + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Global Properties:"); + ImGui::SetWindowFontScale(1.0f); + // ####### ENFORCE PERIODIC BOUNDARY CONDITION ####### // + ImGui::Text("Enforce Periodic Boundary Condition:"); + ImGui::SameLine(); + bool prev_cond_x = enforce_periodic_boundary_x; + ImGui::Checkbox("x###periodic_boundary_x", &enforce_periodic_boundary_x); + ImGui::SameLine(); + bool prev_cond_y = enforce_periodic_boundary_y; + ImGui::Checkbox("y###periodic_boundary_y", &enforce_periodic_boundary_y); + if (prev_cond_x != enforce_periodic_boundary_x || prev_cond_y != enforce_periodic_boundary_y) { + if (enforce_periodic_boundary_x && enforce_periodic_boundary_y) + radiation->enforcePeriodicBoundary("xy"); + else if (enforce_periodic_boundary_x) + radiation->enforcePeriodicBoundary("x"); + else if (enforce_periodic_boundary_y) + radiation->enforcePeriodicBoundary("y"); + else + radiation->enforcePeriodicBoundary(""); + } + // ####### DIFFUSE EXTINCTION COEFFICIENT ####### // + ImGui::SetNextItemWidth(60); + float prev_value = diffuse_extinction_coeff; + ImGui::InputFloat("Diffuse Extinction Coefficient", &diffuse_extinction_coeff); + if (prev_value != diffuse_extinction_coeff) { + context->setGlobalData("diffuse_extinction_coeff", diffuse_extinction_coeff); + } + randomizePopup("diffuse_extinction_coeff", createTaggedPtr(&diffuse_extinction_coeff)); + randomizerParams("diffuse_extinction_coeff"); + ImGui::OpenPopupOnItemClick("randomize_diffuse_extinction_coeff", ImGuiPopupFlags_MouseButtonRight); + // ####### AIR TURBIDITY ####### // + ImGui::SetNextItemWidth(60); + prev_value = air_turbidity; + ImGui::InputFloat("Air Turbidity", &air_turbidity); + if (prev_value != air_turbidity) { + if (air_turbidity > 0) { + context->setGlobalData("air_turbidity", air_turbidity); + } else if (air_turbidity < 0) { // try calibration + if (context->doesTimeseriesVariableExist("net_radiation")) { + air_turbidity = solarposition->calibrateTurbidityFromTimeseries("net_radiation"); + if (air_turbidity > 0 && air_turbidity < 1) { + context->setGlobalData("air_turbidity", air_turbidity); + } + } + } + } + randomizePopup("air_turbidity", createTaggedPtr(&air_turbidity)); + randomizerParams("air_turbidity"); + ImGui::OpenPopupOnItemClick("randomize_air_turbidity", ImGuiPopupFlags_MouseButtonRight); + // ####### SOLAR DIRECT SPECTRUM ####### // + ImGui::SetNextItemWidth(250); + // ImGui::InputText("Solar Direct Spectrum", &solar_direct_spectrum); + if (ImGui::BeginCombo("##combo_solar_direct_spectrum", solar_direct_spectrum.c_str())) { + for (auto &spectra: possible_spectra) { + bool is_solar_direct_spectrum_selected = (solar_direct_spectrum == spectra); + if (ImGui::Selectable(spectra.c_str(), is_solar_direct_spectrum_selected)) + solar_direct_spectrum = spectra; + if (is_solar_direct_spectrum_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Solar Direct Spectrum"); + // ####### BAND PROPERTIES ####### // + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Add Band:"); + ImGui::SetWindowFontScale(1.0f); + // ####### ADD BAND ####### // + toggle_button("##enable_wavelength", &enable_wavelength); + ImGui::SameLine(); + if (enable_wavelength) { + ImGui::Text("Wavelength Min:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##wavelength_min", &wavelength_min); + ImGui::SameLine(); + ImGui::Text("Max:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##wavelength_max", &wavelength_max); + } else { + ImGui::Text("No Specified Wavelength"); + } + // + ImGui::Text("Label:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + ImGui::InputText("##new_band_label", &new_band_label); + ImGui::SameLine(); + ImGui::Text("Emission:"); + ImGui::SameLine(); + ImGui::Checkbox("##enable_emission", &enable_emission); + ImGui::SameLine(); + if (ImGui::Button("Add Band")) { + if (enable_wavelength) { + addBand(new_band_label, wavelength_min, wavelength_max, enable_emission); + } else { + addBand(new_band_label, enable_emission); + bandlabels_set_wavelength.insert(new_band_label); + } + } + // ####### BAND PROPERTIES ####### // + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Band Properties:"); + ImGui::SetWindowFontScale(1.0f); + // ####### SELECT BAND ####### // + if (ImGui::BeginCombo("##combo_current_band", current_band.c_str())) { + for (std::string band: bandlabels_set) { + bool is_current_band_selected = (current_band == band); + if (ImGui::Selectable(band.c_str(), is_current_band_selected)) + current_band = band; + if (is_current_band_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Select Band"); + // ####### DIRECT RAY COUNT ####### // + int prev_direct_ray_count; + ImGui::SetNextItemWidth(100); + if (current_band == "All") { + prev_direct_ray_count = direct_ray_count; + ImGui::InputInt("Direct Ray Count", &direct_ray_count); + randomizePopup("direct_ray_count", createTaggedPtr(&direct_ray_count)); + randomizerParams("direct_ray_count"); + ImGui::OpenPopupOnItemClick("randomize_direct_ray_count", ImGuiPopupFlags_MouseButtonRight); + if (direct_ray_count != prev_direct_ray_count) { + for (std::string band: bandlabels) { + radiation->setDirectRayCount(band, direct_ray_count); + direct_ray_count_dict[band] = direct_ray_count; + } + } + } else { + prev_direct_ray_count = direct_ray_count_dict[current_band]; + ImGui::InputInt("Direct Ray Count", &direct_ray_count_dict[current_band]); + randomizePopup("direct_ray_count_" + current_band, createTaggedPtr(&direct_ray_count_dict[current_band])); + randomizerParams("direct_ray_count_" + current_band); + ImGui::OpenPopupOnItemClick(("randomize_direct_ray_count_" + current_band).c_str(), ImGuiPopupFlags_MouseButtonRight); + if (direct_ray_count_dict[current_band] != prev_direct_ray_count) { + radiation->setDirectRayCount(current_band, direct_ray_count_dict[current_band]); + } + } + // ####### DIFFUSE RAY COUNT ####### // + ImGui::SetNextItemWidth(100); + int prev_diffuse_ray_count; + if (current_band == "All") { + prev_diffuse_ray_count = diffuse_ray_count; + ImGui::InputInt("Diffuse Ray Count", &diffuse_ray_count); + randomizePopup("diffuse_ray_count", createTaggedPtr(&diffuse_ray_count)); + randomizerParams("diffuse_ray_count"); + ImGui::OpenPopupOnItemClick("randomize_diffuse_ray_count", ImGuiPopupFlags_MouseButtonRight); + if (diffuse_ray_count != prev_diffuse_ray_count) { + for (std::string band: bandlabels) { + radiation->setDiffuseRayCount(band, diffuse_ray_count); + diffuse_ray_count_dict[band] = diffuse_ray_count; + } + } + } else { + prev_diffuse_ray_count = diffuse_ray_count_dict[current_band]; + ImGui::InputInt("Diffuse Ray Count", &diffuse_ray_count_dict[current_band]); + randomizePopup("diffuse_ray_count_" + current_band, createTaggedPtr(&diffuse_ray_count_dict[current_band])); + randomizerParams("diffuse_ray_count_" + current_band); + ImGui::OpenPopupOnItemClick(("randomize_diffuse_ray_count_" + current_band).c_str(), ImGuiPopupFlags_MouseButtonRight); + if (diffuse_ray_count_dict[current_band] != prev_diffuse_ray_count) { + radiation->setDiffuseRayCount(current_band, diffuse_ray_count_dict[current_band]); + } + } + // ####### SCATTERING DEPTH ####### // + ImGui::SetNextItemWidth(100); + int prev_scattering_depth; + if (current_band == "All") { + prev_scattering_depth = scattering_depth; + ImGui::InputInt("Scattering Depth", &scattering_depth); + randomizePopup("scattering_depth", createTaggedPtr(&scattering_depth)); + randomizerParams("scattering_depth"); + ImGui::OpenPopupOnItemClick("randomize_scattering_depth", ImGuiPopupFlags_MouseButtonRight); + if (scattering_depth <= 0) { + scattering_depth = prev_scattering_depth; + } + if (prev_scattering_depth != scattering_depth) { + for (std::string band: bandlabels) { + radiation->setScatteringDepth(band, scattering_depth); + scattering_depth_dict[band] = scattering_depth; + } + } + } else { + prev_scattering_depth = scattering_depth_dict[current_band]; + ImGui::InputInt("Scattering Depth", &scattering_depth_dict[current_band]); + randomizePopup("scattering_depth_" + current_band, createTaggedPtr(&scattering_depth_dict[current_band])); + randomizerParams("scattering_depth_" + current_band); + ImGui::OpenPopupOnItemClick(("randomize_scattering_depth_" + current_band).c_str(), ImGuiPopupFlags_MouseButtonRight); + if (scattering_depth_dict[current_band] <= 0) { // scattering depth must be >0 + scattering_depth_dict[current_band] = prev_scattering_depth; + } + if (prev_scattering_depth != scattering_depth_dict[current_band]) { + radiation->setScatteringDepth(current_band, scattering_depth_dict[current_band]); + } + } + // ####### RADIATIVE PROPERTIES ####### // + ImGui::SetWindowFontScale(1.25f); + ImGui::Text("Radiative Properties:"); + ImGui::SetWindowFontScale(1.0f); + ImGui::SetNextItemWidth(100); + // ######### SELECT DATA GROUP ############// + // if (ImGui::Button("Refresh###data_groups_refresh")) { + // updatePrimitiveTypes(); + // updateDataGroups(); + // } + // ImGui::SameLine(); + ImGui::SetNextItemWidth(150); + if (ImGui::BeginCombo("##data_group_primitive", current_data_group.c_str())) { + for (std::string data_group: data_groups_set) { + bool is_data_group_selected = (current_data_group == data_group); + if (ImGui::Selectable(data_group.c_str(), is_data_group_selected)) + current_data_group = data_group; + if (is_data_group_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + ImGui::Text("Select Data Group"); + // default primitive data group + // ######### SELECT PRIMITIVE ############// + // if (ImGui::Button("Refresh")) { + // updatePrimitiveTypes(); + // updateDataGroups(); + // } + // ImGui::SameLine(); + ImGui::SetNextItemWidth(150); + if (ImGui::BeginCombo("##combo_primitive", current_primitive.c_str())) { + for (int m = 0; m < primitive_names.size(); m++) { + bool is_primitive_selected = (current_primitive == primitive_names[m]); + if (ImGui::Selectable(primitive_names[m].c_str(), is_primitive_selected)) + current_primitive = primitive_names[m]; + if (is_primitive_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + ImGui::Text("Select Primitive Type"); + if (current_data_group == "All") { + // REFLECTIVITY + ImGui::Text("Reflectivity:"); + std::string toggle_display_reflectivity = "Manual Entry"; + bool reflectivity_continuous = primitive_continuous[current_primitive][0]; + toggle_button("##reflectivity_toggle", &reflectivity_continuous); + if (reflectivity_continuous != primitive_continuous[current_primitive][0]) { + if (current_primitive == "All") { + for (auto &prim_values: primitive_continuous) { + primitive_continuous[prim_values.first][0] = reflectivity_continuous; + } + } + primitive_continuous[current_primitive][0] = reflectivity_continuous; + } + if (primitive_continuous[current_primitive][0]) { + toggle_display_reflectivity = "File Entry"; + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(250); + if (!primitive_continuous[current_primitive][0]) { + ImGui::Text("Select band:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + if (ImGui::BeginCombo("##combo_band_reflectivity", current_band_reflectivity.c_str())) { + for (int n = 0; n < bandlabels.size(); n++) { + bool is_band_selected = (current_band_reflectivity == bandlabels[n]); + if (ImGui::Selectable(bandlabels[n].c_str(), is_band_selected)) + current_band_reflectivity = bandlabels[n]; + if (is_band_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Enter value:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80); + if (current_primitive == "All") { + float prev_reflectivity = reflectivity; + ImGui::InputFloat("##reflectivity_all", &reflectivity); + if (reflectivity != prev_reflectivity) { + for (auto &prim_values: primitive_values[current_band_reflectivity]) { + primitive_values[current_band_reflectivity][prim_values.first][0] = reflectivity; + } + } + } else { + ImGui::InputFloat("##reflectivity", &primitive_values[current_band_reflectivity][current_primitive][0]); + } + } else { + std::string reflectivity_prev = primitive_spectra[current_primitive][0]; + if (ImGui::BeginCombo("##reflectivity_combo_all", reflectivity_prev.c_str())) { + for (auto &spectra: possible_spectra) { + bool is_spectra_selected = (primitive_spectra[current_primitive][0] == spectra); + if (ImGui::Selectable(spectra.c_str(), is_spectra_selected)) + primitive_spectra[current_primitive][0] = spectra; + if (is_spectra_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + if (current_primitive == "All" && reflectivity_prev != primitive_spectra[current_primitive][0]) { + for (auto &prim_spectrum: primitive_spectra) { + primitive_spectra[prim_spectrum.first][0] = primitive_spectra[current_primitive][0]; + } + } + } + ImGui::SameLine(); + ImGui::Text("%s", toggle_display_reflectivity.c_str()); + // TRANSMISSIVITY + ImGui::Text("Transmissivity:"); + std::string toggle_display_transmissivity = "Manual Entry"; + bool transmissivity_continuous = primitive_continuous[current_primitive][1]; + toggle_button("##transmissivity_toggle", &transmissivity_continuous); + if (transmissivity_continuous != primitive_continuous[current_primitive][1]) { + if (current_primitive == "All") { + for (auto &prim_values: primitive_continuous) { + primitive_continuous[prim_values.first][1] = transmissivity_continuous; + } + } + primitive_continuous[current_primitive][1] = transmissivity_continuous; + } + if (primitive_continuous[current_primitive][1]) { + toggle_display_transmissivity = "File Entry"; + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(250); + if (!primitive_continuous[current_primitive][1]) { + ImGui::Text("Select band:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + if (ImGui::BeginCombo("##combo_band_transmissivity", current_band_transmissivity.c_str())) { + for (int n = 0; n < bandlabels.size(); n++) { + bool is_band_selected = (current_band_transmissivity == bandlabels[n]); + if (ImGui::Selectable(bandlabels[n].c_str(), is_band_selected)) + current_band_transmissivity = bandlabels[n]; + if (is_band_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Enter value:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80); + if (current_primitive == "All") { + float prev_transmissivity = transmissivity; + ImGui::InputFloat("##transmissivity_all", &transmissivity); + if (transmissivity != prev_transmissivity) { + for (auto &prim_values: primitive_values[current_band_transmissivity]) { + primitive_values[current_band_transmissivity][prim_values.first][1] = transmissivity; + } + } + } else { + ImGui::InputFloat("##transmissivity", &primitive_values[current_band_transmissivity][current_primitive][1]); + } + } else { + std::string transmissivity_prev = primitive_spectra[current_primitive][1]; + if (ImGui::BeginCombo("##transmissivity_combo", transmissivity_prev.c_str())) { + for (auto &spectra: possible_spectra) { + bool is_spectra_selected = (primitive_spectra[current_primitive][1] == spectra); + if (ImGui::Selectable(spectra.c_str(), is_spectra_selected)) + primitive_spectra[current_primitive][1] = spectra; + if (is_spectra_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + if (current_primitive == "All" && transmissivity_prev != primitive_spectra[current_primitive][1]) { + for (auto &prim_spectrum: primitive_spectra) { + primitive_spectra[prim_spectrum.first][1] = primitive_spectra[current_primitive][1]; + } + } + } + ImGui::SameLine(); + ImGui::Text("%s", toggle_display_transmissivity.c_str()); + // EMISSIVITY + ImGui::Text("Emissivity:"); + // ImGui::SetNextItemWidth(250); + // ImGui::Text(""); + ImGui::Dummy(ImVec2(35.f, 0.f)); + ImGui::SameLine(); + ImGui::Text("Select band:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + if (ImGui::BeginCombo("##combo_band_emissivity", current_band_emissivity.c_str())) { + for (std::string band: bandlabels_set_emissivity) { + bool is_band_selected = (current_band_emissivity == band); + if (ImGui::Selectable(band.c_str(), is_band_selected)) + current_band_emissivity = band; + if (is_band_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Enter value:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80); + if (current_primitive == "All") { + float prev_emissivity = emissivity; + ImGui::InputFloat("##emissivity_all", &emissivity); + if (emissivity != prev_emissivity) { + for (auto &prim_values: primitive_values[current_band_emissivity]) { + primitive_values[current_band_emissivity][prim_values.first][2] = emissivity; + } + } + } else { + ImGui::InputFloat("##emissivity", &primitive_values[current_band_emissivity][current_primitive][2]); + } + ImGui::SameLine(); + ImGui::Text("Manual Entry"); + } else { // specific data group + // REFLECTIVITY + ImGui::Text("Reflectivity:"); + std::string toggle_display_reflectivity = "Manual Entry"; + bool reflectivity_continuous = primitive_continuous_dict[current_data_group][current_primitive][0]; + toggle_button("##reflectivity_toggle", &reflectivity_continuous); + if (reflectivity_continuous != primitive_continuous_dict[current_data_group][current_primitive][0]) { + if (current_primitive == "All") { + for (auto &prim_values: primitive_continuous_dict[current_data_group]) { + primitive_continuous_dict[current_data_group][prim_values.first][0] = reflectivity_continuous; + } + } + primitive_continuous_dict[current_data_group][current_primitive][0] = reflectivity_continuous; + } + if (primitive_continuous_dict[current_data_group][current_primitive][0]) { + toggle_display_reflectivity = "File Entry"; + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(250); + if (!primitive_continuous_dict[current_data_group][current_primitive][0]) { + ImGui::Text("Select band:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + if (ImGui::BeginCombo("##combo_band_reflectivity", current_band_reflectivity.c_str())) { + for (int n = 0; n < bandlabels.size(); n++) { + bool is_band_selected = (current_band_reflectivity == bandlabels[n]); + if (ImGui::Selectable(bandlabels[n].c_str(), is_band_selected)) + current_band_reflectivity = bandlabels[n]; + if (is_band_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Enter value:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80); + if (current_primitive == "All") { + float prev_reflectivity = reflectivity; + ImGui::InputFloat("##reflectivity_all", &reflectivity); + if (reflectivity != prev_reflectivity) { + for (auto &prim_values: primitive_values_dict[current_data_group][current_band_reflectivity]) { + primitive_values_dict[current_data_group][current_band_reflectivity][prim_values.first][0] = reflectivity; + } + } + } else { + ImGui::InputFloat("##reflectivity", &primitive_values_dict[current_data_group][current_band_reflectivity][current_primitive][0]); + } + } else { + std::string reflectivity_prev = primitive_spectra_dict[current_data_group][current_primitive][0]; + if (ImGui::BeginCombo("##reflectivity_combo", reflectivity_prev.c_str())) { + for (auto &spectra: possible_spectra) { + bool is_spectra_selected = (primitive_spectra_dict[current_data_group][current_primitive][0] == spectra); + if (ImGui::Selectable(spectra.c_str(), is_spectra_selected)) + primitive_spectra_dict[current_data_group][current_primitive][0] = spectra; + if (is_spectra_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + if (current_primitive == "All" && reflectivity_prev != primitive_spectra_dict[current_data_group][current_primitive][0]) { + for (auto &prim_spectrum: primitive_spectra_dict[current_data_group]) { + primitive_spectra_dict[current_data_group][prim_spectrum.first][0] = primitive_spectra_dict[current_data_group][current_primitive][0]; + } + } + } + ImGui::SameLine(); + ImGui::TextUnformatted("%s", toggle_display_reflectivity.c_str()); + // TRANSMISSIVITY + ImGui::Text("Transmissivity:"); + std::string toggle_display_transmissivity = "Manual Entry"; + bool transmissivity_continuous = primitive_continuous_dict[current_data_group][current_primitive][1]; + toggle_button("##transmissivity_toggle", &transmissivity_continuous); + if (transmissivity_continuous != primitive_continuous_dict[current_data_group][current_primitive][1]) { + if (current_primitive == "All") { + for (auto &prim_values: primitive_continuous_dict[current_data_group]) { + primitive_continuous_dict[current_data_group][prim_values.first][1] = transmissivity_continuous; + } + } + primitive_continuous_dict[current_data_group][current_primitive][1] = transmissivity_continuous; + } + if (primitive_continuous_dict[current_data_group][current_primitive][1]) { + toggle_display_transmissivity = "File Entry"; + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(250); + if (!primitive_continuous_dict[current_data_group][current_primitive][1]) { + ImGui::Text("Select band:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + if (ImGui::BeginCombo("##combo_band_transmissivity", current_band_transmissivity.c_str())) { + for (int n = 0; n < bandlabels.size(); n++) { + bool is_band_selected = (current_band_transmissivity == bandlabels[n]); + if (ImGui::Selectable(bandlabels[n].c_str(), is_band_selected)) + current_band_transmissivity = bandlabels[n]; + if (is_band_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Enter value:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80); + if (current_primitive == "All") { + float prev_transmissivity = transmissivity; + ImGui::InputFloat("##transmissivity_all", &transmissivity); + if (transmissivity != prev_transmissivity) { + for (auto &prim_values: primitive_values_dict[current_data_group][current_band_transmissivity]) { + primitive_values_dict[current_data_group][current_band_transmissivity][prim_values.first][1] = transmissivity; + } + } + } else { + ImGui::InputFloat("##transmissivity", &primitive_values_dict[current_data_group][current_band_transmissivity][current_primitive][1]); + } + } else { + std::string transmissivity_prev = primitive_spectra_dict[current_data_group][current_primitive][1]; + if (ImGui::BeginCombo("##transmissivity_combo", transmissivity_prev.c_str())) { + for (auto &spectra: possible_spectra) { + bool is_spectra_selected = (primitive_spectra_dict[current_data_group][current_primitive][1] == spectra); + if (ImGui::Selectable(spectra.c_str(), is_spectra_selected)) + primitive_spectra_dict[current_data_group][current_primitive][1] = spectra; + if (is_spectra_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + if (current_primitive == "All" && transmissivity_prev != primitive_spectra_dict[current_data_group][current_primitive][1]) { + for (auto &prim_spectrum: primitive_spectra_dict[current_data_group]) { + primitive_spectra_dict[current_data_group][prim_spectrum.first][1] = primitive_spectra_dict[current_data_group][current_primitive][1]; + } + } + } + ImGui::SameLine(); + ImGui::TextUnformatted("%s", toggle_display_transmissivity.c_str()); + // EMISSIVITY + ImGui::Text("Emissivity:"); + // ImGui::SetNextItemWidth(250); + // ImGui::Text(""); + ImGui::Dummy(ImVec2(35.f, 0.f)); + ImGui::SameLine(); + ImGui::Text("Select band:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + if (ImGui::BeginCombo("##combo_band_emissivity", current_band_emissivity.c_str())) { + for (std::string band: bandlabels_set_emissivity) { + bool is_band_selected = (current_band_emissivity == band); + if (ImGui::Selectable(band.c_str(), is_band_selected)) + current_band_emissivity = band; + if (is_band_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Enter value:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80); + if (current_primitive == "All") { + float prev_emissivity = emissivity; + ImGui::InputFloat("##emissivity_all", &emissivity); + if (emissivity != prev_emissivity) { + for (auto &prim_values: primitive_values_dict[current_data_group][current_band_emissivity]) { + primitive_values_dict[current_data_group][current_band_emissivity][prim_values.first][2] = emissivity; + } + } + } else { + ImGui::InputFloat("##emissivity", &primitive_values_dict[current_data_group][current_band_emissivity][current_primitive][2]); + } + ImGui::SameLine(); + ImGui::Text("Manual Entry"); + } + ImGui::NewLine(); + if (ImGui::Button("Run Radiation")) { + const char *font_name = "LCD"; + visualizer->addTextboxByCenter("LOADING...", vec3(.5, .5, 0), make_SphericalCoord(0, 0), RGB::red, 40, font_name, Visualizer::COORDINATES_WINDOW_NORMALIZED); + visualizer->plotUpdate(); + runRadiation(); + visualizer->plotUpdate(); + } +#endif +} + + +void ProjectBuilder::rigTab() { +#if defined(ENABLE_HELIOS_VISUALIZER) && defined(ENABLE_RADIATION_MODEL) + std::string current_cam_position = "0"; + if (ImGui::BeginCombo("##rig_combo", current_rig.c_str())) { + for (auto rig_label: rig_labels_set) { + bool is_rig_selected = (current_rig == rig_label); + if (ImGui::Selectable(rig_label.c_str(), is_rig_selected)) + current_rig = rig_label; + current_cam_position = "0"; + if (is_rig_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + if (ImGui::Button("Add Rig")) { + std::string default_rig_label = "rig"; + std::string new_rig_label = "rig_0"; + int count = 0; + while (rig_dict.find(new_rig_label) != rig_dict.end()) { + count++; + new_rig_label = default_rig_label + "_" + std::to_string(count); + } + addRig(new_rig_label); + } + if (!current_rig.empty()) { + // ##### UPDATE RIG ######// + // if (ImGui::Button("Update Rig")){ + // updateRigs(); + // } + // ImGui::SameLine(); + if (ImGui::Button("Delete Rig")) { + deleteRig(current_rig); + } + // ##### RIG NAME ######// + ImGui::SetNextItemWidth(100); + std::string prev_rig_name = rig_labels[rig_dict[current_rig]]; + ImGui::InputText("##rig_name", &rig_labels[rig_dict[current_rig]]); + if (rig_labels[rig_dict[current_rig]] != prev_rig_name && rig_dict.find(rig_labels[rig_dict[current_rig]]) == rig_dict.end() && !rig_labels[rig_dict[current_rig]].empty()) { + int temp = rig_dict[current_rig]; + current_rig = rig_labels[rig_dict[current_rig]]; + std::map::iterator current_rig_iter = rig_dict.find(prev_rig_name); + if (current_rig_iter != rig_dict.end()) { + rig_dict.erase(current_rig_iter); + } + rig_dict[current_rig] = temp; + rig_labels_set.erase(prev_rig_name); + rig_labels_set.insert(rig_labels[rig_dict[current_rig]]); + + std::string new_name = rig_labels[rig_dict[current_rig]]; + rig renamed_rig = rig_dict_.at(prev_rig_name); + rig_dict_.erase(prev_rig_name); + rig_dict_.insert({new_name, renamed_rig}); + } else { + rig_labels[rig_dict[current_rig]] = prev_rig_name; + } + ImGui::SameLine(); + ImGui::Text("Rig Name"); + // ####### WRITE DEPTH ####### // + ImGui::Text("Write:"); + ImGui::SameLine(); + bool write_depth_ = write_depth[rig_dict[current_rig]]; + ImGui::Checkbox("Depth Images", &write_depth_); + write_depth[rig_dict[current_rig]] = write_depth_; + ImGui::SameLine(); + bool write_norm_depth_ = write_norm_depth[rig_dict[current_rig]]; + ImGui::Checkbox("Norm Depth Images", &write_norm_depth_); + write_norm_depth[rig_dict[current_rig]] = write_norm_depth_; + ImGui::SameLine(); + bool write_segmentation_ = write_segmentation_mask[rig_dict[current_rig]]; + ImGui::Checkbox("Segmentation Masks", &write_segmentation_); + write_segmentation_mask[rig_dict[current_rig]] = write_segmentation_; + // ####### BOUNDING BOXES ####### // + if (ImGui::BeginPopup("multi_select_popup")) { + for (auto &box_pair: bounding_boxes) { + ImGui::Selectable(box_pair.first.c_str(), &box_pair.second, ImGuiSelectableFlags_DontClosePopups); + } + ImGui::EndPopup(); + } + if (ImGui::Button("Select Labeled Objects")) { + ImGui::OpenPopup("multi_select_popup"); + } + ImGui::SameLine(); + if (ImGui::Button("Refresh List")) { + refreshBoundingBoxObjectList(); + } + // ImGui::OpenPopupOnItemClick(("rig_position_noise_" + std::to_string(rig_dict[current_rig])).c_str(), ImGuiPopupFlags_MouseButtonLeft); + // Display selected items + ImGui::Text("Objects:"); + int idx = 0; + for (auto &box_pair: bounding_boxes) { + if (box_pair.second) { + ImGui::SameLine(), ImGui::Text("%i. %s", idx, box_pair.first.c_str()); + idx++; + } + } + // ####### RIG COLOR ####### // + float col[3]; + col[0] = rig_colors[rig_dict[current_rig]].r; + col[1] = rig_colors[rig_dict[current_rig]].g; + col[2] = rig_colors[rig_dict[current_rig]].b; + ImGui::ColorEdit3("##rig_color_edit", col); + updateColor(current_rig, "rig", col); + ImGui::SameLine(); + ImGui::Text("Rig Color"); + // ####### CAMERA LABEL ####### // + /* SINGLE CAMERA VERSION + ImGui::SetNextItemWidth(60); + // ImGui::InputText("Camera Label", &camera_labels[rig_dict[(std::string) current_rig]]); + if (ImGui::BeginCombo("##cam_label_combo", camera_labels[rig_dict[(std::string) current_rig]].c_str())){ + for (int n = 0; n < camera_names.size(); n++){ + bool is_cam_label_selected = (camera_labels[rig_dict[(std::string) current_rig]] == camera_names[n]); // You can store your selection however you want, outside or inside your objects + if (ImGui::Selectable(camera_names[n].c_str(), is_cam_label_selected)){ + camera_labels[rig_dict[(std::string) current_rig]] = camera_names[n]; + } + if (is_cam_label_selected) + ImGui::SetItemDefaultFocus(); // You may set the initial focus when opening the combo (scrolling + for keyboard navigation support) + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Camera Label"); + ImGui::EndTabItem(); + */ + // ####### CAMERA CHECKBOX ####### // + ImGui::Text("Cameras:"); + for (int i = 0; i < camera_names.size(); i++) { + std::string &camera_name = camera_names[i]; + + ImGui::SetNextItemWidth(60); + + std::set curr_set = rig_camera_labels[rig_dict[current_rig]]; + // if (i % 3 != 0){ + // ImGui::SameLine(); + // } + bool isCameraSelected = curr_set.find(camera_name) != curr_set.end(); + ImGui::PushID(i); + if (ImGui::Checkbox(camera_name.c_str(), &isCameraSelected)) { + if (isCameraSelected) { + rig_camera_labels[rig_dict[current_rig]].insert(camera_name); + } else { + rig_camera_labels[rig_dict[current_rig]].erase(camera_name); + } + } + ImGui::PopID(); } - } -#endif -} + // ####### LIGHT CHECKBOX ####### // + ImGui::Text("Lights:"); + for (int i = 0; i < light_names.size(); i++) { + std::string &light_name = light_names[i]; -void ProjectBuilder::xmlGetValues(std::string xml_path) { - xml_input_file = xml_path; - if (!open_xml_file(xml_input_file, xmldoc, xml_error_string)) { - helios_runtime_error(xml_error_string); - } - xmlGetValues(); -} + ImGui::SetNextItemWidth(60); -void ProjectBuilder::objectTab(std::string curr_obj_name, int id) { -#ifdef ENABLE_HELIOS_VISUALIZER - if (ImGui::Button("Update Object")) { - updateObject(curr_obj_name); - refreshVisualization(); - } - ImGui::SameLine(); - if (ImGui::Button("Delete Object")) { - deleteObject(curr_obj_name); - } - ImGui::SetNextItemWidth(100); - std::string prev_obj_name = objects_dict[curr_obj_name].name; - ImGui::InputText(("##obj_name_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].name); - if (objects_dict[curr_obj_name].name != prev_obj_name && objects_dict.find(curr_obj_name) == objects_dict.end() && !objects_dict[curr_obj_name].name.empty()) { - object temp_obj = objects_dict[curr_obj_name]; - curr_obj_name = objects_dict[curr_obj_name].name; - std::map::iterator delete_obj_iter = objects_dict.find(prev_obj_name); - if (delete_obj_iter != objects_dict.end()) { - objects_dict.erase(delete_obj_iter); + std::set curr_rig_light = rig_light_labels[rig_dict[current_rig]]; + bool isLightSelected = curr_rig_light.find(light_name) != curr_rig_light.end(); + ImGui::PushID(i); + if (ImGui::Checkbox(light_name.c_str(), &isLightSelected)) { + if (isLightSelected) { + rig_light_labels[rig_dict[current_rig]].insert(light_name); + } else { + rig_light_labels[rig_dict[current_rig]].erase(light_name); + } + } + ImGui::PopID(); + } + // ####### ADD KEYPOINT ####### // + std::stringstream cam_pos_value; + cam_pos_value << current_cam_position.c_str(); + int current_cam_position_; + cam_pos_value >> current_cam_position_; + current_keypoint = std::to_string(keypoint_frames[rig_dict[current_rig]][current_cam_position_]); + std::string modified_current_keypoint = std::to_string(keypoint_frames[rig_dict[current_rig]][current_cam_position_] + 1); // 1-indexed value + if (ImGui::BeginCombo("##cam_combo", modified_current_keypoint.c_str())) { + for (int n = 1; n <= camera_position_vec[rig_dict[current_rig]].size(); n++) { + std::string select_cam_position = std::to_string(n - 1); + std::string selected_keypoint = std::to_string(keypoint_frames[rig_dict[current_rig]][n - 1]); + bool is_pos_selected = (current_cam_position == select_cam_position); + std::string modified_selected_keypoint = std::to_string(keypoint_frames[rig_dict[current_rig]][n - 1] + 1); // 1-indexed value + if (ImGui::Selectable(modified_selected_keypoint.c_str(), is_pos_selected)) { + current_cam_position = std::to_string(n - 1); + } + if (is_pos_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); } + cam_pos_value << current_cam_position.c_str(); + cam_pos_value >> current_cam_position_; + ImGui::SameLine(); + if (ImGui::Button("Add Keypoint")) { + camera_position_vec[rig_dict[current_rig]].push_back(camera_position_vec[rig_dict[current_rig]][current_cam_position_]); + camera_lookat_vec[rig_dict[current_rig]].push_back(camera_lookat_vec[rig_dict[current_rig]][current_cam_position_]); + keypoint_frames[rig_dict[current_rig]].push_back(keypoint_frames[rig_dict[current_rig]].back() + 1); + is_dirty = true; + } + // ####### KEYPOINT FRAME ####### // + ImGui::SetNextItemWidth(80); + int modified_keypoint_frame = keypoint_frames[rig_dict[current_rig]][current_cam_position_] + 1; // 1-indexed value + ImGui::InputInt("Keypoint Frame", &modified_keypoint_frame); + if (modified_keypoint_frame != keypoint_frames[rig_dict[current_rig]][current_cam_position_] + 1) { + keypoint_frames[rig_dict[current_rig]][current_cam_position_] = modified_keypoint_frame - 1; + } + // ####### CAMERA POSITION ####### // + vec3 prev_rig_position_ = camera_position_vec[rig_dict[current_rig]][current_cam_position_]; + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##camera_position_x", &camera_position_vec[rig_dict[current_rig]][current_cam_position_].x); + randomizePopup("camera_position_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_position_vec[rig_dict[current_rig]][current_cam_position_].x)); + randomizerParams("camera_position_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); + ImGui::OpenPopupOnItemClick(("randomize_camera_position_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##camera_position_y", &camera_position_vec[rig_dict[current_rig]][current_cam_position_].y); + randomizePopup("camera_position_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_position_vec[rig_dict[current_rig]][current_cam_position_].y)); + randomizerParams("camera_position_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); + ImGui::OpenPopupOnItemClick(("randomize_camera_position_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##camera_position_z", &camera_position_vec[rig_dict[current_rig]][current_cam_position_].z); + randomizePopup("camera_position_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_position_vec[rig_dict[current_rig]][current_cam_position_].z)); + randomizerParams("camera_position_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); + ImGui::OpenPopupOnItemClick(("randomize_camera_position_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Rig Position"); + ImGui::SameLine(); + ImGui::Button("Add Noise###position"); + noisePopup("rig_position_noise_" + std::to_string(rig_dict[current_rig]), rig_lookat_noise[rig_dict[current_rig]]); + ImGui::OpenPopupOnItemClick(("rig_position_noise_" + std::to_string(rig_dict[current_rig])).c_str(), ImGuiPopupFlags_MouseButtonLeft); + // ####### CAMERA LOOKAT ####### // + vec3 prev_rig_lookat_ = camera_lookat_vec[rig_dict[current_rig]][current_cam_position_]; + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##camera_lookat_x", &camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].x); + randomizePopup("camera_lookat_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].x)); + randomizerParams("camera_lookat_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); + ImGui::OpenPopupOnItemClick(("randomize_camera_lookat_x_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##camera_lookat_y", &camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].y); + randomizePopup("camera_lookat_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].y)); + randomizerParams("camera_lookat_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); + ImGui::OpenPopupOnItemClick(("randomize_camera_lookat_y_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(60); + ImGui::InputFloat("##camera_lookat_z", &camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].z); + randomizePopup("camera_lookat_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_), createTaggedPtr(&camera_lookat_vec[rig_dict[current_rig]][current_cam_position_].z)); + randomizerParams("camera_lookat_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)); + ImGui::OpenPopupOnItemClick(("randomize_camera_lookat_z_" + std::to_string(rig_dict[current_rig]) + std::to_string(current_cam_position_)).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Rig Lookat"); + ImGui::SameLine(); + ImGui::Button("Add Noise###lookat"); + noisePopup("rig_lookat_noise_" + std::to_string(rig_dict[current_rig]), rig_lookat_noise[rig_dict[current_rig]]); + ImGui::OpenPopupOnItemClick(("rig_lookat_noise_" + std::to_string(rig_dict[current_rig])).c_str(), ImGuiPopupFlags_MouseButtonLeft); + // ####### NUMBER OF IMAGES ####### // + ImGui::SetNextItemWidth(80); + ImGui::InputInt("Total Number of Frames", &num_images_vec[rig_dict[current_rig]]); + num_images_vec[rig_dict[current_rig]] = std::max(num_images_vec[rig_dict[current_rig]], *std::max_element(keypoint_frames[rig_dict[current_rig]].begin(), keypoint_frames[rig_dict[(std::string) current_rig]].end()) + 1); - objects_dict[objects_dict[curr_obj_name].name] = temp_obj; + if (prev_rig_position_ != camera_position_vec[rig_dict[current_rig]][current_cam_position_] || prev_rig_lookat_ != camera_lookat_vec[rig_dict[current_rig]][current_cam_position_]) { + updateRigs(); + } - obj_names_set.erase(prev_obj_name); - obj_names_set.insert(objects_dict[curr_obj_name].name); - } else { - objects_dict[curr_obj_name].name = prev_obj_name; + ImGui::NewLine(); + if (ImGui::Button("Record Images")) { + if (band_group_names.empty()) { + std::cout << "At least 1 band group (a group of 1 or 3 bands) must be defined to record images." << std::endl; + } else { + // Update reflectivity, transmissivity, & emissivity for each band / primitive_type + const char *font_name = "LCD"; + visualizer->addTextboxByCenter("LOADING...", vec3(.5, .5, 0), make_SphericalCoord(0, 0), RGB::red, 40, font_name, Visualizer::COORDINATES_WINDOW_NORMALIZED); + visualizer->plotUpdate(); + updatePrimitiveTypes(); + updateSpectra(); + updateCameras(); + try { + record(); + } catch (const std::runtime_error &e) { + std::cerr << "Record failed due to exception: " << e.what() << std::endl; + visualizer->plotUpdate(); + } + } + } } - ImGui::SameLine(); - ImGui::Text("Object Name"); - // ####### OBJECT SCALE ####### // - ImGui::SetNextItemWidth(60); - ImGui::InputFloat(("##obj_scale_x_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].scale.x); - randomizePopup("obj_scale_x_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].scale.x, &objects_dict[curr_obj_name].is_dirty)); - randomizerParams("obj_scale_x_" + std::to_string(objects_dict[curr_obj_name].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_scale_x_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat(("##obj_scale_y_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].scale.y); - randomizePopup("obj_scale_y_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].scale.y, &objects_dict[curr_obj_name].is_dirty)); - randomizerParams("obj_scale_y_" + std::to_string(objects_dict[curr_obj_name].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_scale_y_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat(("##obj_scale_z_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].scale.z); - randomizePopup("obj_scale_z_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].scale.z, &objects_dict[curr_obj_name].is_dirty)); - randomizerParams("obj_scale_z_" + std::to_string(objects_dict[curr_obj_name].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_scale_z_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Object Scale"); - // ####### OBJECT POSITION ####### // - ImGui::SetNextItemWidth(60); - ImGui::InputFloat(("##obj_position_x_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].position.x); - randomizePopup("obj_position_x_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].position.x, &objects_dict[curr_obj_name].is_dirty)); - randomizerParams("obj_position_x_" + std::to_string(objects_dict[curr_obj_name].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_position_x_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat(("##obj_position_y_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].position.y); - randomizePopup("obj_position_y_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].position.y, &objects_dict[curr_obj_name].is_dirty)); - randomizerParams("obj_position_y_" + std::to_string(objects_dict[curr_obj_name].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_position_y_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat(("##obj_position_z_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].position.z); - randomizePopup("obj_position_z_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].position.z, &objects_dict[curr_obj_name].is_dirty)); - randomizerParams("obj_position_z_" + std::to_string(objects_dict[curr_obj_name].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_position_z_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Object Position"); - // ####### OBJECT ORIENTATION ####### // - ImGui::SetNextItemWidth(60); - ImGui::InputFloat(("##obj_orientation_x_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].orientation.x); - randomizePopup("obj_orientation_x_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].orientation.x, &objects_dict[curr_obj_name].is_dirty)); - randomizerParams("obj_orientation_x_" + std::to_string(objects_dict[curr_obj_name].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_x_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat(("##obj_orientation_y_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].orientation.y); - randomizePopup("obj_orientation_y_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].orientation.y, &objects_dict[curr_obj_name].is_dirty)); - randomizerParams("obj_orientation_y_" + std::to_string(objects_dict[curr_obj_name].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_y_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::SetNextItemWidth(60); - ImGui::InputFloat(("##obj_orientation_z_" + std::to_string(id)).c_str(), &objects_dict[curr_obj_name].orientation.z); - randomizePopup("obj_orientation_z_" + std::to_string(objects_dict[curr_obj_name].index), createTaggedPtr(&objects_dict[curr_obj_name].orientation.z, &objects_dict[curr_obj_name].is_dirty)); - randomizerParams("obj_orientation_z_" + std::to_string(objects_dict[curr_obj_name].index)); - ImGui::OpenPopupOnItemClick(("randomize_obj_orientation_z_" + std::to_string(objects_dict[curr_obj_name].index)).c_str(), ImGuiPopupFlags_MouseButtonRight); - ImGui::SameLine(); - ImGui::Text("Object Orientation"); +#endif } + void ProjectBuilder::rigTab(std::string curr_rig_name, int id) { +#if defined(ENABLE_HELIOS_VISUALIZER) && defined(ENABLE_RADIATION_MODEL) ImGui::SetNextItemWidth(100); std::string prev_rig_name = rig_labels[rig_dict[curr_rig_name]]; ImGui::InputText("##rig_name", &rig_labels[rig_dict[curr_rig_name]]); @@ -5064,8 +5180,191 @@ void ProjectBuilder::rigTab(std::string curr_rig_name, int id) { #endif } +void ProjectBuilder::lightTab() { +#if defined(ENABLE_HELIOS_VISUALIZER) && defined(ENABLE_RADIATION_MODEL) + // LOAD XML LIBRARY FILE + ImGui::SetNextItemWidth(60); + if (ImGui::Button("Load XML Library File")) { + std::string new_xml_library_file = file_dialog(); + if (!new_xml_library_file.empty() && std::filesystem::exists(new_xml_library_file)) { + if (light_xml_library_files.find(new_xml_library_file) == light_xml_library_files.end()) { + light_xml_library_files.insert(new_xml_library_file); + std::vector current_light_file = get_xml_node_values(new_xml_library_file, "label", "globaldata_vec2"); + possible_light_spectra.insert(possible_light_spectra.end(), current_light_file.begin(), current_light_file.end()); + } + context->loadXML(new_xml_library_file.c_str()); + } + } + if (ImGui::BeginCombo("##light_combo", current_light.c_str())) { + for (int n = 0; n < light_names.size(); n++) { + bool is_light_selected = (current_light == light_names[n]); + if (ImGui::Selectable(light_names[n].c_str(), is_light_selected)) + current_light = light_names[n]; + if (is_light_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + if (ImGui::Button("Add Light")) { + std::string default_light_name = "light"; + std::string new_light_name = "light_0"; + int count = 0; + while (light_dict.find(new_light_name) != light_dict.end()) { + count++; + new_light_name = default_light_name + "_" + std::to_string(count); + } + light_dict.insert({new_light_name, scast(light_names.size())}); + light_spectra.push_back(light_spectra[light_dict[current_light]]); + light_types.push_back(light_types[light_dict[current_light]]); + light_direction_vec.push_back(light_direction_vec[light_dict[current_light]]); + light_direction_sph_vec.push_back(light_direction_sph_vec[light_dict[current_light]]); + light_rotation_vec.push_back(light_rotation_vec[light_dict[current_light]]); + light_size_vec.push_back(light_size_vec[light_dict[current_light]]); + light_radius_vec.push_back(light_radius_vec[light_dict[current_light]]); + light_names.push_back(new_light_name); + light_flux_vec.push_back(light_flux_vec[light_dict[current_light]]); + std::string parent = "light"; + pugi::xml_node light_block = helios.child(parent.c_str()); + pugi::xml_node new_light_node = helios.append_copy(light_block); + std::string name = "label"; + pugi::xml_attribute node_label = new_light_node.attribute(name.c_str()); + node_label.set_value(new_light_name.c_str()); + current_light = new_light_name; + } + ImGui::SetNextItemWidth(100); + std::string prev_light_name = light_names[light_dict[current_light]]; + ImGui::InputText("##light_name", &light_names[light_dict[current_light]]); + if (light_names[light_dict[current_light]] != prev_light_name) { + int temp = light_dict[current_light]; + current_light = light_names[light_dict[current_light]]; + std::map::iterator current_light_iter = light_dict.find(prev_light_name); + if (current_light_iter != light_dict.end()) { + light_dict.erase(current_light_iter); + } + light_dict[current_light] = temp; + } + ImGui::SameLine(); + ImGui::Text("Light Label"); + // ####### LIGHT SPECTRA ####### // + std::string prev_light_spectra = light_spectra[light_dict[current_light]]; + if (ImGui::BeginCombo("##light_spectra_combo", light_spectra[light_dict[current_light]].c_str())) { + for (int n = 0; n < possible_light_spectra.size(); n++) { + bool is_light_spectra_selected = (light_spectra[light_dict[current_light]] == possible_light_spectra[n]); + if (ImGui::Selectable(possible_light_spectra[n].c_str(), is_light_spectra_selected)) + light_spectra[light_dict[current_light]] = possible_light_spectra[n]; + if (is_light_spectra_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Light Spectrum"); + // ####### LIGHT TYPE ############ // + if (ImGui::BeginCombo("##light_type_combo", light_types[light_dict[current_light]].c_str())) { + for (int n = 0; n < all_light_types.size(); n++) { + bool is_type_selected = (light_types[light_dict[current_light]] == all_light_types[n]); + if (ImGui::Selectable(all_light_types[n].c_str(), is_type_selected)) { + light_types[light_dict[current_light]] = all_light_types[n]; + } + if (is_type_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::Text("Light Type"); + // collimated -> direction + // disk -> position, radius, rotation + // sphere -> position, radius + // sunsphere -> direction + // rectangle -> position, size, rotation + // ####### LIGHT DIRECTION ####### // + if (light_types[light_dict[(std::string) current_light]] == "collimated" || light_types[light_dict[(std::string) current_light]] == "sunsphere") { + ImGui::SetNextItemWidth(90); + ImGui::InputFloat("##light_direction_x", &light_direction_vec[light_dict[current_light]].x); + randomizePopup("light_direction_x_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_direction_vec[light_dict[current_light]].x)); + randomizerParams("light_direction_x_" + std::to_string(light_dict[current_light])); + ImGui::OpenPopupOnItemClick(("light_direction_x_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(90); + ImGui::InputFloat("##light_direction_y", &light_direction_vec[light_dict[current_light]].y); + randomizePopup("light_direction_y_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_direction_vec[light_dict[current_light]].y)); + randomizerParams("light_direction_y_" + std::to_string(light_dict[current_light])); + ImGui::OpenPopupOnItemClick(("light_direction_y_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(90); + ImGui::InputFloat("##light_direction_z", &light_direction_vec[light_dict[current_light]].z); + randomizePopup("light_direction_z_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_direction_vec[light_dict[current_light]].z)); + randomizerParams("light_direction_z_" + std::to_string(light_dict[current_light])); + ImGui::OpenPopupOnItemClick(("light_direction_z_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Light Direction"); + } + // ####### LIGHT SOURCE FLUX ####### // + ImGui::SetNextItemWidth(90); + ImGui::InputFloat("##source_flux", &light_flux_vec[light_dict[current_light]]); + randomizePopup("source_flux_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_flux_vec[light_dict[current_light]])); + randomizerParams("source_flux_" + std::to_string(light_dict[current_light])); + ImGui::OpenPopupOnItemClick(("source_flux_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Source Flux"); + // radiation->setSourceFlux(light_UUID, band, flux_value); + // ####### LIGHT ROTATION ####### // + if (light_types[light_dict[current_light]] == "disk" || light_types[light_dict[current_light]] == "rectangle") { + ImGui::SetNextItemWidth(90); + ImGui::InputFloat("##light_rotation_x", &light_rotation_vec[light_dict[current_light]].x); + randomizePopup("light_rotation_x_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_rotation_vec[light_dict[current_light]].x)); + randomizerParams("light_rotation_x_" + std::to_string(light_dict[current_light])); + ImGui::OpenPopupOnItemClick(("light_rotation_x_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(90); + ImGui::InputFloat("##light_rotation_y", &light_rotation_vec[light_dict[current_light]].y); + randomizePopup("light_rotation_y_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_rotation_vec[light_dict[current_light]].y)); + randomizerParams("light_rotation_y_" + std::to_string(light_dict[current_light])); + ImGui::OpenPopupOnItemClick(("light_rotation_y_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(90); + ImGui::InputFloat("##light_rotation_z", &light_rotation_vec[light_dict[current_light]].z); + randomizePopup("light_rotation_z_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_rotation_vec[light_dict[current_light]].z)); + randomizerParams("light_rotation_z_" + std::to_string(light_dict[current_light])); + ImGui::OpenPopupOnItemClick(("light_rotation_z_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Light Rotation"); + } + // ####### LIGHT SIZE ####### // + if (light_types[light_dict[current_light]] == "rectangle") { + ImGui::SetNextItemWidth(90); + ImGui::InputFloat("##light_size_x", &light_size_vec[light_dict[current_light]].x); + randomizePopup("light_size_x_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_size_vec[light_dict[current_light]].x)); + randomizerParams("light_size_x_" + std::to_string(light_dict[current_light])); + ImGui::OpenPopupOnItemClick(("light_size_x_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::SetNextItemWidth(90); + ImGui::InputFloat("##light_size_y", &light_size_vec[light_dict[current_light]].y); + randomizePopup("light_size_y_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_size_vec[light_dict[current_light]].y)); + randomizerParams("light_size_y_" + std::to_string(light_dict[current_light])); + ImGui::OpenPopupOnItemClick(("light_size_y_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Light Size"); + } + // ####### LIGHT RADIUS ####### // + if (light_types[light_dict[current_light]] == "disk" || light_types[light_dict[current_light]] == "sphere") { + ImGui::SetNextItemWidth(90); + ImGui::InputFloat("##light_radius", &light_radius_vec[light_dict[current_light]]); + randomizePopup("light_radius_" + std::to_string(light_dict[current_light]), createTaggedPtr(&light_radius_vec[light_dict[current_light]])); + randomizerParams("light_radius_" + std::to_string(light_dict[current_light])); + ImGui::OpenPopupOnItemClick(("light_radius_" + std::to_string(light_dict[current_light])).c_str(), ImGuiPopupFlags_MouseButtonRight); + ImGui::SameLine(); + ImGui::Text("Light Radius"); + } + // LIGHT END +#endif +} + + void ProjectBuilder::canopyTab(std::string curr_canopy_name, int id) { -#ifdef ENABLE_PLANT_ARCHITECTURE + #ifdef ENABLE_PLANT_ARCHITECTURE if (ImGui::Button("Update Canopy")) { updateCanopy(curr_canopy_name); is_dirty = true; @@ -5076,7 +5375,6 @@ void ProjectBuilder::canopyTab(std::string curr_canopy_name, int id) { deleteCanopy(curr_canopy_name); is_dirty = true; canopy_dict[current_canopy].is_dirty = false; - // refreshVisualization(); } if (canopy_dict[curr_canopy_name].is_dirty) { ImGui::SameLine(); @@ -5147,7 +5445,7 @@ void ProjectBuilder::canopyTab(std::string curr_canopy_name, int id) { prev_plant_library_ != canopy_dict[curr_canopy_name].library_name || prev_plant_age_ != canopy_dict[curr_canopy_name].age || prev_ground_clipping_height_ != canopy_dict[curr_canopy_name].ground_clipping_height) { canopy_dict[curr_canopy_name].is_dirty = true; } -#endif // PLANT_ARCHITECTURE + #endif // PLANT_ARCHITECTURE } void ProjectBuilder::saveCanopy(std::string file_name, std::vector canopy_ID_vec, vec3 position, std::string file_extension) const { @@ -5682,13 +5980,12 @@ void ProjectBuilder::outputConsole() { std::streambuf *prev_buf = std::cout.rdbuf(); std::string buffer = captured_cout.str(); std::size_t buffer_size = buffer.size(); - if (ImGui::BeginChild("##console", ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 5), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar)) { - ImGui::TextUnformatted(buffer.c_str()); - if (buffer_size != last_console_size) { - ImGui::SetScrollHereY(1.0f); - } - ImGui::EndChild(); + ImGui::BeginChild("##console", ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 5), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::TextUnformatted(buffer.c_str()); + if (buffer_size != last_console_size) { + ImGui::SetScrollHereY(1.0f); } + ImGui::EndChild(); last_console_size = buffer_size; std::cout.rdbuf(prev_buf); } @@ -5746,17 +6043,19 @@ void ProjectBuilder::updateColor(std::string curr_obj, std::string obj_type, flo void ProjectBuilder::updateObject(std::string curr_obj) { // Scale, rotate, and translate object if (objects_dict[curr_obj].use_texture_file && objects_dict[curr_obj].is_dirty) { - context->deletePrimitive(objects_dict[curr_obj].UUIDs); + context->deleteObject(objects_dict[curr_obj].objID); if (std::filesystem::path(objects_dict[curr_obj].file).extension() == ".obj") { objects_dict[curr_obj].UUIDs = context->loadOBJ(objects_dict[curr_obj].file.c_str()); } else if (std::filesystem::path(objects_dict[curr_obj].file).extension() == ".ply") { objects_dict[curr_obj].UUIDs = context->loadPLY(objects_dict[curr_obj].file.c_str()); } - context->scalePrimitive(objects_dict[curr_obj].UUIDs, objects_dict[curr_obj].scale); - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].orientation.x), "x"); - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].orientation.y), "y"); - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].orientation.z), "z"); - context->translatePrimitive(objects_dict[curr_obj].UUIDs, objects_dict[curr_obj].position); + objects_dict[curr_obj].objID = context->addPolymeshObject(objects_dict[curr_obj].UUIDs); + + context->scaleObject(objects_dict[curr_obj].objID, objects_dict[curr_obj].scale); + context->rotateObject(objects_dict[curr_obj].objID, deg2rad(objects_dict[curr_obj].orientation.x), "x"); + context->rotateObject(objects_dict[curr_obj].objID, deg2rad(objects_dict[curr_obj].orientation.y), "y"); + context->rotateObject(objects_dict[curr_obj].objID, deg2rad(objects_dict[curr_obj].orientation.z), "z"); + context->translateObject(objects_dict[curr_obj].objID, objects_dict[curr_obj].position); objects_dict[curr_obj].prev_scale = objects_dict[curr_obj].scale; objects_dict[curr_obj].prev_orientation = objects_dict[curr_obj].orientation; @@ -5767,29 +6066,32 @@ void ProjectBuilder::updateObject(std::string curr_obj) { obj_scale_.x = objects_dict[curr_obj].scale.x / objects_dict[curr_obj].prev_scale.x; obj_scale_.y = objects_dict[curr_obj].scale.y / objects_dict[curr_obj].prev_scale.y; obj_scale_.z = objects_dict[curr_obj].scale.z / objects_dict[curr_obj].prev_scale.z; - // context->scalePrimitiveAboutPoint(); - context->translatePrimitive(objects_dict[curr_obj].UUIDs, -objects_dict[curr_obj].prev_position); // translate back to origin - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, -deg2rad(objects_dict[curr_obj].prev_orientation.x), "x"); - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, -deg2rad(objects_dict[curr_obj].prev_orientation.y), "y"); - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, -deg2rad(objects_dict[curr_obj].prev_orientation.z), "z"); - - context->scalePrimitive(objects_dict[curr_obj].UUIDs, obj_scale_); - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].prev_orientation.x), "x"); - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].prev_orientation.y), "y"); - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].prev_orientation.z), "z"); - context->translatePrimitive(objects_dict[curr_obj].UUIDs, objects_dict[curr_obj].prev_position); // restore translation + context->translateObject(objects_dict[curr_obj].objID, -objects_dict[curr_obj].prev_position); // translate back to origin + context->rotateObject(objects_dict[curr_obj].objID, -deg2rad(objects_dict[curr_obj].prev_orientation.x), "x"); + context->rotateObject(objects_dict[curr_obj].objID, -deg2rad(objects_dict[curr_obj].prev_orientation.y), "y"); + context->rotateObject(objects_dict[curr_obj].objID, -deg2rad(objects_dict[curr_obj].prev_orientation.z), "z"); + + context->scaleObject(objects_dict[curr_obj].objID, obj_scale_); + context->rotateObject(objects_dict[curr_obj].objID, deg2rad(objects_dict[curr_obj].prev_orientation.x), "x"); + context->rotateObject(objects_dict[curr_obj].objID, deg2rad(objects_dict[curr_obj].prev_orientation.y), "y"); + context->rotateObject(objects_dict[curr_obj].objID, deg2rad(objects_dict[curr_obj].prev_orientation.z), "z"); + context->translateObject(objects_dict[curr_obj].objID, objects_dict[curr_obj].prev_position); // restore translation objects_dict[curr_obj].prev_scale = objects_dict[curr_obj].scale; } if (objects_dict[curr_obj].orientation != objects_dict[curr_obj].prev_orientation) { // context->rotatePrimitive(origin = prev_position, axis = (1,0,0)); // rotate about x - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].orientation.x - objects_dict[curr_obj].prev_orientation.x), objects_dict[curr_obj].prev_position, make_vec3(1, 0, 0)); - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].orientation.y - objects_dict[curr_obj].prev_orientation.y), objects_dict[curr_obj].prev_position, make_vec3(0, 1, 0)); - context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].orientation.z - objects_dict[curr_obj].prev_orientation.z), objects_dict[curr_obj].prev_position, make_vec3(0, 0, 1)); + // context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].orientation.x - objects_dict[curr_obj].prev_orientation.x), objects_dict[curr_obj].prev_position, make_vec3(1, 0, 0)); + // context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].orientation.y - objects_dict[curr_obj].prev_orientation.y), objects_dict[curr_obj].prev_position, make_vec3(0, 1, 0)); + // context->rotatePrimitive(objects_dict[curr_obj].UUIDs, deg2rad(objects_dict[curr_obj].orientation.z - objects_dict[curr_obj].prev_orientation.z), objects_dict[curr_obj].prev_position, make_vec3(0, 0, 1)); + context->rotateObject(objects_dict[curr_obj].objID, deg2rad(objects_dict[curr_obj].orientation.x - objects_dict[curr_obj].prev_orientation.x), objects_dict[curr_obj].prev_position, make_vec3(1, 0, 0)); + context->rotateObject(objects_dict[curr_obj].objID, deg2rad(objects_dict[curr_obj].orientation.y - objects_dict[curr_obj].prev_orientation.y), objects_dict[curr_obj].prev_position, make_vec3(0, 1, 0)); + context->rotateObject(objects_dict[curr_obj].objID, deg2rad(objects_dict[curr_obj].orientation.z - objects_dict[curr_obj].prev_orientation.z), objects_dict[curr_obj].prev_position, make_vec3(0, 0, 1)); objects_dict[curr_obj].prev_orientation = objects_dict[curr_obj].orientation; } if (objects_dict[curr_obj].position != objects_dict[curr_obj].prev_position) { - context->translatePrimitive(objects_dict[curr_obj].UUIDs, objects_dict[curr_obj].position - objects_dict[curr_obj].prev_position); + // context->translatePrimitive(objects_dict[curr_obj].UUIDs, objects_dict[curr_obj].position - objects_dict[curr_obj].prev_position); + context->translateObject(objects_dict[curr_obj].objID, objects_dict[curr_obj].position - objects_dict[curr_obj].prev_position); objects_dict[curr_obj].prev_position = objects_dict[curr_obj].position; } objects_dict[curr_obj].prev_color = objects_dict[curr_obj].color; @@ -5825,6 +6127,67 @@ void ProjectBuilder::deleteRig(std::string curr_rig) { } +void ProjectBuilder::addRig(std::string new_rig_label) { + rig new_rig; + new_rig.label = new_rig_label; + + if (current_rig.empty()) { + // If there is no currently selected rig, use default values. + new_rig.position = default_rig.position; + new_rig.lookat = default_rig.position; + new_rig.camera_labels = default_rig.camera_labels; + new_rig.position_noise = default_rig.position_noise; + new_rig.lookat_noise = default_rig.lookat_noise; + new_rig.camera_positions = default_rig.camera_positions; + new_rig.camera_lookats = default_rig.camera_lookats; + new_rig.color = default_rig.color; + new_rig.num_images = default_rig.num_images; + new_rig.keypoint_frames = default_rig.keypoint_frames; + } else { + // If there is a currently selected rig, copy current values. + rig curr_rig = rig_dict_.at(current_rig); + + new_rig.label = curr_rig.label; + new_rig.position = curr_rig.position; + new_rig.lookat = curr_rig.lookat; + new_rig.camera_labels = curr_rig.camera_labels; + new_rig.position_noise = curr_rig.position_noise; + new_rig.lookat_noise = curr_rig.lookat_noise; + new_rig.camera_positions = curr_rig.camera_positions; + new_rig.camera_lookats = curr_rig.camera_lookats; + new_rig.color = curr_rig.color; + new_rig.num_images = curr_rig.num_images; + new_rig.keypoint_frames = curr_rig.keypoint_frames; + } + + rig_dict_.insert({new_rig_label, new_rig}); + + rig_dict.insert({new_rig_label, scast(rig_labels.size())}); + camera_positions.push_back(camera_position); + camera_lookats.push_back(camera_lookat); + camera_labels.push_back(camera_label); + camera_position_vec.push_back(camera_position_vec[rig_dict[current_rig]]); + camera_lookat_vec.push_back(camera_lookat_vec[rig_dict[current_rig]]); + rig_labels.push_back(new_rig_label); + rig_labels_set.insert(new_rig_label); + rig_camera_labels.push_back(rig_camera_labels[rig_dict[current_rig]]); + rig_light_labels.push_back(rig_light_labels[rig_dict[current_rig]]); + keypoint_frames.push_back(keypoint_frames[rig_dict[current_rig]]); + num_images_vec.push_back(num_images_vec[rig_dict[current_rig]]); + rig_colors.push_back(rig_colors[rig_dict[current_rig]]); + rig_position_noise.push_back(std::vector{distribution{}, distribution{}, distribution{}}); + rig_lookat_noise.push_back(std::vector{distribution{}, distribution{}, distribution{}}); + // current_rig = new_rig_label; + std::string parent = "rig"; + pugi::xml_node rig_block = helios.child(parent.c_str()); + pugi::xml_node new_rig_node = helios.append_copy(rig_block); + std::string name = "label"; + pugi::xml_attribute node_label = new_rig_node.attribute(name.c_str()); + node_label.set_value(new_rig_label.c_str()); + current_rig = new_rig_label; +} + + #ifdef ENABLE_HELIOS_VISUALIZER void ProjectBuilder::dropDown(std::string widget_name, std::string &selected, std::vector choices) { if (ImGui::BeginCombo(widget_name.c_str(), selected.c_str())) { @@ -5882,7 +6245,6 @@ void ProjectBuilder::deleteCanopy(const std::string &canopy) { void ProjectBuilder::deleteObject(const std::string &obj) { context->deletePrimitive(objects_dict[obj].UUIDs); - // refreshVisualization(); objects_dict.erase(obj); obj_names_set.erase(obj); if (!obj_names_set.empty()) { @@ -5896,7 +6258,7 @@ void ProjectBuilder::deleteObject(const std::string &obj) { void ProjectBuilder::updateCanopy(const std::string &canopy) { -#ifdef ENABLE_PLANT_ARCHITECTURE + #ifdef ENABLE_PLANT_ARCHITECTURE for (auto plant_instance: canopy_dict[canopy].IDs) { plantarchitecture->deletePlantInstance(plant_instance); } @@ -5928,7 +6290,8 @@ void ProjectBuilder::updateCanopy(const std::string &canopy) { primitive_UUIDs["flower"] = flower_UUIDs; canopy_dict[canopy].IDs = new_canopy_IDs; -#endif + canopy_dict[canopy].is_dirty = false; + #endif } @@ -5972,6 +6335,7 @@ void ProjectBuilder::refreshVisualization() { visualizer->addCoordinateAxes(helios::make_vec3(0, 0, 0.05), helios::make_vec3(1, 1, 1), "positive"); } visualizer->plotUpdate(); + updatePrimitiveTypes(); } #else void ProjectBuilder::refreshVisualization() { @@ -5985,6 +6349,7 @@ void ProjectBuilder::recordPopup() { if (ImGui::BeginPopup("repeat_record")) { ImGui::SetNextItemWidth(100); ImGui::InputInt("Number of Recordings", &num_recordings); + num_recordings = std::max(num_recordings, 1); ImGui::EndPopup(); } } @@ -6075,24 +6440,15 @@ void ProjectBuilder::deleteGround() { void ProjectBuilder::refreshVisualizationTypes() { // primitive visualization_types_primitive.clear(); - std::vector allUUIDs = context->getAllUUIDs(); - for (auto &UUID: allUUIDs) { - std::vector primitiveData = context->listPrimitiveData(UUID); - for (auto &data: primitiveData) { - visualization_types_primitive.insert(data); - primitive_data_types[data] = context->getPrimitiveDataType(data.c_str()); - } + for (auto &data: context->listAllPrimitiveDataLabels()) { + visualization_types_primitive.insert(data); + primitive_data_types[data] = context->getPrimitiveDataType(data.c_str()); } // object visualization_types_object.clear(); - std::vector allobjIDs = context->getAllObjectIDs(); - for (auto &objID: allobjIDs) { - std::vector objData = context->listObjectData(objID); - for (auto &data: objData) { - visualization_types_object.insert(data); - object_data_types[data] = context->getObjectDataType(data.c_str()); - } + for (auto &data: context->listAllObjectDataLabels()) { + visualization_types_object.insert(data); } } #else @@ -6207,3 +6563,160 @@ void ProjectBuilder::buildTiledGround(const vec3 &ground_origin, const vec2 &gro context->setPrimitiveData(ground_UUIDs, "object_label", "ground"); primitive_UUIDs["ground"] = ground_UUIDs; } + +void ProjectBuilder::refreshBoundingBoxObjectList() { + for (auto &primitive_UUID : context->getAllUUIDs()) { + for (std::string data : context->listPrimitiveData(primitive_UUID)) { + if ( context->getPrimitiveDataType( primitive_UUID, data.c_str() ) == HELIOS_TYPE_INT || + context->getPrimitiveDataType( primitive_UUID, data.c_str() ) == HELIOS_TYPE_UINT ) { + if ( bounding_boxes.find( data ) == bounding_boxes.end() ) { + bounding_boxes.insert({data, false}); + bounding_boxes_primitive.insert(data); + } + } + } + } + for (auto &object_UUID : context->getAllObjectIDs()) { + for (std::string data : context->listObjectData(object_UUID)) { + if ( context->getObjectDataType( object_UUID, data.c_str() ) == HELIOS_TYPE_INT || + context->getObjectDataType( object_UUID, data.c_str() ) == HELIOS_TYPE_UINT ) { + if ( bounding_boxes.find( data ) == bounding_boxes.end() ) { + bounding_boxes.insert({data, false}); + bounding_boxes_object.insert(data); + } + } + } + } +} + + +void ProjectBuilder::globalCalculation() { + // Get all relevant primitives + std::vector relevant_UUIDs{}; + if (calculation_selection_datagroup["All"]) { + for (auto &prim_pair : primitive_UUIDs) { + if (calculation_selection_primitive[prim_pair.first] || calculation_selection_primitive["All"]) { + relevant_UUIDs.insert(relevant_UUIDs.end(), prim_pair.second.begin(), prim_pair.second.end()); + } + } + } else { + for (auto &obj : objects_dict) { + if (calculation_selection_datagroup[obj.second.data_group]) { + for (auto &prim_pair : calculation_selection_primitive) { + if (prim_pair.second || calculation_selection_primitive["All"]) { + std::vector new_UUIDs = context->filterPrimitivesByData(obj.second.UUIDs, "object_label", prim_pair.first); + relevant_UUIDs.insert(relevant_UUIDs.end(), new_UUIDs.begin(), new_UUIDs.end()); + } + } + } + } + for (auto &canopy : canopy_dict) { + if (calculation_selection_datagroup[canopy.second.data_group]) { + std::vector canopy_UUIDs; + for (auto &plant_id : canopy.second.IDs) { + std::vector plant_UUIDs =context->getObjectPrimitiveUUIDs( plantarchitecture->getAllPlantObjectIDs(plant_id) ); + canopy_UUIDs.insert(canopy_UUIDs.end(), plant_UUIDs.begin(), plant_UUIDs.end()); + } + for (auto &prim_pair : calculation_selection_primitive) { + if (prim_pair.second || calculation_selection_primitive["All"]) { + std::vector new_UUIDs = context->filterPrimitivesByData(canopy_UUIDs, "object_label", prim_pair.first); + relevant_UUIDs.insert(relevant_UUIDs.end(), new_UUIDs.begin(), new_UUIDs.end()); + } + } + } + } + } + std::vector globalVars = context->listGlobalData(); + // Perform calculation + if (std::find(globalVars.begin(), globalVars.end(), calculation_variables_global[0]) != globalVars.end()) { + context->getGlobalData(calculation_variables_global[0].c_str(), calculation_result_global); + } else if (curr_aggregation == "Mean") { + context->calculatePrimitiveDataMean(relevant_UUIDs, calculation_variables_global[0], calculation_result_global); + } else if (calculation_aggregations[0] == "Sum") { + context->calculatePrimitiveDataSum(relevant_UUIDs, calculation_variables_global[0], calculation_result_global); + } else if (calculation_aggregations[0] == "Area Weighted Mean") { + context->calculatePrimitiveDataAreaWeightedMean(relevant_UUIDs, calculation_variables_global[0], calculation_result_global); + } else if (calculation_aggregations[0] == "Area Weighted Sum") { + context->calculatePrimitiveDataAreaWeightedSum(relevant_UUIDs, calculation_variables_global[0], calculation_result_global); + } + for (int i = 0; i < calculation_operators_global.size(); i++) { + float prev_res = calculation_result_global; + if (calculation_aggregations[i] == "Mean") { + context->calculatePrimitiveDataMean(relevant_UUIDs, calculation_variables_global[0], calculation_result_global); + } else if (calculation_aggregations[i] == "Sum") { + context->calculatePrimitiveDataSum(relevant_UUIDs, calculation_variables_global[0], calculation_result_global); + } else if (calculation_aggregations[i] == "Area Weighted Mean") { + context->calculatePrimitiveDataAreaWeightedMean(relevant_UUIDs, calculation_variables_global[0], calculation_result_global); + } else if (calculation_aggregations[i] == "Area Weighted Sum") { + context->calculatePrimitiveDataAreaWeightedSum(relevant_UUIDs, calculation_variables_global[0], calculation_result_global); + } + std::string curr_op = calculation_operators_global[i]; + if (curr_op == "+") { + calculation_result_global = prev_res + calculation_result_global; + } else if (curr_op == "-") { + calculation_result_global = prev_res - calculation_result_global; + } else if (curr_op == "/") { + calculation_result_global = prev_res / calculation_result_global; + } else if (curr_op == "x") { + calculation_result_global = prev_res * calculation_result_global; + } + } +} + + + +void ProjectBuilder::savePrimitiveCalculation() { + // Get all relevant primitives + std::vector relevant_UUIDs{}; + if (calculation_selection_datagroup["All"]) { + for (auto &prim_pair : primitive_UUIDs) { + if (calculation_selection_primitive[prim_pair.first] || calculation_selection_primitive["All"]) { + relevant_UUIDs.insert(relevant_UUIDs.end(), prim_pair.second.begin(), prim_pair.second.end()); + } + } + } else { + for (auto &obj : objects_dict) { + if (calculation_selection_datagroup[obj.second.data_group]) { + for (auto &prim_pair : calculation_selection_primitive) { + if (prim_pair.second || calculation_selection_primitive["All"]) { + std::vector new_UUIDs = context->filterPrimitivesByData(obj.second.UUIDs, "object_label", prim_pair.first); + relevant_UUIDs.insert(relevant_UUIDs.end(), new_UUIDs.begin(), new_UUIDs.end()); + } + } + } + } + for (auto &canopy : canopy_dict) { + if (calculation_selection_datagroup[canopy.second.data_group]) { + std::vector canopy_UUIDs; + for (auto &plant_id : canopy.second.IDs) { + std::vector plant_UUIDs =context->getObjectPrimitiveUUIDs( plantarchitecture->getAllPlantObjectIDs(plant_id) ); + canopy_UUIDs.insert(canopy_UUIDs.end(), plant_UUIDs.begin(), plant_UUIDs.end()); + } + for (auto &prim_pair : calculation_selection_primitive) { + if (prim_pair.second || calculation_selection_primitive["All"]) { + std::vector new_UUIDs = context->filterPrimitivesByData(canopy_UUIDs, "object_label", prim_pair.first); + relevant_UUIDs.insert(relevant_UUIDs.end(), new_UUIDs.begin(), new_UUIDs.end()); + } + } + } + } + } + for (auto &UUID : relevant_UUIDs) { + context->setPrimitiveData(UUID, calculation_name_primitive.c_str(), calculation_result_global); + } + refreshVisualizationTypes(); +} + + +void ProjectBuilder::runRadiation() { + for (std::string band_group_name: band_group_names) { + bandGroup curr_band_group = band_group_lookup[band_group_name]; + if (!curr_band_group.grayscale) { + radiation->runBand(curr_band_group.bands); + } else { + radiation->runBand(std::vector{curr_band_group.bands[0]}); + } + } +} + + diff --git a/plugins/radiation/CMakeLists.txt b/plugins/radiation/CMakeLists.txt index 60e7bbd99..dad1047a8 100755 --- a/plugins/radiation/CMakeLists.txt +++ b/plugins/radiation/CMakeLists.txt @@ -9,7 +9,7 @@ endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/") -add_library(radiation STATIC "src/RadiationModel.cpp" "src/RadiationCamera.cpp" "src/CameraCalibration.cpp" "tests/selfTest.cpp") +add_library(radiation STATIC "src/RadiationModel.cpp" "src/RadiationCamera.cpp" "src/CameraCalibration.cpp" "tests/selfTest.cpp") target_include_directories(radiation PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/lib/json" ) diff --git a/plugins/visualizer/src/VisualizerRendering.cpp b/plugins/visualizer/src/VisualizerRendering.cpp index 298ad2173..74d6b8c17 100644 --- a/plugins/visualizer/src/VisualizerRendering.cpp +++ b/plugins/visualizer/src/VisualizerRendering.cpp @@ -724,16 +724,24 @@ void Visualizer::transferBufferData() { } void Visualizer::transferTextureData() { - if (texArray == 0) { - glGenTextures(1, &texArray); - } - - glBindTexture(GL_TEXTURE_2D_ARRAY, texArray); const size_t layers = std::max(1, texture_manager.size()); - if (layers != texture_array_layers) { + + // Check if texture needs recreation (Windows requires deleting and recreating texture + // when layer count changes due to glTexStorage3D immutable format restrictions) + if (texArray == 0 || layers != texture_array_layers) { + // Delete existing texture if it exists + if (texArray != 0) { + glDeleteTextures(1, &texArray); + } + + // Create new texture + glGenTextures(1, &texArray); + glBindTexture(GL_TEXTURE_2D_ARRAY, texArray); glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, maximum_texture_size.x, maximum_texture_size.y, layers); texture_array_layers = layers; + } else { + glBindTexture(GL_TEXTURE_2D_ARRAY, texArray); } glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);