/// <summary> /// Compute Octree for a Polyhedron /// </summary> /// <param name="elementID"></param> /// <param name="polyH"></param> /// <param name="forUserDict"></param> public void ComputeOctree(string elementID, Polyhedron polyH, bool forUserDict) { // Make sure ElementID string is 22 character long for correct encoding/decoding if (elementID.Length < 22) { elementID = elementID.PadLeft(22, '0'); } ElementID eidNo = new ElementID(elementID); Tuple <UInt64, UInt64> elementIDNo = eidNo.ElementIDNo; OctreeNode theTree = new OctreeNode(); // Do it in steps: // 1. Find the smallest containing cell based on the PolyH BB, it it to quickly eliminate the irrelevant cells very quickly theTree.nodeCellID = OctreeNodeProcess.getSmallestContainingCell(polyH); theTree._depth = theTree.nodeCellID.Level; // 2. Perform subdivision using the BB first: quick division since there is no expensive intersection. It leaves all the leaves based on BB OctreeNodeProcess.ProcessBB(theTree, polyH.boundingBox); // 3. Evaluate each leaf nodes for further subdivision using the actual polyhedron (the original algorithm) OctreeNodeProcess.Process(theTree, polyH); List <CellID64> collCellID; List <int> collBorderFlag; OctreeNodeProcess.collectCellIDs(theTree, out collCellID, out collBorderFlag); for (int i = 0; i < collCellID.Count; ++i) { if (forUserDict) { insertDataToUserDict(elementIDNo, collCellID[i], collBorderFlag[i], false); } else { //insertDataToDictDB(elementID, collCellID[i]); insertDataToDict(elementIDNo, collCellID[i]); } } }
public static void regenSpatialIndexDict(int fedID, OctreeDict regenSpIndexTree) { BIMRLCommon refBIMRLCommon = new BIMRLCommon(); string sqlStmt = "SELECT ELEMENTID, CELLID FROM " + DBOperation.formatTabName("BIMRL_SPATIALINDEX", fedID); try { OracleCommand cmd = new OracleCommand(sqlStmt, DBOperation.DBConn); cmd.FetchSize = 100000; OracleDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { string elementid = reader.GetString(0); ElementID eID = new ElementID(elementid); string cellid = reader.GetString(1); CellID64 cell = new CellID64(cellid); SortedSet <int> cData = new SortedSet <int>(); cData.Add(getIndexForElementID(eID.ElementIDNo)); // the flag is no longer used, any value doesn't matter CellData data = new CellData { nodeType = 1, data = cData }; regenSpIndexTree.AddOrUpdate(cell.iCellID, data); } reader.Dispose(); cmd.Dispose(); } catch (OracleException e) { string excStr = "%%Read Error - " + e.Message + "\n\t" + sqlStmt; refBIMRLCommon.StackPushError(excStr); } catch (SystemException e) { string excStr = "%%Read Error - " + e.Message + "\n\t" + sqlStmt; refBIMRLCommon.StackPushError(excStr); throw; } }
/// <summary> /// Compute Octree for a Line Segment /// </summary> /// <param name="elementID"></param> /// <param name="lineS"></param> /// <param name="forUserDict"></param> public void ComputeOctree(string elementID, LineSegment3D lineS, bool forUserDict) { // Make sure ElementID string is 22 character long for correct encoding/decoding if (elementID.Length < 22) { elementID = elementID.PadLeft(22, '0'); } ElementID eidNo = new ElementID(elementID); Tuple <UInt64, UInt64> elementIDNo = eidNo.ElementIDNo; OctreeNode theTree = new OctreeNode(); // Add a step: // 1. Find the smallest containing cell based on the Face BB, it it to quickly eliminate the irrelevant cells very quickly theTree.nodeCellID = OctreeNodeProcess.getSmallestContainingCell(lineS); theTree._depth = theTree.nodeCellID.Level; OctreeNodeProcess.Process(theTree, lineS); List <CellID64> collCellID; List <int> collBorderFlag; OctreeNodeProcess.collectCellIDs(theTree, out collCellID, out collBorderFlag); for (int i = 0; i < collCellID.Count; ++i) { if (forUserDict) { insertDataToUserDict(elementIDNo, collCellID[i], collBorderFlag[i], false); } else { //insertDataToDictDB(elementID, collCellID[i]); insertDataToDict(elementIDNo, collCellID[i]); } } }
/// <summary> /// Collect ALL the cellids from userDict for populating transient geometry(ies) /// </summary> /// <param name="elementIDList"></param> /// <param name="cellIDStrList"></param> /// <param name="borderFlagList"></param> public void collectSpatialIndexUserDict(out List <string> elementIDList, out List <string> cellIDStrList, out List <int> XMinB, out List <int> YMinB, out List <int> ZMinB, out List <int> XMaxB, out List <int> YMaxB, out List <int> ZMaxB, out List <int> depthList, out List <int> cellType) { int initArraySize = 50000; elementIDList = new List <string>(initArraySize); cellIDStrList = new List <string>(initArraySize); cellType = new List <int>(initArraySize); XMinB = new List <int>(initArraySize); YMinB = new List <int>(initArraySize); ZMinB = new List <int>(initArraySize); XMaxB = new List <int>(initArraySize); YMaxB = new List <int>(initArraySize); ZMaxB = new List <int>(initArraySize); depthList = new List <int>(initArraySize); int XMin; int YMin; int ZMin; int XMax; int YMax; int ZMax; foreach (KeyValuePair <UInt64, CellData> dictEntry in userDict) { CellID64 cellID = new CellID64(dictEntry.Key); if (dictEntry.Value.data != null) { foreach (int tupEID in dictEntry.Value.data) { ElementID eID = new ElementID(getElementIDByIndex(tupEID)); // For UserGeom, the ID i s generated from string of a simple number padded left with '0'. Now we need to remove them int end0Pos = 0; for (int i = 0; i < eID.ElementIDString.Length; ++i) { if (eID.ElementIDString[i] != '0') { end0Pos = i; break; } } string userGeomID = eID.ElementIDString.Remove(0, end0Pos); elementIDList.Add(userGeomID); cellIDStrList.Add(cellID.ToString()); // cellType.Add(eID.Value); cellType.Add(dictEntry.Value.nodeType); CellID64.getCellIDComponents(cellID, out XMin, out YMin, out ZMin, out XMax, out YMax, out ZMax); XMinB.Add(XMin); YMinB.Add(YMin); ZMinB.Add(ZMin); XMaxB.Add(XMax); YMaxB.Add(YMax); ZMaxB.Add(ZMax); depthList.Add(CellID64.getLevel(cellID)); } } } }