// (c) 2025 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. ANSYS Confidential Information
syntax = "proto3";
import "ansys/api/speos/results/v1/ray_path.proto";

package ansys.api.speos.scene.v1;

// Optical scene definition made of parts, optical properties, sources, sensors and simulations
message Scene
{
	// Geometry path of object that will include the specific property (can be sub-scene/part/body/face). 
	// Empty or "" for all geometries, or in the format : <sub-scene name>/<part name>/<body name>/<face name> (no name by default for root scene and root part).
	// "part1" -> part1 of the root part in the root scene
	// "part1/body1/face1" -> face1 in body1 in part1 of the root part in the root scene
	// "subScene1" -> root part in the sub scene subScene1
	// "subScene1/part2" -> part2 of the sub scene subScene1
	message GeoPaths
	{
		repeated string geo_paths = 1; // list of geo paths
	}

	// Instance of a VOP to apply on geometries of the scene
	message VOPInstance
	{
		string name = 1;
		string description = 2;
		map<string, string> metadata = 3; // User defined metadata
		string vop_guid = 10; // Guid of the element to instantiate
		GeoPaths geometries = 11; // Geometries that will use this material
	}

	// Instance of a SOP to apply on geometries of the scene
	message SOPInstance
	{
		string name = 1;
		string description = 2;
		map<string, string> metadata = 3; // User defined metadata
		string sop_guid = 10; // Guid of the element to instantiate
		GeoPaths geometries = 11; // Geometries that will use this material
	}

	// Instance of a source to add in the scene
	message SourceInstance
	{
		message IntensityProperties {
			message LibraryProperties {
				message AxisSystem {
					repeated double values = 1; // orientation (Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz)
				}
				// Define the intensity distribution as normal to the selected surface.
				message NormalToSurface {}
				// Define the intensity distribution as normal to the selected emissive surface and its orientation on the emissive surface.
				message NormalToUVMap {}

				GeoPaths exit_geometries = 1; // Exit Geometries that will use this surface source 
				// Orientation of the source intensity distribution
				oneof orientation {
					AxisSystem axis_system = 2; // orientation (Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz)
					NormalToSurface normal_to_surface = 3; // Define the intensity distribution as normal to the selected surface.
					NormalToUVMap normal_to_uv_map = 4; // Define the intensity distribution as normal to the selected emissive surface and its orientation on the emissive surface.
				}
			}
			message AsymmetricGaussianProperties {
				option deprecated = true; // Use GaussianProperties instead
				repeated double axis_system = 1; // orientation (Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz)
			}

			message GaussianProperties {
			    repeated double axis_system = 1; // optional - orientation of the intensity distribution (Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz) - if not filled : normal to surface map.
			}

			oneof properties {
				LibraryProperties library_properties = 1; // To be filled if the intensity_guid of the source template corresponds to an IntensityTemplate of type Library
				AsymmetricGaussianProperties asymmetric_gaussian_properties = 2; // Deprecated (use gaussian_properties instead) - To be filled if the intensity_guid of the source template corresponds to an IntensityTemplate of type AsymmetricGaussian
				GaussianProperties gaussian_properties = 3; // To be filled if the intensity_guid of the source template corresponds to an IntensityTemplate of type Gaussian
			}
		}
		message LuminaireProperties{
			repeated double axis_system = 1; // Position of the source (Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz)
		}

		message SurfaceProperties{
			message ExitanceConstantProperties {
				message GeoPath {
					string geo_path = 1; // Geometry that will use this surface source ("<body name>" for a whole body, or "<body name>/<face name>" for a specific face) 
					optional bool reverse_normal = 2; // optional - if not set or false : normal is not reversed.
				}
				repeated GeoPath geo_paths = 1;
			}
			message ExitanceVariableProperties {
				repeated double axis_plane = 1; // Position of the exitance map (Ox Oy Oz Xx Xy Xz Yx Yy Yz)
			}

			oneof exitanceProperties {
				ExitanceConstantProperties exitance_constant_properties = 1; // To be filled if the Surface SourceTemplate has ExitanceConstant 
				ExitanceVariableProperties exitance_variable_properties = 2; // To be filled if the Surface SourceTemplate has ExitanceVariable 
			}
			IntensityProperties intensity_properties = 3;
		}

		message RayFileProperties{
			repeated double axis_system = 1; // Position of the source (Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz)
			GeoPaths exit_geometries = 2; // Exit Geometries that will use this rayfile source 
		}

		string name = 1;
		string description = 2;
		map<string, string> metadata = 3; // User defined metadata
		string source_guid = 10; // Guid of the SourceTemplate in SourceTemplatesManager to instantiate
		oneof properties {
			LuminaireProperties luminaire_properties = 11; // To be filled if the source_guid corresponds to a SourceTemplate of type Luminaire
			SurfaceProperties surface_properties = 12; // To be filled if the source_guid corresponds to a SourceTemplate of type Surface
			RayFileProperties rayfile_properties = 13; // To be filled if the source_guid corresponds to a SourceTemplate of type RayFile
		}
	}

	// Instance of a sensor to add in the scene
	message SensorInstance
	{
		// Ray file types available
		enum EnumRayFileType {
			RayFileNone = 0; // Generates no ray file.
			RayFileClassic = 1; // Generates a ray file without polarization data.
			RayFilePolarization = 2; // Generates a ray file with the polarization data for each ray.
			RayFileTM25 = 3; // Generates a .tm25ray file with polarization data for each ray.
			RayFileTM25NoPolarization = 4; // Generates a .tm25ray file without polarization data.
		}

		// Includes the simulation's results in one layer.
		message LayerTypeNone {}
		// Includes one layer per active source in the result.
		message LayerTypeSource {}
		// Includes one layer per surface selected in the result.
		message LayerTypeFace {
			enum EnumSCAFilteringType {
				LastImpact = 0;
				IntersectedOneTime = 1;
			}
			message Layer {
				string name = 1; // Name of the layer 
				GeoPaths geometries = 2; // Surface selected.
			}

			EnumSCAFilteringType sca_filtering_mode = 1;
			repeated Layer layers = 2; // Layers that will be taken into account in the result.
		}
		// Includes one layer per sequence in the result.
		message LayerTypeSequence {
			enum EnumSequenceType {
				Geometries = 0;
				Faces = 1;
			}

			uint32 maximum_nb_of_sequence = 1;
			EnumSequenceType define_sequence_per = 2;
		}
		// Includes one layer per Stokes parameter using the polarization parameter.
		message LayerTypePolarization {}
		// Includes one layer per range of incident angles.
		message LayerTypeIncidenceAngle {
			uint32 sampling = 1;
		}

		message CameraSensorProperties {
			repeated double axis_system = 1; // Position of the sensor (Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz)
			string trajectory_file_uri = 2; // Trajectory file, used to define the positions and orientations of the Camera sensor in time.
			oneof layer_type {
				LayerTypeNone layer_type_none = 3; // Layer type : None
				LayerTypeSource layer_type_source = 4; // Layer type : Source
			}
		}
		message IrradianceSensorProperties {
			repeated double axis_system = 1; // Position of the sensor (Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz)
			EnumRayFileType ray_file_type = 2; // Choose type of ray file generated after the simulation.
			oneof layer_type {
				LayerTypeNone layer_type_none = 3; // Layer type : None
				LayerTypeSource layer_type_source = 4; // Layer type : Source
				LayerTypeFace layer_type_face = 5; // Layer type : Face
				LayerTypeSequence layer_type_sequence = 6; // Layer type : Sequence
				LayerTypePolarization layer_type_polarization = 7; // Layer type : Polarization
				LayerTypeIncidenceAngle layer_type_incidence_angle = 8; // Layer type : Incidence angle
			}
			repeated double integration_direction = 9; // Sensor global integration direction [x,y,z], optional (default direction is normal to sensor plane (anti-normal of the sensor)) and only settable for sensor template with IlluminanceTypePlanar or IlluminanceTypeSemiCylindrical as illuminance_type
			GeoPaths output_face_geometries = 10; // List of output faces for inverse simulation optimization
		}
		message RadianceSensorProperties {
			repeated double axis_system = 1; // Position of the sensor (Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz)
			repeated double observer_point = 2; // Position of the observer point (Ox Oy Oz), optional (default: focal length is used)
			oneof layer_type {
				LayerTypeNone layer_type_none = 3; // Layer type : None
				LayerTypeSource layer_type_source = 4; // Layer type : Source
				LayerTypeFace layer_type_face = 5; // Layer type : Face
				LayerTypeSequence layer_type_sequence = 6; // Layer type : Sequence								
			}
		}

		string name = 1;
		string description = 2;
		map<string, string> metadata = 3; // User defined metadata
		string sensor_guid = 10; // Guid of the SensorTemplate in SensorTemplatesManager to instantiate
		string result_file_name = 11; // Result file name without extention. Result files of the sensor will be based on this name.
		oneof properties {
			CameraSensorProperties camera_sensor_properties = 12; // To be filled if the sensor_guid corresponds to a SensorTemplate of type CameraSensorTemplate
			IrradianceSensorProperties irradiance_sensor_properties = 13; // To be filled if the sensor_guid corresponds to a SensorTemplate of type IrradianceSensorTemplate
			RadianceSensorProperties radiance_sensor_properties = 14; // To be filled if the sensor_guid corresponds to a SensorTemplate of type SensorTemplate::Radiance
		}
	}

	// Instance of a simulation to add in the scene
	message SimulationInstance
	{
		string name = 1;
		string description = 2;
		map<string, string> metadata = 3; // User defined metadata
		string simulation_guid = 10; // Guid of the element to instantiate
		repeated string sensor_paths = 11; // Sensors that this simulation will include (empty or "" for all sensors, "<sensor name>" for a specific sensor in the current scene, or "<scene name>/<sensor name>" for a specific sensor in a specific sub scene)
		repeated string source_paths = 12; // Sources that this simulation will include (empty or "" for all sources, "<source name>" for a specific source in the current scene, or "<scene name>/<source name>" for a specific source in a specific sub scene)
		GeoPaths geometries = 13; // Geometries that this simulation will include (empty to select the root part and all the subscenes)
	}

	message SceneInstance
	{
		string name = 1;
		string description = 2;
		map<string, string> metadata = 3; // User defined metadata
		string scene_guid = 10; // Guid of the element to instantiate
		repeated double axis_system = 11; // Scene position relative to parent PartTemplate reference (Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz) 
	}

	string name = 1;
	string description = 2;
	map<string, string> metadata = 3; // User defined metadata

	string part_guid = 10; // Guid from PartsManager of the geometrical part included inside the scene
	repeated VOPInstance vops = 11; // The volume materials applied on geometries
	repeated SOPInstance sops = 12; // The surface materials applied on geometries
	repeated SourceInstance sources = 13; // The sources added in the scene
	repeated SensorInstance sensors = 14; // The sensors added in the scene
	repeated SimulationInstance simulations = 15; // The simulations added in the scene
	
	repeated SceneInstance scenes = 20; // Sub scenes
}

