private void ChooseSingleFilteredPassForCellPromProfiler(byte stripeIndex, byte j, out int topMostLayerCompactionHalfPassCount) { // if (Debug_ExtremeLogSwitchD) Log.LogDebug{$"SI@{StripeIndex}/{J} at {clientGrid.OriginX}x{clientGrid.OriginY}: Using profiler"); topMostLayerCompactionHalfPassCount = 0; if (_canUseGlobalLatestCells) { // Optimistically assume that the global latest value is acceptable AssignRequiredFilteredPassAttributesFromGlobalLatestCells(ref _assignmentContext.FilteredValue.FilteredPassData.FilteredPass, stripeIndex, j); _assignmentContext.FilteredValue.PassCount = -1; // Check to see if there is a non-null value for the requested field in the latest value. // If there is none, then there is no non-null value in any of the recorded cells passes // so the null value may be returned as the filtered value. if (_clientGrid.AssignableFilteredValueIsNull(ref _assignmentContext.FilteredValue.FilteredPassData)) { return; } if (_clientGrid.WantsLiftProcessingResults()) { _haveFilteredPass = IsFilteredValueFromLatestCellPass(stripeIndex, j); } if (_haveFilteredPass) { FiltersValuePopulation.PopulateFilteredValues(_siteModel.MachinesTargetValues[_currentPass.FilteredPass.InternalSiteModelMachineIndex], _populationControl, ref _assignmentContext.FilteredValue.FilteredPassData); } } if (!_haveFilteredPass) { _cellPassIterator.SetCellCoordinatesInSubGrid(stripeIndex, j); // if (Debug_ExtremeLogSwitchD) Log.LogDebug{$"SI@{StripeIndex}/{J} at {clientGrid.OriginX}x{clientGrid.OriginY}: Calling BuildLiftsForCell"); if (_profiler.CellLiftBuilder.Build(_cellProfile, _liftParams, _clientGrid, _assignmentContext, // Place a filtered value into this assignment context _cellPassIterator, // Iterate over the cells using this cell pass iterator true)) // Return an individual filtered value { // topMostLayerPassCount = _profiler.CellLiftBuilder.FilteredPassCountOfTopMostLayer; topMostLayerCompactionHalfPassCount = _profiler.CellLiftBuilder.FilteredHalfCellPassCountOfTopMostLayer; // Filtered value selection is combined with lift analysis in this context via // the provision of the client grid and the assignment context to the lift analysis engine // If we have a temperature filter to be filtered by last pass if (_filter.AttributeFilter.HasTemperatureRangeFilter && _filter.AttributeFilter.FilterTemperatureByLastPass) { var materialTemperature = _cellProfile.Passes.FilteredPassData[_cellProfile.Passes.PassCount - 1].FilteredPass.MaterialTemperature; _haveFilteredPass = materialTemperature != CellPassConsts.NullMaterialTemperatureValue && Range.InRange(materialTemperature, _filter.AttributeFilter.MaterialTemperatureMin, _filter.AttributeFilter.MaterialTemperatureMax); } else { _haveFilteredPass = true; } } // if (Debug_ExtremeLogSwitchD) Log.LogDebug{$"SI@{StripeIndex}/{J} at {clientGrid.OriginX}x{clientGrid.OriginY}: Call to BuildLiftsForCell completed"); } }
/// <summary> /// Performs primary filtered iteration over cell passes in the cell being processed to determine the cell pass /// to be selected. /// </summary> private void ProcessCellPasses() { _haveFilteredPass = false; _firstPassMinElev = false; while (_cellPassIterator.MayHaveMoreFilterableCellPasses() && _cellPassIterator.GetNextCellPass(ref _currentPass.FilteredPass)) { FiltersValuePopulation.PopulateFilteredValues(_siteModel.MachinesTargetValues[_currentPass.FilteredPass.InternalSiteModelMachineIndex], _populationControl, ref _currentPass); if (_filter.AttributeFilter.FilterPass(ref _currentPass, _filterAnnex)) { if (_filter.AttributeFilter.HasElevationTypeFilter) { _assignmentContext.FilteredValue.PassCount = 1; } // Track cell passes against lowest/highest elevation criteria if (_filter.AttributeFilter.HasElevationTypeFilter && _filter.AttributeFilter.ElevationType == ElevationType.Lowest) { if (!_haveFilteredPass || _currentPass.FilteredPass.Height < _tempPass.FilteredPass.Height) { _tempPass = _currentPass; } _haveFilteredPass = true; } else if (_filter.AttributeFilter.HasElevationTypeFilter && _filter.AttributeFilter.ElevationType == ElevationType.Highest) { if (!_haveFilteredPass || _currentPass.FilteredPass.Height > _tempPass.FilteredPass.Height) { _tempPass = _currentPass; } _haveFilteredPass = true; } else if (_filter.AttributeFilter.HasElevationTypeFilter && _filter.AttributeFilter.ElevationType == ElevationType.First) { _assignmentContext.FilteredValue.FilteredPassData = _currentPass; _haveFilteredPass = true; _assignmentContext.FilteredValue.PassCount = CellPassConsts.NullPassCountValue; break; } else if (_gridDataType == GridDataType.Temperature) { var materialTemperature = _currentPass.FilteredPass.MaterialTemperature; if (materialTemperature != CellPassConsts.NullMaterialTemperatureValue) { if (_filter.AttributeFilter.HasTemperatureRangeFilter) { if (Range.InRange(materialTemperature, _filter.AttributeFilter.MaterialTemperatureMin, _filter.AttributeFilter.MaterialTemperatureMax)) { _assignmentContext.FilteredValue.FilteredPassData = _currentPass; _haveFilteredPass = true; _assignmentContext.FilteredValue.PassCount = CellPassConsts.NullPassCountValue; break; } } else { _assignmentContext.FilteredValue.FilteredPassData = _currentPass; _haveFilteredPass = true; _assignmentContext.FilteredValue.PassCount = CellPassConsts.NullPassCountValue; break; } } } else { // check for min elevation mode var internalMachineIndex = _currentPass.FilteredPass.InternalSiteModelMachineIndex; var machine = _siteModel.Machines[internalMachineIndex]; var machineIsAnExcavator = machine.MachineType == MachineType.Excavator; var mappingMode = _siteModel.MachinesTargetValues[internalMachineIndex].ElevationMappingModeStateEvents.GetValueAtDate(_currentPass.FilteredPass.Time, out _, ElevationMappingMode.LatestElevation); var minimumElevationMappingModeAtCellPassTime = mappingMode == ElevationMappingMode.MinimumElevation; if (machineIsAnExcavator && minimumElevationMappingModeAtCellPassTime) { if (!_firstPassMinElev) { _firstPassMinElev = true; _haveFilteredPass = true; _tempPass = _currentPass; } else if (_currentPass.FilteredPass.Height < _tempPass.FilteredPass.Height) { _tempPass = _currentPass; // take if lowest pass } } else { // All criteria have been met for acceptance of this pass _assignmentContext.FilteredValue.FilteredPassData = _currentPass; _haveFilteredPass = true; _assignmentContext.FilteredValue.PassCount = CellPassConsts.NullPassCountValue; break; } } } } }
/// <summary> /// Special version of ProcessCellPasses when using a pass count range Filter. /// Performs primary filtered iteration over cell passes in the cell being processed to determine the cell pass /// to be selected. /// </summary> private void ProcessCellPassesPassCountRange() { _haveFilteredPass = false; var haveHalfPass = false; var passRangeCount = 0; int idxPtr; var arrayLength = 1000; var filteredPassDataArray = new FilteredPassData[arrayLength]; var filteredPassBoolArray = new bool[arrayLength]; var passes = 0; var validPasses = 0; var minElevCheckRequired = false; _firstPassMinElev = false; while (_cellPassIterator.MayHaveMoreFilterableCellPasses() && _cellPassIterator.GetNextCellPass(ref _currentPass.FilteredPass)) { FiltersValuePopulation.PopulateFilteredValues(_siteModel.MachinesTargetValues[_currentPass.FilteredPass.InternalSiteModelMachineIndex], _populationControl, ref _currentPass); if (_filter.AttributeFilter.FilterPass(ref _currentPass, _filterAnnex)) { if (_gridDataType == GridDataType.Temperature) { // make sure we have a valid temperature pass var materialTemperature = _currentPass.FilteredPass.MaterialTemperature; if (materialTemperature != CellPassConsts.NullMaterialTemperatureValue) { if (_filter.AttributeFilter.HasTemperatureRangeFilter) { if (Range.InRange(materialTemperature, _filter.AttributeFilter.MaterialTemperatureMin, _filter.AttributeFilter.MaterialTemperatureMax)) { _assignmentContext.FilteredValue.FilteredPassData = _currentPass; _haveFilteredPass = true; _assignmentContext.FilteredValue.PassCount = CellPassConsts.NullPassCountValue; } } } else { _assignmentContext.FilteredValue.FilteredPassData = _currentPass; _haveFilteredPass = true; _assignmentContext.FilteredValue.PassCount = CellPassConsts.NullPassCountValue; } } else { _assignmentContext.FilteredValue.FilteredPassData = _currentPass; _haveFilteredPass = true; _assignmentContext.FilteredValue.PassCount = CellPassConsts.NullPassCountValue; } } // Add valid pass to list for pass count range filter if (_haveFilteredPass) { filteredPassDataArray[passes] = _currentPass; passes++; if (passes == arrayLength - 1) { arrayLength = arrayLength + 500; Array.Resize(ref filteredPassDataArray, arrayLength); Array.Resize(ref filteredPassBoolArray, arrayLength); } _haveFilteredPass = false; // reset } } // end while more passes _haveFilteredPass = false; // reset for next test // For pass count range filtering we must walk from earliest to latest // setup idxPtr to walk forward in time if (_cellPassIterator.SegmentIterator.IterationDirection == IterationDirection.Forwards) { idxPtr = 0; } else { idxPtr = passes - 1; // last entry is earliest } if (passes > 0) { for (var i = 0; i < passes; i++) { if (i > 0) { if (_cellPassIterator.SegmentIterator.IterationDirection == IterationDirection.Forwards) { idxPtr++; } else { idxPtr--; } } _currentPass = filteredPassDataArray[idxPtr]; if (_currentPass.FilteredPass.HalfPass) { if (haveHalfPass) { passRangeCount++; // increase count on second half pass encountered } else { haveHalfPass = true; continue; // wont be using first half pass } haveHalfPass = false; } else { passRangeCount++; // increase count for a full pass } if (Range.InRange(passRangeCount, _filter.AttributeFilter.PassCountRangeMin, _filter.AttributeFilter.PassCountRangeMax)) { filteredPassBoolArray[idxPtr] = true; // tagged for minElev check if (_filter.AttributeFilter.HasElevationTypeFilter) { _assignmentContext.FilteredValue.PassCount = 1; } else { validPasses++; _assignmentContext.FilteredValue.PassCount = validPasses; } if ((_filter.AttributeFilter.HasElevationMappingModeFilter && _filter.AttributeFilter.ElevationMappingMode == ElevationMappingMode.MinimumElevation) || (_filter.AttributeFilter.HasElevationTypeFilter && _filter.AttributeFilter.ElevationType == ElevationType.Lowest)) { if (!_haveFilteredPass || _currentPass.FilteredPass.Height < _tempPass.FilteredPass.Height) { _tempPass = _currentPass; } _haveFilteredPass = true; } else if (_filter.AttributeFilter.HasElevationTypeFilter && _filter.AttributeFilter.ElevationType == ElevationType.Highest) { if (!_haveFilteredPass || _currentPass.FilteredPass.Height > _tempPass.FilteredPass.Height) { _tempPass = _currentPass; } _haveFilteredPass = true; } else { // are we only interested in first pass if (_filter.AttributeFilter.HasElevationTypeFilter && _filter.AttributeFilter.ElevationType == ElevationType.First) { _assignmentContext.FilteredValue.FilteredPassData = _currentPass; _haveFilteredPass = true; _assignmentContext.FilteredValue.PassCount = CellPassConsts.NullPassCountValue; break; // we are out of here } if (!minElevCheckRequired) { minElevCheckRequired = true; // means we need to do an extra check below for minElevation on chosen last pass } if (!_haveFilteredPass) { _haveFilteredPass = true; } _tempPass = _currentPass; // good pass. Last one assigned will be latest } } // end in range if (passRangeCount == _filter.AttributeFilter.PassCountRangeMax) { break; // we are out of here } } // end pass loop if (minElevCheckRequired) { // If minElevCheckRequired we now have a known list of good passes to determine the lowest pass // Rule states we walk in direction of CellPassIterator and return lowest pass while mode is minElev // Walk through list that was constructed by CellPassIterator direction to get lowest pass _haveFilteredPass = false; for (var i = 0; i < passes; i++) { if (!filteredPassBoolArray[i]) { continue; } _currentPass = filteredPassDataArray[i]; // check for min elevation mode var internalMachineIndex = _currentPass.FilteredPass.InternalSiteModelMachineIndex; var machine = _siteModel.Machines[internalMachineIndex]; var machineIsAnExcavator = machine.MachineType == MachineType.Excavator; var mappingMode = _siteModel.MachinesTargetValues[internalMachineIndex].ElevationMappingModeStateEvents.GetValueAtDate(_currentPass.FilteredPass.Time, out _, ElevationMappingMode.LatestElevation); var minimumElevationMappingModeAtCellPassTime = mappingMode == ElevationMappingMode.MinimumElevation; if (machineIsAnExcavator && minimumElevationMappingModeAtCellPassTime) { if (!_firstPassMinElev) { _firstPassMinElev = true; // take first pass in list as lowest to begin with _tempPass = _currentPass; } else if (!_haveFilteredPass || (_currentPass.FilteredPass.Height < _tempPass.FilteredPass.Height)) { _tempPass = _currentPass; } if (!_haveFilteredPass) { _haveFilteredPass = true; } } else { if (_firstPassMinElev && _haveFilteredPass) // take last know lowest pass { break; } _assignmentContext.FilteredValue.FilteredPassData = _currentPass; _haveFilteredPass = true; _assignmentContext.FilteredValue.PassCount = CellPassConsts.NullPassCountValue; break; // we have the pass we need } } // end passes } // end min check required } // end passes > 0 }