/// <summary> /// Add a new timestep to this VTKDataset /// </summary> /// <param name="parser">The parser data for this new timestep. As VTK format does not handle timestep inherently, we are using multiple VTKParser</param> /// <returns></returns> public bool AddTimestep(VTKParser parser) { //Check the type of the new timestep if (Parser.GetDatasetType() != parser.GetDatasetType()) { return(false); } if (Parser.GetDatasetType() == VTKDatasetType.VTK_STRUCTURED_POINTS) { if (Parser.GetStructuredPointsDescriptor() != parser.GetStructuredPointsDescriptor()) { return(false); } } List <VTKFieldValue> ptFieldValues = new List <VTKFieldValue>(); List <VTKFieldValue> cellFieldValues = new List <VTKFieldValue>(); foreach (VTKFieldValue f in PtFieldValues) { VTKFieldValue tf = parser.GetPointFieldValueDescriptors().Find((t) => (f as FieldValueMetaData) == (t as FieldValueMetaData)); if (tf is null) { return(false); } ptFieldValues.Add(tf); } foreach (VTKFieldValue f in CellFieldValues) { VTKFieldValue tf = parser.GetCellFieldValueDescriptors().Find((t) => (f as FieldValueMetaData) == (t as FieldValueMetaData)); if (tf is null) { return(false); } ptFieldValues.Add(tf); } m_timesteps.Add(new VTKDatasetTimeStep { Parser = parser, PtFieldValues = ptFieldValues, CellFieldValues = cellFieldValues }); m_nbTimesteps++; return(true); }
/// <summary> /// Represent a VTKDataset /// </summary> /// <param name="id">The ID of the Dataset</param> /// <param name="name">The Dataset's name</param> /// <param name="parser">The VTKParser containing all the dataset.</param> /// <param name="ptFieldValues">Array of point field values to take account of</param> /// <param name="cellFieldValues">Array of cell field values to take account of</param> public VTKDataset(int id, String name, VTKParser parser, VTKFieldValue[] ptFieldValues, VTKFieldValue[] cellFieldValues) : base(id, name) { m_timesteps.Add(new VTKDatasetTimeStep { Parser = parser, PtFieldValues = new List <VTKFieldValue>(ptFieldValues), CellFieldValues = new List <VTKFieldValue>(cellFieldValues) }); m_nbTimesteps = 1; //Add all the field values to load for (int i = 0; i < PtFieldValues.Count; i++) { VTKFieldValue metaData = PtFieldValues[i]; PointFieldDescriptor desc = new PointFieldDescriptor(metaData); desc.ID = (UInt32)i; m_ptFieldDescs.Add(desc); } }
public override Task <int> LoadValues() { return(Task.Run(() => { bool succeed = true; //Load the mask if it exists. Look at only timestep 0 (normally every timesteps should be consistent) foreach (VTKFieldValue fv in Parser.GetPointFieldValueDescriptors()) { if (fv.Name == "vtkValidPointMask") { m_mask = Parser.ParseAllFieldValues(fv); break; } } for (int t = 0; t < m_nbTimesteps; t++) { for (int i = 0; i < m_ptFieldDescs.Count; i++) { //Get our working variables PointFieldDescriptor desc = m_ptFieldDescs[i]; VTKFieldValue fieldVal = m_timesteps[t].PtFieldValues[i]; //Load disk values VTKValue value = m_timesteps[t].Parser.ParseAllFieldValues(fieldVal); desc.Value.Add(value); object lockObject = new object(); //This if used as a lock //Case 1: scalar values if (desc.NbValuesPerTuple == 1) { //Compute min/max ranges Parallel.For(0, desc.NbTuples, () => new float[2] { float.MaxValue, float.MinValue }, (j, loopState, partialRes) => { //Read mask unsafe { if (m_mask != null && ((byte *)m_mask.Value)[j] == 0) { return partialRes; } } float val = value.ReadAsFloat((UInt64)j); if (float.IsNaN(val)) { if (m_mask != null) { unsafe { ((byte *)m_mask.Value)[j] = 0; } } return partialRes; } partialRes[0] = Math.Min(partialRes[0], val); partialRes[1] = Math.Max(partialRes[1], val); return partialRes; }, (partialRes) => { lock (lockObject) { desc.MinVal = Math.Min(desc.MinVal, partialRes[0]); desc.MaxVal = Math.Max(desc.MaxVal, partialRes[1]); } }); } //Case 2: vector values else { //Compute min/max ranges. Consider here only vector magnitude in the computation Parallel.For(0, desc.NbTuples, () => new float[2] { float.MaxValue, float.MinValue }, (j, loopState, partialRes) => { //Read mask unsafe { if (m_mask != null && ((byte *)m_mask.Value)[j] == 0) { return partialRes; } } float mag = 0; for (int k = 0; k < desc.NbValuesPerTuple; k++) { float val = value.ReadAsFloat((UInt64)(j * desc.NbValuesPerTuple + k)); if (float.IsNaN(val)) { if (m_mask != null) { unsafe { ((byte *)m_mask.Value)[j] = 0; } } return partialRes; } mag += val * val; } mag = (float)Math.Sqrt((double)mag); partialRes[0] = Math.Min(partialRes[0], mag); partialRes[1] = Math.Max(partialRes[1], mag); return partialRes; }, (partialRes) => { lock (lockObject) { desc.MinVal = Math.Min(desc.MinVal, partialRes[0]); desc.MaxVal = Math.Max(desc.MaxVal, partialRes[1]); } }); } } } m_isLoaded = true; return (succeed ? 1 : 0); })); }