// Manager for Scenes
service ScenesManager {
	// Create a Scene
	rpc Create(Create_Request) returns (Create_Response) {}
	// Read a Scene
	rpc Read(Read_Request) returns (Read_Response) {}
	// Update a Scene
	rpc Update(Update_Request) returns (Update_Response) {}
	// Delete a Scene
	rpc Delete(Delete_Request) returns (Delete_Response) {}
	// List all Scenes in manager
	rpc List(List_Request) returns (List_Response) {}
}

// Request to create a Scene in ScenesManager
message Create_Request {
	Scene scene = 1;
}
message Create_Response {
	string guid = 1; // Guid of the Scene created in ScenesManager
}

// Request to read a Scene in ScenesManager
message Read_Request {
	string guid = 1; // Guid of the Scene to be read
}
message Read_Response {
	Scene scene = 1; // Scene corresponding to the guid given in Read_Request
}

// Request to update a Scene in ScenesManager
message Update_Request {
	string guid = 1; // Guid of the Scene to be updated
	Scene scene = 2; // Scene that will be used for the update
}
message Update_Response {}

// Request to delete a Scene in ScenesManager
message Delete_Request {
	string guid = 1; // Guid of the Scene to be deleted
}
message Delete_Response {}

message List_Request {}
message List_Response {
	repeated string guids = 1; // Guids of the Scenes in ScenesManager
}

