private void LASReaderThread(string path, int pointskip, Action <Thread, Vector3[]> cb) { byte[] bytes = File.ReadAllBytes(path); LASHeader_1_2 header = LASHeaders.MarshalHeader(bytes, true); LASReaderThread(pointskip, cb, bytes, header); }
public static Vector3 GetFirstPoint(byte[] bytes, LASHeader_1_2 header) { bytes = bytes.Skip((int)header.OffsetToPointData).ToArray(); using (MemoryStream stream = new MemoryStream(bytes)) { using (BinaryReader reader = new BinaryReader(stream)) { byte[] point = reader.ReadBytes(header.PointDataRecordLength); int x = BitConverter.ToInt32(point, 0); int y = BitConverter.ToInt32(point, 4); int z = BitConverter.ToInt32(point, 8); //ushort R = BitConverter.ToUInt16(point, 28); //ushort G = BitConverter.ToUInt16(point, 30); //ushort B = BitConverter.ToUInt16(point, 32); Vector3 pos = new Vector3((float)((x * header.XScaleFactor) + (header.XOffset)), ((float)((y * header.YScaleFactor) + (header.YOffset))), ((float)((z * header.ZScaleFactor) + (header.ZOffset)))); return(pos); } } }
/// <summary> /// starts the conversion /// </summary> public void Convert() { for (int i = 0; i < _files.Length; i++) { byte[] bytes = File.ReadAllBytes(_files[i]); LASHeader_1_2 header = LASHeaders.MarshalHeader(bytes, true); if (!_merge) { Thread t = _pointReader.ReadLASPointsAsync(bytes, header); _separateQues.Add(t, new ConcurrentQueue <string>()); StartSeparateWriter(Path.Combine(_outputpath, _files[i].Split('/').Last() + ".pcache"), header, _pskip, t); } else { Thread t = _pointReader.ReadLASPointsAsync(bytes, header); _totalrecords += Mathf.FloorToInt((header.NumberOfPointRecords / (float)(1 + _pskip))); } } if (_merge) { StartMergeWriter(_totalrecords); } }
private void StartSeparateWriter(string outputpath, LASHeader_1_2 header, int pskip, Thread observe) { Thread t = new Thread(() => SingleWriterThread(outputpath, header, pskip, observe)); t.Start(); _progresses.Add(t, 0); }
/// <summary> /// Takes in the bytes of a .las file and the header, /// and proceeds to read the points. /// </summary> /// <param name="bytes">bytes of a .las-file</param> /// <param name="header">header of the .las file</param> /// <returns>the reader thread</returns> public Thread ReadLASPointsAsync(byte[] bytes, LASHeader_1_2 header) { Thread t = new Thread(() => { LASReaderThread(_pskip, _batchAction, bytes, header); ThreadFinished(Thread.CurrentThread); }); t.IsBackground = true; QueueThread(t); return(t); }
private void SingleWriterThread(string outputpath, LASHeader_1_2 header, int pskip, Thread observe) { using (StreamWriter writer = new StreamWriter(outputpath)) { int targetamount = Mathf.FloorToInt((float)header.NumberOfPointRecords / (1 + pskip) + 1); int written = 0; writer.WriteLine("pcache"); writer.WriteLine("format ascii 1.0"); writer.WriteLine("elements " + targetamount); writer.WriteLine("property float position.x"); writer.WriteLine("property float position.y"); writer.WriteLine("property float position.z"); writer.WriteLine("end_header"); while (true) { if (_separateQues[observe].TryDequeue(out string row)) { writer.WriteLine(row); if (written % 1000 == 0) { _progresses[Thread.CurrentThread] = (written / (float)targetamount); } written++; } else { Thread.Sleep(10); } if (_cancel || (!observe.IsAlive && !observe.ThreadState.HasFlag(ThreadState.Unstarted) && _separateQues[observe].Count == 0)) { break; } } _progresses[Thread.CurrentThread] = 1; } }
public void OnGUI() { scrollpos = EditorGUILayout.BeginScrollView(scrollpos); EditorGUILayout.LabelField("EXPERIMENTAL Editor to easily instantiate VFX Graphs from .las into the scene"); EditorGUILayout.LabelField("\n"); EditorGUILayout.LabelField(".las files in StreamingAssets:"); EditorGUILayout.PropertyField(filenamesprop, true); if (GUILayout.Button("Add file")) { string path = EditorUtility.OpenFilePanel("select .las file", "Assets/StreamingAssets", "las"); string[] filepath = path.Split('/'); filenames.Add(filepath[filepath.Length - 1]); } EditorGUILayout.LabelField("\n"); EditorGUILayout.LabelField("VisualEffect to be used:"); EditorGUILayout.LabelField("Requires two exposed properties in the graph"); EditorGUILayout.LabelField("1. _PositionMapArray (Texture2DArray)"); EditorGUILayout.LabelField("2. _Depth (int)"); EditorGUILayout.PropertyField(vfxgraphprop, true); EditorGUILayout.LabelField("\n"); EditorGUILayout.LabelField("Whether to merge all to one LASBinder or create separate"); EditorGUILayout.LabelField("(try to disable if precision of the graph becomes a problem)"); EditorGUILayout.PropertyField(mergeFilesprop, true); EditorGUILayout.LabelField("\n"); EditorGUILayout.LabelField("Amount of points to skip in between readings:"); EditorGUILayout.PropertyField(pointskipprop, true); EditorGUILayout.LabelField("\n"); EditorGUILayout.LabelField("Whether to center the first point to zero and use it as origin:"); EditorGUILayout.PropertyField(anchortofirstpointprop, true); pointskipprop.intValue = Mathf.Clamp(pointskipprop.intValue, 0, 10000); if (GUILayout.Button("Add to selected gameobject")) { byte[] bytes = File.ReadAllBytes(Path.Combine(Application.streamingAssetsPath, filenames[0])); LASHeader_1_2 firstfileheader = LASHeaders.MarshalHeader(bytes, true); anchor = LASPointReader.GetFirstPoint(bytes, firstfileheader); if (Selection.transforms != null && Selection.transforms.Length > 0) { parent = Selection.transforms[0]; } if (!mergefiles) { generated = 0; EditorApplication.update += FrameByFrameNewGraph; } else { NewGraph(filenames, parent, anchor); } } EditorGUILayout.LabelField("\n"); EditorGUILayout.EndScrollView(); so.ApplyModifiedProperties(); so.Update(); }
private void LASReaderThread(int pointskip, Action <Thread, Vector3[]> cb, byte[] bytes, LASHeader_1_2 header) { bytes = bytes.Skip((int)header.OffsetToPointData).ToArray(); List <Vector3> vertices = new List <Vector3>(); using (MemoryStream stream = new MemoryStream(bytes)) { using (BinaryReader reader = new BinaryReader(stream)) { for (int i = 0; i < header.NumberOfPointRecords; i++) { byte[] point = reader.ReadBytes(header.PointDataRecordLength); if (i % (1 + pointskip) != 0) { continue; } int x = BitConverter.ToInt32(point, 0); int y = BitConverter.ToInt32(point, 4); int z = BitConverter.ToInt32(point, 8); //ushort R = BitConverter.ToUInt16(point, 28); //ushort G = BitConverter.ToUInt16(point, 30); //ushort B = BitConverter.ToUInt16(point, 32); Vector3 pos = new Vector3((float)((x * header.XScaleFactor) + (header.XOffset)), ((float)((y * header.YScaleFactor) + (header.YOffset))), ((float)((z * header.ZScaleFactor) + (header.ZOffset)))); vertices.Add(pos); if (vertices.Count > THREAD_NOTIFY_AMOUNT) { cb.Invoke(Thread.CurrentThread, vertices.ToArray()); vertices.Clear(); } if (_cancel) { break; } } } cb.Invoke(Thread.CurrentThread, vertices.ToArray()); } }