public float?GetAverageHeightFromNeighbourhood(int pKernelSizeMultiplier) { int pKernelSize = CGroundArray.GetKernelSize(); pKernelSize *= pKernelSizeMultiplier; int defined = 0; float heightSum = 0; for (int x = -pKernelSize; x < pKernelSize; x++) { for (int y = -pKernelSize; y < pKernelSize; y++) { int xIndex = indexInField.Item1 + x; int yIndex = indexInField.Item2 + y; CField el = GetFieldWithOffset(x, y); if (el != null && el.IsDefined()) { defined++; heightSum += (float)el.GetHeight(); } } } if (defined == 0) { return(null); } return(heightSum / defined); }
public void ReInit() { lowestHeight = int.MaxValue; highestHeight = int.MinValue; groundArray = null; unassigned.Clear(); ground.Clear(); vege.Clear(); building.Clear(); InitArrays(); }
/// <summary> /// Create a bitmap big enough to store all results together /// Warning: can be inited only after main header is set /// </summary> public static void Init() { if (!exportBitmap) { return; } float mainArrayWidth = CProjectData.mainHeader.Width; float mainArrayHeight = CProjectData.mainHeader.Height; mainMapStepSize = CGroundArray.GetStepSizeForWidth(MAIN_WIDTH, mainArrayWidth); mainMap = new Bitmap((int)(mainArrayWidth / mainMapStepSize), (int)(mainArrayHeight / mainMapStepSize)); }
/// <summary> /// Transforms given point from world coordinates to index in main bitmap /// </summary> private static Tuple <int, int> GetIndexInMainBitmap(Vector3 pPoint) { Tuple <int, int> posInMain = CGroundArray.GetIndexInArray( pPoint, CProjectData.mainHeader.TopLeftCorner, mainMapStepSize); //todo: error posInMain is OOB CUtils.TransformArrayIndexToBitmapIndex(ref posInMain, CProjectData.mainHeader, mainMapStepSize, mainMap); if (!CUtils.IsInBitmap(posInMain, mainMap)) { CDebug.Error($"cant write to bitmap {posInMain.Item1}, {posInMain.Item2}"); return(null); } return(posInMain); }
//TODO: not practical since it can only return CField and the caller // has to cast it to more specific type. Find out more general approach? //public CField GetFieldContaining(EArray pClass, bool pNormal, Vector3 pPoint) //{ // switch(pClass) // { // case EArray.Ground: // if(!pNormal) // break; // return groundArray.GetFieldContainingPoint(pPoint); // case EArray.Vege: // if(pNormal) // break; // return vegeDetailArray.GetFieldContainingPoint(pPoint); // case EArray.Tree: // return pNormal ? // treeNormalArray.GetFieldContainingPoint(pPoint) : // treeDetailArray.GetFieldContainingPoint(pPoint); // } // CDebug.Error($"GetFieldContaining() for class {pClass} - {pNormal} not defined"); // return null; //} private void InitArrays() { unassignedArray = new CUnassignedArray(NORMAL_STEP, false); ballArray = new CBallArray(NORMAL_STEP, false); ballDetailArray = new CBallArray(DETAIL_STEP_BALLS, true); groundArray = new CGroundArray(NORMAL_STEP, false); buildingArray = new CVegeArray(NORMAL_STEP, false); vegeArray = new CVegeArray(NORMAL_STEP, false); vegeDetailArray = new CVegeArray(DETAIL_STEP, true); preprocessDetailArray = new CVegeArray(DETAIL_STEP, true); preprocessNormalArray = new CVegeArray(NORMAL_STEP, false); treeDetailArray = new CTreeArray(DETAIL_STEP, true); treeNormalArray = new CTreeArray(NORMAL_STEP, false); CObjPartition.Init(); }
/// <summary> /// Sets SmoothHeight based on average from neighbourhood /// </summary> public void CalculateSmoothHeight(double[,] pGaussKernel) { if (!IsDefined()) { return; } //int defined = 0; float heightSum = 0; float midHeight = (float)GetHeight(); int kernelSize = CGroundArray.GetKernelSize(); float gaussWeightSum = 0; for (int x = 0; x < kernelSize; x++) { for (int y = 0; y < kernelSize; y++) { int xIndex = indexInField.Item1 + x - kernelSize / 2; int yIndex = indexInField.Item2 + y - kernelSize / 2; CField el = CProjectData.Points.groundArray.GetField(xIndex, yIndex); float? elHeight = el?.GetHeight(); //if element is not defined, use height from the middle element float definedHeight = midHeight; if (elHeight != null) { definedHeight = (float)elHeight; } float gaussWeight = (float)pGaussKernel[x, y]; gaussWeightSum += gaussWeight; heightSum += definedHeight * gaussWeight; } } SmoothHeight = heightSum; }
public static Obj ExportToObj(string pArrayName, EExportStrategy pStrategy, bool pUseSmoothHeight, Tuple <int, int> pStartIndex, Tuple <int, int> pEndIndex) { CGroundArray pArray = CProjectData.Points.groundArray; Obj obj = new Obj(pArrayName); float minHeight = CProjectData.GetMinHeight(); int missingCoordCount = 0; int xStart = pStartIndex.Item1; int yStart = pStartIndex.Item2; int xEnd = pEndIndex.Item1 + 1; int yEnd = pEndIndex.Item2 + 1; xEnd = Math.Min(xEnd, pArray.arrayXRange); yEnd = Math.Min(yEnd, pArray.arrayYRange); //prepare vertices for (int x = xStart; x < xEnd; x++) { for (int y = yStart; y < yEnd; y++) { Vertex v = new Vertex(); CGroundField el = pArray.GetField(x, y); float? height = el.GetHeight(pUseSmoothHeight ? CField.EHeight.Smooth : CField.EHeight.MaxZ); height = GetHeight(pStrategy, y, el, height); //create vertex only if height is defined if (height != null) { //TODO: ATTENTION! in OBJ the height value = Y, while in LAS format it is Z and X,Y are space coordinates //move heights so the lowest point touches the 0 //if (pHeight != EHeight.Tree) { height -= minHeight; } v.LoadFromStringArray(new[] { "v", pArray.GetFieldXCoord(x).ToString(), height.ToString(), pArray.GetFieldYCoord(y).ToString() }); obj.AddVertex(v); //record the index of vertex associated with this field position el.VertexIndex = obj.VertexList.Count; //first index = 1 (not 0)! } else { missingCoordCount++; } } } int faceCount = 0; //generate faces for (int x = xStart; x < xEnd - 1; x++) { for (int y = yStart; y < yEnd - 1; y++) { //create face only if all necessary vertices has been defined. -1 = not defined //| /| 3:[0,1] 2:[1,1] //|/ | 1:[0,0] 4:[1,0] //we create 2 faces: (1,2,3) and (1,2,4) int ind1 = pArray.GetField(x, y).VertexIndex; if (ind1 != -1) { int ind2 = pArray.GetField(x + 1, y + 1).VertexIndex; if (ind2 != -1) { int ind3 = pArray.GetField(x, y + 1).VertexIndex; if (ind3 != -1) { Face f = new Face(); f.LoadFromStringArray(new[] { "f", ind1.ToString(), ind2.ToString(), ind3.ToString() //ind1+"//"+ind3, ind3+"//"+ind2, ind2+"//"+ind1 }); obj.FaceList.Add(f); faceCount++; } int ind4 = pArray.GetField(x + 1, y).VertexIndex; if (ind4 != -1) { Face f = new Face(); f.LoadFromStringArray(new[] { "f", ind1.ToString(), ind4.ToString(), ind2.ToString() }); obj.FaceList.Add(f); } } } } } return(obj); }