// Actions available on a Scene
service SceneActions {
	// Load .speos file
	rpc LoadFile(LoadFile_Request) returns (LoadFile_Response) {} 
	// Save .speos file
	rpc SaveFile(SaveFile_Request) returns (SaveFile_Response) {} 
	// Get RayPaths generated by a source
	rpc GetSourceRayPaths(GetSourceRayPaths_Request) returns (stream ansys.api.speos.results.v1.RayPath) {}
}

// Request to LoadFile service
message LoadFile_Request {
	string guid = 1; // Guid of a ScenesManager element to update
    string file_uri = 2; // File uri (path or guid from FileTransferService) 
}
// Response to LoadFile service
message LoadFile_Response {
}

// Request to SaveFile service
message SaveFile_Request {
    string guid = 1; // Guid of a ScenesManager element to save
    string file_uri = 2; // File uri (path or guid from FileTransferService) 
}
// Response to SaveFile service
message SaveFile_Response {
}

message GetSourceRayPaths_Request {
	string guid = 1; // Guid of a ScenesManager element
	string source_path = 2; // path to the source in the Scene : "<source name>" for a specific source in the current scene, or "<scene name>/<source name>" for a specific source in a specific sub scene
	optional uint32 rays_nb = 3; // Number of rays sent by the source. Default 100
	optional bool raw_data = 4; // Boolean to get the wavelengths in response stream
	optional bool display_data = 5; // Boolean to get the colors (RGB24 format) in response stream
}