/// <summary> /// Loads the data entry interface by type (grid or standard layout) /// </summary> /// <param name="tableName"></param> /// <param name="container"></param> /// <param name="controls"></param> private void LoadDataEntryControl(string tableName, Control container, IEnumerable <ICaisisInputControl> controls) { // @PatientId lookup FIX: don't use session patient var lkpControls = from lkp in controls.OfType <ICaisisLookupControl>() where (!string.IsNullOrEmpty(lkp.LookupCode) && lkp.LookupCode.Contains("@PatientId")) || (!string.IsNullOrEmpty(lkp.LookupDistinct) && lkp.LookupDistinct.Contains("@PatientId")) select lkp; foreach (var lkpControl in lkpControls) { lkpControl.LookupCode = string.Empty; lkpControl.LookupDistinct = string.Empty; } // build grid table bool isGrid = _dataEntryController.IsGridView(tableName); if (isGrid) { int blankRows = _dataEntryController.GetTotalBlankGridRows(tableName); int totalBlankRows = _dataEntryController.GetVisibleBlankGridRows(tableName); var tableFieldsMetadata = _dataEntryController.GetTableFieldsMetadata(tableName); GridDataEntry con = LoadControl("~/Core/DataEntryForms/DataEntryControls/GridDataEntry.ascx") as GridDataEntry; container.Controls.Add(con); con.BuildLayout(tableName, blankRows, totalBlankRows, tableFieldsMetadata); } // build column layout else { int colCount = _dataEntryController.GetNumDisplayColumns(tableName); var commonDataElements = _dataEntryController.GetCommonDataElements(tableName); ColumnDataEntry con = LoadControl("~/Core/DataEntryForms/DataEntryControls/ColumnDataEntry.ascx") as ColumnDataEntry; con.SetControlIcon = SetControlMetaData; con.BuildControl += new CaisisEventHandler(SetControlToolTip); container.Controls.Add(con); con.BuildLayout(controls, colCount, commonDataElements); } }
public static void BuildUniformGridGPU() { BuildTriangleList(); if (NumTris <= 0 || NumTris > MAX_TRIS) { Debug.LogError("Number of tris in scene not valid"); } //compute the number of grid cells (Wald et al. 2006) float k = 5; float V = SceneBounds.size.x * SceneBounds.size.y * SceneBounds.size.z; float m = Mathf.Pow(k * NumTris / V, 1f / 3f); int nx = Mathf.CeilToInt(SceneBounds.size.x * m); int ny = Mathf.CeilToInt(SceneBounds.size.y * m); int nz = Mathf.CeilToInt(SceneBounds.size.z * m); GridInfo = new UniformGridInfo(); GridInfo.size = SceneBounds.size; GridInfo.nx = (uint)nx; GridInfo.ny = (uint)ny; GridInfo.nz = (uint)nz; //DEBUG LOG Debug.Log("Number of Triangles: " + NumTris); Debug.Log("Number of grid cells: " + nx + " " + ny + " " + nz); //create a temporary buffer with foreach triangle the number of overlapped cells ComputeBuffer cells_overlapped = new ComputeBuffer(NumTris, 4); ComputeShader grid_build_cs = Resources.Load <ComputeShader>("UniformGridBuild"); int cells_counting_kernel = grid_build_cs.FindKernel("cells_counting"); int num_groups = Mathf.CeilToInt(NumTris / 32.0f); Vector4 grid_origin = new Vector4(SceneBounds.min.x, SceneBounds.min.y, SceneBounds.min.z, 0); Vector4 grid_size = new Vector4(nx / SceneBounds.size.x, ny / SceneBounds.size.y, nz / SceneBounds.size.z, 0); GridInfo.grid_origin = grid_origin; GridInfo.grid_size = grid_size; //bind shader data grid_build_cs.SetBuffer(cells_counting_kernel, "vertices_list", TrisVertexBuffer); grid_build_cs.SetBuffer(cells_counting_kernel, "cells_overlapped", cells_overlapped); grid_build_cs.SetVector("grid_origin", grid_origin); grid_build_cs.SetVector("grid_size", grid_size); grid_build_cs.SetInt("num_tris", NumTris); grid_build_cs.Dispatch(cells_counting_kernel, num_groups, 1, 1); //now with the number of overlapped cells by each triangle, with a prefix sum i get the start index in the indices list and the total number of indices //TODO: parallel prefix sum on the GPU would be better int[] num_overlapped = new int[NumTris]; cells_overlapped.GetData(num_overlapped); int[] summed = new int[NumTris + 1]; summed[0] = 0; for (int i = 1; i <= NumTris; ++i) { summed[i] = summed[i - 1] + num_overlapped[i - 1]; } //create the index buffer int num_pairs = summed[NumTris]; ComputeBuffer cell_tris_pair_buffer = new ComputeBuffer(num_pairs, 8); //8 byte for a pair of ints //upload the prefix sum result to the GPU ComputeBuffer prefix_sum_result = new ComputeBuffer(NumTris + 1, 4); prefix_sum_result.SetData(summed); //dispatch a compute kernel to find the overlapped cells int cells_overlapping_kernel = grid_build_cs.FindKernel("cells_overlapping"); grid_build_cs.SetBuffer(cells_overlapping_kernel, "vertices_list", TrisVertexBuffer); grid_build_cs.SetBuffer(cells_overlapping_kernel, "prefix_sum_result", prefix_sum_result); grid_build_cs.SetBuffer(cells_overlapping_kernel, "cell_tris_pair_buffer", cell_tris_pair_buffer); grid_build_cs.SetInt("num_cells_x", nx); grid_build_cs.SetInt("num_cells_y", ny); grid_build_cs.Dispatch(cells_overlapping_kernel, num_groups, 1, 1); //next sort the pairs by their cell ID //TODO: parallel radix sort on the gpu would be better TrisCellPair[] pairs = new TrisCellPair[num_pairs]; cell_tris_pair_buffer.GetData(pairs); System.Array.Sort <TrisCellPair>(pairs, (x, y) => x.cell_id.CompareTo(y.cell_id)); //create the index list. This is the sorted list of pairs <tris_id, cell_id> after removing the cell_id, so is a list with only tris_id uint[] index_list = new uint[num_pairs]; for (int i = 0; i < index_list.Length; ++i) { index_list[i] = pairs[i].tris_id; } if (IndexList != null) { IndexList.Dispose(); } IndexList = new ComputeBuffer(num_pairs, 4); IndexList.SetData(index_list); //create the grid data //TODO: again, a GPU implementation would be better if (GridData != null) { GridData.Dispose(); } GridData = new ComputeBuffer(nx * ny * nz, 8); GridDataEntry[] grid_data = new GridDataEntry[nx * ny * nz]; uint current_cell = pairs[0].cell_id; uint tris_count = 0; uint offset = 0; for (uint i = 0; i < num_pairs; ++i) { if (pairs[i].cell_id == current_cell) { tris_count++; } else { grid_data[current_cell] = new GridDataEntry(offset, tris_count); offset += tris_count; tris_count = 1; current_cell = pairs[i].cell_id; } } grid_data[current_cell] = new GridDataEntry(offset, tris_count); GridData.SetData(grid_data); cell_tris_pair_buffer.Dispose(); prefix_sum_result.Dispose(); cells_overlapped.Dispose(); Debug.Log("UNIFORM GRID BUILD COMPLETE"); }