mirror of
https://github.com/storytold/LiveScan3D.git
synced 2026-10-09 00:09:58 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
</configuration>
|
||||
@@ -0,0 +1,429 @@
|
||||
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
|
||||
// License: MIT Software License See LICENSE.txt for the full license.
|
||||
|
||||
// If you use this software in your research, then please use the following citation:
|
||||
|
||||
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
|
||||
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
|
||||
|
||||
// @INPROCEEDINGS{Kowalski15,
|
||||
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
|
||||
// booktitle={3D Vision (3DV), 2015 International Conference on},
|
||||
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
|
||||
// year={2015},
|
||||
// }
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace KinectServer
|
||||
{
|
||||
public delegate void SocketListChangedHandler(List<KinectSocket> list);
|
||||
public class KinectServer
|
||||
{
|
||||
Socket oServerSocket;
|
||||
|
||||
bool bServerRunning = false;
|
||||
|
||||
KinectSettings oSettings;
|
||||
object oClientSocketLock = new object();
|
||||
object oFrameRequestLock = new object();
|
||||
|
||||
List<KinectSocket> lClientSockets = new List<KinectSocket>();
|
||||
|
||||
public event SocketListChangedHandler eSocketListChanged;
|
||||
|
||||
public int nClientCount
|
||||
{
|
||||
get
|
||||
{
|
||||
int nClients;
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
nClients = lClientSockets.Count;
|
||||
}
|
||||
return nClients;
|
||||
}
|
||||
}
|
||||
|
||||
public List<AffineTransform> lCameraPoses
|
||||
{
|
||||
get
|
||||
{
|
||||
List<AffineTransform> cameraPoses = new List<AffineTransform>();
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
cameraPoses.Add(lClientSockets[i].oCameraPose);
|
||||
}
|
||||
}
|
||||
return cameraPoses;
|
||||
}
|
||||
}
|
||||
|
||||
public List<AffineTransform> lWorldTransforms
|
||||
{
|
||||
get
|
||||
{
|
||||
List<AffineTransform> worldTransforms = new List<AffineTransform>();
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
worldTransforms.Add(lClientSockets[i].oWorldTransform);
|
||||
}
|
||||
}
|
||||
return worldTransforms;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
lClientSockets[i].oWorldTransform = value[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool bAllCalibrated
|
||||
{
|
||||
get
|
||||
{
|
||||
bool allCalibrated = true;
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
if (!lClientSockets[i].bCalibrated)
|
||||
{
|
||||
allCalibrated = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return allCalibrated;
|
||||
}
|
||||
}
|
||||
|
||||
public KinectServer(KinectSettings settings)
|
||||
{
|
||||
this.oSettings = settings;
|
||||
}
|
||||
|
||||
private void SocketListChanged()
|
||||
{
|
||||
if (eSocketListChanged != null)
|
||||
{
|
||||
eSocketListChanged(lClientSockets);
|
||||
}
|
||||
}
|
||||
|
||||
public void StartServer()
|
||||
{
|
||||
if (!bServerRunning)
|
||||
{
|
||||
oServerSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
||||
oServerSocket.Blocking = false;
|
||||
|
||||
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 48001);
|
||||
oServerSocket.Bind(endPoint);
|
||||
oServerSocket.Listen(10);
|
||||
|
||||
bServerRunning = true;
|
||||
Thread listeningThread = new Thread(this.ListeningWorker);
|
||||
listeningThread.Start();
|
||||
Thread receivingThread = new Thread(this.ReceivingWorker);
|
||||
receivingThread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopServer()
|
||||
{
|
||||
if (bServerRunning)
|
||||
{
|
||||
bServerRunning = false;
|
||||
|
||||
oServerSocket.Close();
|
||||
lock (oClientSocketLock)
|
||||
lClientSockets.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void CaptureSynchronizedFrame()
|
||||
{
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
lClientSockets[i].CaptureFrame();
|
||||
}
|
||||
|
||||
//Wait till frames captured
|
||||
bool allGathered = false;
|
||||
while (!allGathered)
|
||||
{
|
||||
allGathered = true;
|
||||
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
if (!lClientSockets[i].bFrameCaptured)
|
||||
{
|
||||
allGathered = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Calibrate()
|
||||
{
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
lClientSockets[i].Calibrate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SendSettings()
|
||||
{
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
lClientSockets[i].SendSettings(oSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SendCalibrationData()
|
||||
{
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
lClientSockets[i].SendCalibrationData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void GetStoredFrame(List<List<byte>> lFramesRGB, List<List<Single>> lFramesVerts)
|
||||
{
|
||||
lFramesRGB.Clear();
|
||||
lFramesVerts.Clear();
|
||||
|
||||
lock (oFrameRequestLock)
|
||||
{
|
||||
//Request frames
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
lClientSockets[i].RequestStoredFrame();
|
||||
}
|
||||
|
||||
//Wait till frames received
|
||||
bool allGathered = false;
|
||||
while (!allGathered)
|
||||
{
|
||||
allGathered = true;
|
||||
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
if (!lClientSockets[i].bStoredFrameReceived)
|
||||
{
|
||||
allGathered = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Store received frames
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
lFramesRGB.Add(new List<byte>(lClientSockets[i].lFrameRGB));
|
||||
lFramesVerts.Add(new List<Single>(lClientSockets[i].lFrameVerts));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void GetLatestFrame(List<List<byte>> lFramesRGB, List<List<Single>> lFramesVerts)
|
||||
{
|
||||
lFramesRGB.Clear();
|
||||
lFramesVerts.Clear();
|
||||
|
||||
lock (oFrameRequestLock)
|
||||
{
|
||||
//Request frames
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
lClientSockets[i].RequestLastFrame();
|
||||
}
|
||||
|
||||
//Wait till frames received
|
||||
bool allGathered = false;
|
||||
while (!allGathered)
|
||||
{
|
||||
allGathered = true;
|
||||
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
if (!lClientSockets[i].bLatestFrameReceived)
|
||||
{
|
||||
allGathered = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Store received frames
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
lFramesRGB.Add(new List<byte>(lClientSockets[i].lFrameRGB));
|
||||
lFramesVerts.Add(new List<Single>(lClientSockets[i].lFrameVerts));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearStoredFrames()
|
||||
{
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
lClientSockets[i].ClearStoredFrames();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ListeningWorker()
|
||||
{
|
||||
while (bServerRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
Socket newClient = oServerSocket.Accept();
|
||||
|
||||
//we do not want to add new clients while a frame is being requested
|
||||
lock (oFrameRequestLock)
|
||||
{
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
lClientSockets.Add(new KinectSocket(newClient));
|
||||
lClientSockets[lClientSockets.Count - 1].SendSettings(oSettings);
|
||||
lClientSockets[lClientSockets.Count - 1].eChanged += new SocketChangedHandler(SocketListChanged);
|
||||
if (eSocketListChanged != null)
|
||||
{
|
||||
eSocketListChanged(lClientSockets);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
}
|
||||
System.Threading.Thread.Sleep(100);
|
||||
}
|
||||
|
||||
if (eSocketListChanged != null)
|
||||
{
|
||||
eSocketListChanged(lClientSockets);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReceivingWorker()
|
||||
{
|
||||
System.Timers.Timer checkConnectionTimer = new System.Timers.Timer();
|
||||
checkConnectionTimer.Interval = 1000;
|
||||
|
||||
checkConnectionTimer.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
if (!lClientSockets[i].SocketConnected())
|
||||
{
|
||||
lClientSockets.RemoveAt(i);
|
||||
if (eSocketListChanged != null)
|
||||
{
|
||||
eSocketListChanged(lClientSockets);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
checkConnectionTimer.Start();
|
||||
|
||||
while (bServerRunning)
|
||||
{
|
||||
lock (oClientSocketLock)
|
||||
{
|
||||
for (int i = 0; i < lClientSockets.Count; i++)
|
||||
{
|
||||
byte[] buffer = lClientSockets[i].Receive(1);
|
||||
|
||||
while (buffer.Length != 0)
|
||||
{
|
||||
if (buffer[0] == 0)
|
||||
{
|
||||
lClientSockets[i].bFrameCaptured = true;
|
||||
}
|
||||
else if (buffer[0] == 1)
|
||||
{
|
||||
lClientSockets[i].ReceiveCalibrationData();
|
||||
}
|
||||
//stored frame
|
||||
else if (buffer[0] == 2)
|
||||
{
|
||||
lClientSockets[i].ReceiveFrame();
|
||||
lClientSockets[i].bStoredFrameReceived = true;
|
||||
}
|
||||
//last frame
|
||||
else if (buffer[0] == 3)
|
||||
{
|
||||
lClientSockets[i].ReceiveFrame();
|
||||
lClientSockets[i].bLatestFrameReceived = true;
|
||||
}
|
||||
|
||||
buffer = lClientSockets[i].Receive(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
|
||||
checkConnectionTimer.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
|
||||
// License: MIT Software License See LICENSE.txt for the full license.
|
||||
|
||||
// If you use this software in your research, then please use the following citation:
|
||||
|
||||
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
|
||||
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
|
||||
|
||||
// @INPROCEEDINGS{Kowalski15,
|
||||
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
|
||||
// booktitle={3D Vision (3DV), 2015 International Conference on},
|
||||
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
|
||||
// year={2015},
|
||||
// }
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace KinectServer
|
||||
{
|
||||
[Serializable]
|
||||
public class KinectSettings
|
||||
{
|
||||
public float[] aMinBounds = new float[3];
|
||||
public float[] aMaxBounds = new float[3];
|
||||
|
||||
public bool bFilter = false;
|
||||
public int nFilterNeighbors = 10;
|
||||
public float fFilterThreshold = 0.1f;
|
||||
|
||||
public BindingList<MarkerPose> lMarkerPoses = new BindingList<MarkerPose>();
|
||||
|
||||
public int nNumICPIterations = 10;
|
||||
public int nMaxNumRefineIters = 10;
|
||||
public bool bMergeScansForSave = false;
|
||||
|
||||
public KinectSettings()
|
||||
{
|
||||
aMinBounds[0] = -5f;
|
||||
aMinBounds[1] = -5f;
|
||||
aMinBounds[2] = -5f;
|
||||
|
||||
aMaxBounds[0] = 5f;
|
||||
aMaxBounds[1] = 5f;
|
||||
aMaxBounds[2] = 5f;
|
||||
}
|
||||
|
||||
public List<byte> ToByteList()
|
||||
{
|
||||
List<byte> lData = new List<byte>();
|
||||
|
||||
byte[] bTemp = new byte[sizeof(float) * 3];
|
||||
|
||||
Buffer.BlockCopy(aMinBounds, 0, bTemp, 0, sizeof(float) * 3);
|
||||
lData.AddRange(bTemp);
|
||||
Buffer.BlockCopy(aMaxBounds, 0, bTemp, 0, sizeof(float) * 3);
|
||||
lData.AddRange(bTemp);
|
||||
|
||||
if (bFilter)
|
||||
lData.Add(1);
|
||||
else
|
||||
lData.Add(0);
|
||||
|
||||
bTemp = BitConverter.GetBytes(nFilterNeighbors);
|
||||
lData.AddRange(bTemp);
|
||||
|
||||
bTemp = BitConverter.GetBytes(fFilterThreshold);
|
||||
lData.AddRange(bTemp);
|
||||
|
||||
bTemp = BitConverter.GetBytes(lMarkerPoses.Count);
|
||||
lData.AddRange(bTemp);
|
||||
|
||||
for (int i = 0; i < lMarkerPoses.Count; i++)
|
||||
{
|
||||
bTemp = new byte[sizeof(float) * 9];
|
||||
Buffer.BlockCopy(lMarkerPoses[i].pose.R, 0, bTemp, 0, sizeof(float) * 9);
|
||||
lData.AddRange(bTemp);
|
||||
|
||||
bTemp = new byte[sizeof(float) * 3];
|
||||
Buffer.BlockCopy(lMarkerPoses[i].pose.t, 0, bTemp, 0, sizeof(float) * 3);
|
||||
lData.AddRange(bTemp);
|
||||
|
||||
bTemp = BitConverter.GetBytes(lMarkerPoses[i].id);
|
||||
lData.AddRange(bTemp);
|
||||
}
|
||||
|
||||
return lData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
|
||||
// License: MIT Software License See LICENSE.txt for the full license.
|
||||
|
||||
// If you use this software in your research, then please use the following citation:
|
||||
|
||||
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
|
||||
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
|
||||
|
||||
// @INPROCEEDINGS{Kowalski15,
|
||||
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
|
||||
// booktitle={3D Vision (3DV), 2015 International Conference on},
|
||||
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
|
||||
// year={2015},
|
||||
// }
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace KinectServer
|
||||
{
|
||||
public delegate void SocketChangedHandler();
|
||||
|
||||
public class KinectSocket
|
||||
{
|
||||
Socket oSocket;
|
||||
byte[] byteToSend = new byte[1];
|
||||
public bool bFrameCaptured = false;
|
||||
public bool bLatestFrameReceived = false;
|
||||
public bool bStoredFrameReceived = false;
|
||||
public bool bCalibrated = false;
|
||||
//The pose of the sensor in the scene (used by the OpenGLWindow to show the sensor)
|
||||
public AffineTransform oCameraPose = new AffineTransform();
|
||||
//The transform that maps the vertices in the sensor coordinate system to the world corrdinate system.
|
||||
public AffineTransform oWorldTransform = new AffineTransform();
|
||||
|
||||
public string sSocketState;
|
||||
|
||||
public List<byte> lFrameRGB = new List<byte>();
|
||||
public List<Single> lFrameVerts = new List<Single>();
|
||||
|
||||
public event SocketChangedHandler eChanged;
|
||||
|
||||
public KinectSocket(Socket clientSocket)
|
||||
{
|
||||
oSocket = clientSocket;
|
||||
sSocketState = oSocket.RemoteEndPoint.ToString() + " Calibrated = false";
|
||||
}
|
||||
|
||||
public void CaptureFrame()
|
||||
{
|
||||
bFrameCaptured = false;
|
||||
byteToSend[0] = 0;
|
||||
SendByte();
|
||||
}
|
||||
|
||||
public void Calibrate()
|
||||
{
|
||||
bCalibrated = false;
|
||||
sSocketState = oSocket.RemoteEndPoint.ToString() + " Calibrated = false";
|
||||
|
||||
byteToSend[0] = 1;
|
||||
SendByte();
|
||||
|
||||
UpdateSocketState();
|
||||
}
|
||||
|
||||
public void SendSettings(KinectSettings settings)
|
||||
{
|
||||
List<byte> lData = settings.ToByteList();
|
||||
|
||||
byte[] bTemp = BitConverter.GetBytes(lData.Count);
|
||||
lData.InsertRange(0, bTemp);
|
||||
lData.Insert(0, 2);
|
||||
|
||||
if (SocketConnected())
|
||||
oSocket.Send(lData.ToArray());
|
||||
}
|
||||
|
||||
public void RequestStoredFrame()
|
||||
{
|
||||
byteToSend[0] = 3;
|
||||
SendByte();
|
||||
bStoredFrameReceived = false;
|
||||
}
|
||||
|
||||
public void RequestLastFrame()
|
||||
{
|
||||
byteToSend[0] = 4;
|
||||
SendByte();
|
||||
bLatestFrameReceived = false;
|
||||
}
|
||||
|
||||
public void SendCalibrationData()
|
||||
{
|
||||
int size = 1 + 2 * (9 + 3) * sizeof(float);
|
||||
byte[] data = new byte[size];
|
||||
int i = 0;
|
||||
|
||||
data[i] = 5;
|
||||
i++;
|
||||
|
||||
Buffer.BlockCopy(oWorldTransform.R, 0, data, i, 9 * sizeof(float));
|
||||
i += 9 * sizeof(float);
|
||||
Buffer.BlockCopy(oWorldTransform.t, 0, data, i, 3 * sizeof(float));
|
||||
i += 3 * sizeof(float);
|
||||
|
||||
Buffer.BlockCopy(oCameraPose.R, 0, data, i, 9 * sizeof(float));
|
||||
i += 9 * sizeof(float);
|
||||
Buffer.BlockCopy(oCameraPose.t, 0, data, i, 3 * sizeof(float));
|
||||
i += 3 * sizeof(float);
|
||||
|
||||
|
||||
if (SocketConnected())
|
||||
oSocket.Send(data);
|
||||
}
|
||||
|
||||
public void ClearStoredFrames()
|
||||
{
|
||||
byteToSend[0] = 6;
|
||||
SendByte();
|
||||
}
|
||||
|
||||
public void ReceiveCalibrationData()
|
||||
{
|
||||
bCalibrated = true;
|
||||
|
||||
byte[] buffer = Receive(sizeof(int) * 1);
|
||||
//currently not used
|
||||
int markerId = BitConverter.ToInt32(buffer, 0);
|
||||
|
||||
buffer = Receive(sizeof(float) * 9);
|
||||
Buffer.BlockCopy(buffer, 0, oWorldTransform.R, 0, sizeof(float) * 9);
|
||||
|
||||
buffer = Receive(sizeof(float) * 3);
|
||||
Buffer.BlockCopy(buffer, 0, oWorldTransform.t, 0, sizeof(float) * 3);
|
||||
|
||||
buffer = Receive(sizeof(float) * 9);
|
||||
Buffer.BlockCopy(buffer, 0, oCameraPose.R, 0, sizeof(float) * 9);
|
||||
|
||||
buffer = Receive(sizeof(float) * 3);
|
||||
Buffer.BlockCopy(buffer, 0, oCameraPose.t, 0, sizeof(float) * 3);
|
||||
|
||||
UpdateSocketState();
|
||||
}
|
||||
|
||||
public void ReceiveFrame()
|
||||
{
|
||||
lFrameRGB.Clear();
|
||||
lFrameVerts.Clear();
|
||||
|
||||
int nToRead;
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
while (oSocket.Available == 0)
|
||||
{
|
||||
if (!SocketConnected())
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
oSocket.Receive(buffer, 4, SocketFlags.None);
|
||||
|
||||
//string result = System.Text.Encoding.UTF8.GetString(buffer);
|
||||
//n_to_read = Int32.Parse(result);
|
||||
|
||||
nToRead = BitConverter.ToInt32(buffer, 0);
|
||||
|
||||
if (nToRead == 0)
|
||||
return;
|
||||
|
||||
buffer = new byte[nToRead];
|
||||
int nAlreadyRead = 0;
|
||||
|
||||
while (nAlreadyRead != nToRead)
|
||||
{
|
||||
while (oSocket.Available == 0)
|
||||
{
|
||||
if (!SocketConnected())
|
||||
return;
|
||||
}
|
||||
|
||||
nAlreadyRead += oSocket.Receive(buffer, nAlreadyRead, nToRead - nAlreadyRead, SocketFlags.None);
|
||||
}
|
||||
|
||||
int point_size = 3 + 3 * 4;
|
||||
int n_vertices = nToRead / point_size;
|
||||
|
||||
for (int i = 0; i < n_vertices; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
lFrameRGB.Add(buffer[i * point_size + j]);
|
||||
lFrameVerts.Add(BitConverter.ToSingle(buffer, i * point_size + j * 4 + 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Receive(int nBytes)
|
||||
{
|
||||
byte[] buffer;
|
||||
if (oSocket.Available != 0)
|
||||
{
|
||||
buffer = new byte[Math.Min(nBytes, oSocket.Available)];
|
||||
oSocket.Receive(buffer, nBytes, SocketFlags.None);
|
||||
}
|
||||
else
|
||||
buffer = new byte[0];
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public bool SocketConnected()
|
||||
{
|
||||
bool part1 = oSocket.Poll(1000, SelectMode.SelectRead);
|
||||
bool part2 = (oSocket.Available == 0);
|
||||
|
||||
if (part1 && part2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void SendByte()
|
||||
{
|
||||
oSocket.Send(byteToSend);
|
||||
}
|
||||
|
||||
public void UpdateSocketState()
|
||||
{
|
||||
if (bCalibrated)
|
||||
sSocketState = oSocket.RemoteEndPoint.ToString() + " Calibrated = true";
|
||||
else
|
||||
sSocketState = oSocket.RemoteEndPoint.ToString() + " Calibrated = false";
|
||||
|
||||
if (eChanged != null)
|
||||
eChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{78422B2C-0EF1-4A28-A40E-2A7C4A9204B1}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>KinectServer</RootNamespace>
|
||||
<AssemblyName>LiveScanServer</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="OpenTK, Version=1.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL" />
|
||||
<Reference Include="OpenTK.Compatibility, Version=1.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL" />
|
||||
<Reference Include="OpenTK.GLControl, Version=1.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MainWindowForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainWindowForm.Designer.cs">
|
||||
<DependentUpon>MainWindowForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="KinectServer.cs" />
|
||||
<Compile Include="KinectSettings.cs" />
|
||||
<Compile Include="KinectSocket.cs" />
|
||||
<Compile Include="OpenGLWindow.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SettingsForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SettingsForm.Designer.cs">
|
||||
<DependentUpon>SettingsForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Utils.cs" />
|
||||
<EmbeddedResource Include="MainWindowForm.resx">
|
||||
<DependentUpon>MainWindowForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="SettingsForm.resx">
|
||||
<DependentUpon>SettingsForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
namespace KinectServer
|
||||
{
|
||||
partial class MainWindowForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.btStart = new System.Windows.Forms.Button();
|
||||
this.btCalibrate = new System.Windows.Forms.Button();
|
||||
this.btRecord = new System.Windows.Forms.Button();
|
||||
this.lClientListBox = new System.Windows.Forms.ListBox();
|
||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||
this.statusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.recordingWorker = new System.ComponentModel.BackgroundWorker();
|
||||
this.txtSeqName = new System.Windows.Forms.TextBox();
|
||||
this.btRefineCalib = new System.Windows.Forms.Button();
|
||||
this.OpenGLWorker = new System.ComponentModel.BackgroundWorker();
|
||||
this.savingWorker = new System.ComponentModel.BackgroundWorker();
|
||||
this.updateWorker = new System.ComponentModel.BackgroundWorker();
|
||||
this.btShowLive = new System.Windows.Forms.Button();
|
||||
this.btSettings = new System.Windows.Forms.Button();
|
||||
this.refineWorker = new System.ComponentModel.BackgroundWorker();
|
||||
this.lbSeqName = new System.Windows.Forms.Label();
|
||||
this.statusStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btStart
|
||||
//
|
||||
this.btStart.Location = new System.Drawing.Point(12, 12);
|
||||
this.btStart.Name = "btStart";
|
||||
this.btStart.Size = new System.Drawing.Size(95, 23);
|
||||
this.btStart.TabIndex = 0;
|
||||
this.btStart.Text = "Start server";
|
||||
this.btStart.UseVisualStyleBackColor = true;
|
||||
this.btStart.Click += new System.EventHandler(this.btStart_Click);
|
||||
//
|
||||
// btCalibrate
|
||||
//
|
||||
this.btCalibrate.Location = new System.Drawing.Point(12, 70);
|
||||
this.btCalibrate.Name = "btCalibrate";
|
||||
this.btCalibrate.Size = new System.Drawing.Size(95, 23);
|
||||
this.btCalibrate.TabIndex = 2;
|
||||
this.btCalibrate.Text = "Calibrate";
|
||||
this.btCalibrate.UseVisualStyleBackColor = true;
|
||||
this.btCalibrate.Click += new System.EventHandler(this.btCalibrate_Click);
|
||||
//
|
||||
// btRecord
|
||||
//
|
||||
this.btRecord.Location = new System.Drawing.Point(12, 126);
|
||||
this.btRecord.Name = "btRecord";
|
||||
this.btRecord.Size = new System.Drawing.Size(95, 23);
|
||||
this.btRecord.TabIndex = 4;
|
||||
this.btRecord.Text = "Start recording";
|
||||
this.btRecord.UseVisualStyleBackColor = true;
|
||||
this.btRecord.Click += new System.EventHandler(this.btRecord_Click);
|
||||
//
|
||||
// lClientListBox
|
||||
//
|
||||
this.lClientListBox.FormattingEnabled = true;
|
||||
this.lClientListBox.Location = new System.Drawing.Point(113, 12);
|
||||
this.lClientListBox.Name = "lClientListBox";
|
||||
this.lClientListBox.Size = new System.Drawing.Size(219, 108);
|
||||
this.lClientListBox.TabIndex = 5;
|
||||
//
|
||||
// statusStrip1
|
||||
//
|
||||
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.statusLabel});
|
||||
this.statusStrip1.Location = new System.Drawing.Point(0, 187);
|
||||
this.statusStrip1.Name = "statusStrip1";
|
||||
this.statusStrip1.Size = new System.Drawing.Size(344, 22);
|
||||
this.statusStrip1.TabIndex = 6;
|
||||
this.statusStrip1.Text = "statusStrip1";
|
||||
//
|
||||
// statusLabel
|
||||
//
|
||||
this.statusLabel.Name = "statusLabel";
|
||||
this.statusLabel.Size = new System.Drawing.Size(0, 17);
|
||||
//
|
||||
// recordingWorker
|
||||
//
|
||||
this.recordingWorker.WorkerSupportsCancellation = true;
|
||||
this.recordingWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.recordingWorker_DoWork);
|
||||
this.recordingWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.recordingWorker_RunWorkerCompleted);
|
||||
//
|
||||
// txtSeqName
|
||||
//
|
||||
this.txtSeqName.Location = new System.Drawing.Point(113, 155);
|
||||
this.txtSeqName.MaxLength = 40;
|
||||
this.txtSeqName.Name = "txtSeqName";
|
||||
this.txtSeqName.Size = new System.Drawing.Size(106, 20);
|
||||
this.txtSeqName.TabIndex = 7;
|
||||
this.txtSeqName.Text = "noname";
|
||||
//
|
||||
// btRefineCalib
|
||||
//
|
||||
this.btRefineCalib.Location = new System.Drawing.Point(12, 97);
|
||||
this.btRefineCalib.Name = "btRefineCalib";
|
||||
this.btRefineCalib.Size = new System.Drawing.Size(95, 23);
|
||||
this.btRefineCalib.TabIndex = 11;
|
||||
this.btRefineCalib.Text = "Refine calib";
|
||||
this.btRefineCalib.UseVisualStyleBackColor = true;
|
||||
this.btRefineCalib.Click += new System.EventHandler(this.btRefineCalib_Click);
|
||||
//
|
||||
// OpenGLWorker
|
||||
//
|
||||
this.OpenGLWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.OpenGLWorker_DoWork);
|
||||
this.OpenGLWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.OpenGLWorker_RunWorkerCompleted);
|
||||
//
|
||||
// savingWorker
|
||||
//
|
||||
this.savingWorker.WorkerSupportsCancellation = true;
|
||||
this.savingWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.savingWorker_DoWork);
|
||||
this.savingWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.savingWorker_RunWorkerCompleted);
|
||||
//
|
||||
// updateWorker
|
||||
//
|
||||
this.updateWorker.WorkerSupportsCancellation = true;
|
||||
this.updateWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.updateWorker_DoWork);
|
||||
//
|
||||
// btShowLive
|
||||
//
|
||||
this.btShowLive.Location = new System.Drawing.Point(12, 154);
|
||||
this.btShowLive.Name = "btShowLive";
|
||||
this.btShowLive.Size = new System.Drawing.Size(95, 23);
|
||||
this.btShowLive.TabIndex = 12;
|
||||
this.btShowLive.Text = "Show live";
|
||||
this.btShowLive.UseVisualStyleBackColor = true;
|
||||
this.btShowLive.Click += new System.EventHandler(this.btShowLive_Click);
|
||||
//
|
||||
// btSettings
|
||||
//
|
||||
this.btSettings.Location = new System.Drawing.Point(12, 41);
|
||||
this.btSettings.Name = "btSettings";
|
||||
this.btSettings.Size = new System.Drawing.Size(95, 23);
|
||||
this.btSettings.TabIndex = 13;
|
||||
this.btSettings.Text = "Settings";
|
||||
this.btSettings.UseVisualStyleBackColor = true;
|
||||
this.btSettings.Click += new System.EventHandler(this.btSettings_Click);
|
||||
//
|
||||
// refineWorker
|
||||
//
|
||||
this.refineWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.refineWorker_DoWork);
|
||||
this.refineWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.refineWorker_RunWorkerCompleted);
|
||||
//
|
||||
// lbSeqName
|
||||
//
|
||||
this.lbSeqName.AutoSize = true;
|
||||
this.lbSeqName.Location = new System.Drawing.Point(113, 136);
|
||||
this.lbSeqName.Name = "lbSeqName";
|
||||
this.lbSeqName.Size = new System.Drawing.Size(88, 13);
|
||||
this.lbSeqName.TabIndex = 14;
|
||||
this.lbSeqName.Text = "Sequence name:";
|
||||
//
|
||||
// MainWindowForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(344, 209);
|
||||
this.Controls.Add(this.lbSeqName);
|
||||
this.Controls.Add(this.btSettings);
|
||||
this.Controls.Add(this.btShowLive);
|
||||
this.Controls.Add(this.btRefineCalib);
|
||||
this.Controls.Add(this.txtSeqName);
|
||||
this.Controls.Add(this.statusStrip1);
|
||||
this.Controls.Add(this.lClientListBox);
|
||||
this.Controls.Add(this.btRecord);
|
||||
this.Controls.Add(this.btCalibrate);
|
||||
this.Controls.Add(this.btStart);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.Name = "MainWindowForm";
|
||||
this.Text = "LiveScanServer";
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
|
||||
this.statusStrip1.ResumeLayout(false);
|
||||
this.statusStrip1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button btStart;
|
||||
private System.Windows.Forms.Button btCalibrate;
|
||||
private System.Windows.Forms.Button btRecord;
|
||||
private System.Windows.Forms.ListBox lClientListBox;
|
||||
private System.Windows.Forms.StatusStrip statusStrip1;
|
||||
private System.ComponentModel.BackgroundWorker recordingWorker;
|
||||
private System.Windows.Forms.TextBox txtSeqName;
|
||||
private System.Windows.Forms.Button btRefineCalib;
|
||||
private System.ComponentModel.BackgroundWorker OpenGLWorker;
|
||||
private System.ComponentModel.BackgroundWorker savingWorker;
|
||||
private System.ComponentModel.BackgroundWorker updateWorker;
|
||||
private System.Windows.Forms.Button btShowLive;
|
||||
private System.Windows.Forms.Button btSettings;
|
||||
private System.ComponentModel.BackgroundWorker refineWorker;
|
||||
private System.Windows.Forms.ToolStripStatusLabel statusLabel;
|
||||
private System.Windows.Forms.Label lbSeqName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,524 @@
|
||||
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
|
||||
// License: MIT Software License See LICENSE.txt for the full license.
|
||||
|
||||
// If you use this software in your research, then please use the following citation:
|
||||
|
||||
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
|
||||
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
|
||||
|
||||
// @INPROCEEDINGS{Kowalski15,
|
||||
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
|
||||
// booktitle={3D Vision (3DV), 2015 International Conference on},
|
||||
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
|
||||
// year={2015},
|
||||
// }
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Timers;
|
||||
|
||||
|
||||
namespace KinectServer
|
||||
{
|
||||
public partial class MainWindowForm : Form
|
||||
{
|
||||
[DllImport("ICP.dll")]
|
||||
static extern float ICP(IntPtr verts1, IntPtr verts2, int nVerts1, int nVerts2, float[] R, float[] t, int maxIter = 200);
|
||||
|
||||
KinectServer oServer;
|
||||
|
||||
//Those three variables are shared with the OpenGLWindow class and are used to exchange data with it.
|
||||
//Vertices from all of the sensors
|
||||
List<float> lAllVertices = new List<float>();
|
||||
//Color data from all of the sensors
|
||||
List<byte> lAllColors = new List<byte>();
|
||||
//Sensor poses from all of the sensors
|
||||
List<AffineTransform> lAllCameraPoses = new List<AffineTransform>();
|
||||
|
||||
bool bServerRunning = false;
|
||||
bool bRecording = false;
|
||||
bool bSaving = false;
|
||||
|
||||
//Live view open or not
|
||||
bool bLiveViewRunning = false;
|
||||
|
||||
System.Timers.Timer oStatusBarTimer = new System.Timers.Timer();
|
||||
|
||||
KinectSettings oSettings = new KinectSettings();
|
||||
//The live view window class
|
||||
OpenGLWindow oOpenGLWindow;
|
||||
|
||||
public MainWindowForm()
|
||||
{
|
||||
//This tries to read the settings from "settings.bin", if it failes the settings stay at default values.
|
||||
try
|
||||
{
|
||||
IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
|
||||
Stream stream = new FileStream("settings.bin", FileMode.Open, FileAccess.Read);
|
||||
oSettings = (KinectSettings)formatter.Deserialize(stream);
|
||||
stream.Close();
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
}
|
||||
|
||||
oServer = new KinectServer(oSettings);
|
||||
oServer.eSocketListChanged += new SocketListChangedHandler(UpdateListView);
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
//The current settings are saved to a files.
|
||||
IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
|
||||
|
||||
Stream stream = new FileStream("settings.bin", FileMode.Create, FileAccess.Write);
|
||||
formatter.Serialize(stream, oSettings);
|
||||
stream.Close();
|
||||
|
||||
oServer.StopServer();
|
||||
}
|
||||
|
||||
//Starts the server
|
||||
private void btStart_Click(object sender, EventArgs e)
|
||||
{
|
||||
bServerRunning = !bServerRunning;
|
||||
|
||||
if (bServerRunning)
|
||||
{
|
||||
oServer.StartServer();
|
||||
btStart.Text = "Stop server";
|
||||
}
|
||||
else
|
||||
{
|
||||
oServer.StopServer();
|
||||
btStart.Text = "Start server";
|
||||
}
|
||||
}
|
||||
|
||||
//Opens the settings form
|
||||
private void btSettings_Click(object sender, EventArgs e)
|
||||
{
|
||||
SettingsForm form = new SettingsForm();
|
||||
form.oSettings = oSettings;
|
||||
form.oServer = oServer;
|
||||
form.Show();
|
||||
}
|
||||
|
||||
//Performs recording which is synchronized frame capture.
|
||||
//The frames are downloaded from the clients and saved once recording is finished.
|
||||
private void recordingWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
oServer.ClearStoredFrames();
|
||||
|
||||
int nCaptured = 0;
|
||||
BackgroundWorker worker = (BackgroundWorker)sender;
|
||||
while (!worker.CancellationPending)
|
||||
{
|
||||
oServer.CaptureSynchronizedFrame();
|
||||
|
||||
nCaptured++;
|
||||
SetStatusBarOnTimer("Captured frame " + (nCaptured).ToString() + ".", 5000);
|
||||
}
|
||||
}
|
||||
|
||||
private void recordingWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
//After recording has been terminated it is time to begin saving the frames.
|
||||
//Saving is downloading the frames from clients and saving them locally.
|
||||
bSaving = true;
|
||||
|
||||
btRecord.Text = "Stop saving";
|
||||
btRecord.Enabled = true;
|
||||
|
||||
savingWorker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
//Opens the live view window
|
||||
private void OpenGLWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
bLiveViewRunning = true;
|
||||
oOpenGLWindow = new OpenGLWindow();
|
||||
|
||||
//The variables below are shared between this class and the OpenGLWindow.
|
||||
lock (lAllVertices)
|
||||
{
|
||||
oOpenGLWindow.vertices = lAllVertices;
|
||||
oOpenGLWindow.colors = lAllColors;
|
||||
oOpenGLWindow.cameraPoses = lAllCameraPoses;
|
||||
oOpenGLWindow.settings = oSettings;
|
||||
}
|
||||
oOpenGLWindow.Run();
|
||||
}
|
||||
|
||||
private void OpenGLWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
bLiveViewRunning = false;
|
||||
updateWorker.CancelAsync();
|
||||
}
|
||||
|
||||
private void savingWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
int nFrames = 0;
|
||||
|
||||
string outDir = "out" + "\\" + txtSeqName.Text + "\\";
|
||||
DirectoryInfo di = Directory.CreateDirectory(outDir);
|
||||
|
||||
BackgroundWorker worker = (BackgroundWorker)sender;
|
||||
//This loop is running till it is either cancelled (using the btRecord button), or till there are no more stored frames.
|
||||
while (!worker.CancellationPending)
|
||||
{
|
||||
List<List<byte>> lFrameRGBAllDevices = new List<List<byte>>();
|
||||
List<List<float>> lFrameVertsAllDevices = new List<List<float>>();
|
||||
|
||||
oServer.GetStoredFrame(lFrameRGBAllDevices, lFrameVertsAllDevices);
|
||||
|
||||
nFrames++;
|
||||
int nVerticesTotal = 0;
|
||||
for (int i = 0; i < lFrameRGBAllDevices.Count; i++)
|
||||
{
|
||||
nVerticesTotal += lFrameVertsAllDevices[i].Count;
|
||||
}
|
||||
|
||||
//This indicates that there are no more stored frames.
|
||||
if (nVerticesTotal == 0)
|
||||
break;
|
||||
|
||||
List<byte> lFrameRGB = new List<byte>();
|
||||
List<Single> lFrameVerts = new List<Single>();
|
||||
|
||||
SetStatusBarOnTimer("Saving frame " + (nFrames).ToString() + ".", 5000);
|
||||
for (int i = 0; i < lFrameRGBAllDevices.Count; i++)
|
||||
{
|
||||
lFrameRGB.AddRange(lFrameRGBAllDevices[i]);
|
||||
lFrameVerts.AddRange(lFrameVertsAllDevices[i]);
|
||||
|
||||
//This is ran if the frames from each client are to be placed in separate files.
|
||||
if (!oSettings.bMergeScansForSave)
|
||||
{
|
||||
string outputFilename = outDir + "\\" + nFrames.ToString().PadLeft(5, '0') + i.ToString() + ".ply";
|
||||
saveToPly(outputFilename, lFrameVertsAllDevices[i], lFrameRGBAllDevices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//This is ran if the frames from all clients are to be placed in a single file.
|
||||
if (oSettings.bMergeScansForSave)
|
||||
{
|
||||
string outputFilename = outDir + "\\" + nFrames.ToString().PadLeft(5, '0') + ".ply";
|
||||
saveToPly(outputFilename, lFrameVerts, lFrameRGB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void savingWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
oServer.ClearStoredFrames();
|
||||
bSaving = false;
|
||||
|
||||
//If the live view window was open, we need to restart the UpdateWorker.
|
||||
if (bLiveViewRunning)
|
||||
RestartUpdateWorker();
|
||||
|
||||
btRecord.Enabled = true;
|
||||
btRecord.Text = "Start recording";
|
||||
btRefineCalib.Enabled = true;
|
||||
btCalibrate.Enabled = true;
|
||||
}
|
||||
|
||||
//Continually requests frames that will be displayed in the live view window.
|
||||
private void updateWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
List<List<byte>> lFramesRGB = new List<List<byte>>();
|
||||
List<List<Single>> lFramesVerts = new List<List<Single>>();
|
||||
|
||||
BackgroundWorker worker = (BackgroundWorker)sender;
|
||||
while (!worker.CancellationPending)
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
oServer.GetLatestFrame(lFramesRGB, lFramesVerts);
|
||||
|
||||
//Update the vertex and color lists that are common between this class and the OpenGLWindow.
|
||||
lock (lAllVertices)
|
||||
{
|
||||
lAllVertices.Clear();
|
||||
lAllColors.Clear();
|
||||
lAllCameraPoses.Clear();
|
||||
|
||||
for (int i = 0; i < lFramesRGB.Count; i++)
|
||||
{
|
||||
lAllVertices.AddRange(lFramesVerts[i]);
|
||||
lAllColors.AddRange(lFramesRGB[i]);
|
||||
lAllCameraPoses.Add(oServer.lCameraPoses[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//Notes the fact that a new frame was downloaded, this is used to estimate the FPS.
|
||||
if (oOpenGLWindow != null)
|
||||
oOpenGLWindow.CloudUpdateTick();
|
||||
}
|
||||
}
|
||||
|
||||
//Performs the ICP based pose refinement.
|
||||
private void refineWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
if (oServer.bAllCalibrated == false)
|
||||
{
|
||||
SetStatusBarOnTimer("Not all of the devices are calibrated.", 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
//Download a frame from each client.
|
||||
List<List<float>> lAllFrameVertices = new List<List<float>>();
|
||||
List<List<byte>> lAllFrameColors = new List<List<byte>>();
|
||||
oServer.GetLatestFrame(lAllFrameColors, lAllFrameVertices);
|
||||
|
||||
//Initialize containers for the poses.
|
||||
List<float[]> Rs = new List<float[]>();
|
||||
List<float[]> Ts = new List<float[]>();
|
||||
for (int i = 0; i < lAllFrameVertices.Count; i++)
|
||||
{
|
||||
float[] tempR = new float[9];
|
||||
float[] tempT = new float[3];
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
tempT[j] = 0;
|
||||
tempR[j + j * 3] = 1;
|
||||
}
|
||||
|
||||
Rs.Add(tempR);
|
||||
Ts.Add(tempT);
|
||||
}
|
||||
|
||||
//Use ICP to refine the sensor poses.
|
||||
//This part is explained in more detail in our article (name on top of this file).
|
||||
float error = 1;
|
||||
float oldError = 1;
|
||||
bool firstPass = true;
|
||||
int iter = 0;
|
||||
while (true)
|
||||
{
|
||||
if (iter > oSettings.nMaxNumRefineIters)
|
||||
break;
|
||||
|
||||
error = 0;
|
||||
for (int i = 0; i < lAllFrameVertices.Count; i++)
|
||||
{
|
||||
List<float> otherFramesVertices = new List<float>();
|
||||
for (int j = 0; j < lAllFrameVertices.Count; j++)
|
||||
{
|
||||
if (j == i)
|
||||
continue;
|
||||
otherFramesVertices.AddRange(lAllFrameVertices[j]);
|
||||
}
|
||||
|
||||
float[] verts1 = otherFramesVertices.ToArray();
|
||||
float[] verts2 = lAllFrameVertices[i].ToArray();
|
||||
|
||||
IntPtr pVerts1 = Marshal.AllocHGlobal(otherFramesVertices.Count * sizeof(float));
|
||||
IntPtr pVerts2 = Marshal.AllocHGlobal(lAllFrameVertices[i].Count * sizeof(float));
|
||||
|
||||
Marshal.Copy(verts1, 0, pVerts1, verts1.Length);
|
||||
Marshal.Copy(verts2, 0, pVerts2, verts2.Length);
|
||||
|
||||
error += ICP(pVerts1, pVerts2, otherFramesVertices.Count / 3, lAllFrameVertices[i].Count / 3, Rs[i], Ts[i], oSettings.nNumICPIterations);
|
||||
|
||||
Marshal.Copy(pVerts2, verts2, 0, verts2.Length);
|
||||
lAllFrameVertices[i].Clear();
|
||||
lAllFrameVertices[i].AddRange(verts2);
|
||||
}
|
||||
|
||||
if (firstPass)
|
||||
{
|
||||
firstPass = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Math.Abs(oldError - error) / error < 0.01)
|
||||
break;
|
||||
}
|
||||
oldError = error;
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
||||
//Update the calibration data in client machines.
|
||||
List<AffineTransform> worldTransforms = oServer.lWorldTransforms;
|
||||
|
||||
for (int i = 0; i < worldTransforms.Count; i++)
|
||||
{
|
||||
float[] tempT = new float[3];
|
||||
float[,] tempR = new float[3, 3];
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
tempT[j] += Ts[i][k] * worldTransforms[i].R[k, j];
|
||||
}
|
||||
|
||||
worldTransforms[i].t[j] += tempT[j];
|
||||
}
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
for (int l = 0; l < 3; l++)
|
||||
{
|
||||
tempR[j, k] += Rs[i][l * 3 + j] * worldTransforms[i].R[l, k];
|
||||
}
|
||||
|
||||
worldTransforms[i].R[j, k] = tempR[j, k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oServer.lWorldTransforms = worldTransforms;
|
||||
|
||||
oServer.SendCalibrationData();
|
||||
}
|
||||
|
||||
private void refineWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
//Re-enable all of the buttons after refinement.
|
||||
btRefineCalib.Enabled = true;
|
||||
btCalibrate.Enabled = true;
|
||||
btRecord.Enabled = true;
|
||||
}
|
||||
|
||||
//This is used for: starting/stopping the recording worker, stopping the saving worker
|
||||
private void btRecord_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (oServer.nClientCount < 1)
|
||||
{
|
||||
SetStatusBarOnTimer("At least one client needs to be connected for recording.", 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
//If we are saving frames right now, this button stops saving.
|
||||
if (bSaving)
|
||||
{
|
||||
btRecord.Enabled = false;
|
||||
savingWorker.CancelAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
bRecording = !bRecording;
|
||||
if (bRecording)
|
||||
{
|
||||
//Stop the update worker to reduce the network usage (provides better synchronization).
|
||||
updateWorker.CancelAsync();
|
||||
|
||||
recordingWorker.RunWorkerAsync();
|
||||
btRecord.Text = "Stop recording";
|
||||
btRefineCalib.Enabled = false;
|
||||
btCalibrate.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
btRecord.Enabled = false;
|
||||
recordingWorker.CancelAsync();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void btCalibrate_Click(object sender, EventArgs e)
|
||||
{
|
||||
oServer.Calibrate();
|
||||
}
|
||||
|
||||
private void btRefineCalib_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (oServer.nClientCount < 2)
|
||||
{
|
||||
SetStatusBarOnTimer("To refine calibration you need at least 2 connected devices.", 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
btRefineCalib.Enabled = false;
|
||||
btCalibrate.Enabled = false;
|
||||
btRecord.Enabled = false;
|
||||
|
||||
refineWorker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void saveToPly(string filename, List<Single> vertices, List<byte> colors)
|
||||
{
|
||||
int nVertices = vertices.Count / 3;
|
||||
|
||||
System.IO.StreamWriter file = new System.IO.StreamWriter(filename);
|
||||
|
||||
//PLY file header is written here.
|
||||
file.WriteLine("ply\nformat ascii 1.0");
|
||||
file.WriteLine("element vertex " + nVertices.ToString());
|
||||
file.WriteLine("property float x\nproperty float y\nproperty float z\nproperty uchar red\nproperty uchar green\nproperty uchar blue\nend_header");
|
||||
|
||||
//Vertex and color data are written here.
|
||||
for (int j = 0; j < vertices.Count / 3; j++)
|
||||
{
|
||||
string s = "";
|
||||
for (int k = 0; k < 3; k++) s += vertices[j * 3 + k].ToString(CultureInfo.InvariantCulture) + " ";
|
||||
for (int k = 0; k < 3; k++) s += colors[j * 3 + k].ToString(CultureInfo.InvariantCulture) + " ";
|
||||
file.WriteLine(s);
|
||||
}
|
||||
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void RestartUpdateWorker()
|
||||
{
|
||||
if (!updateWorker.IsBusy)
|
||||
updateWorker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void btShowLive_Click(object sender, EventArgs e)
|
||||
{
|
||||
RestartUpdateWorker();
|
||||
|
||||
//Opens the live view window if it is not open yet.
|
||||
if (!OpenGLWorker.IsBusy)
|
||||
OpenGLWorker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void SetStatusBarOnTimer(string message, int milliseconds)
|
||||
{
|
||||
statusLabel.Text = message;
|
||||
|
||||
oStatusBarTimer.Stop();
|
||||
oStatusBarTimer = new System.Timers.Timer();
|
||||
|
||||
oStatusBarTimer.Interval = milliseconds;
|
||||
oStatusBarTimer.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
oStatusBarTimer.Stop();
|
||||
statusLabel.Text = "";
|
||||
};
|
||||
oStatusBarTimer.Start();
|
||||
}
|
||||
|
||||
//Updates the ListBox contaning the connected clients, called by events inside KinectServer.
|
||||
private void UpdateListView(List<KinectSocket> socketList)
|
||||
{
|
||||
List<string> listBoxItems = new List<string>();
|
||||
|
||||
for (int i = 0; i < socketList.Count; i++)
|
||||
listBoxItems.Add(socketList[i].sSocketState);
|
||||
|
||||
lClientListBox.DataSource = listBoxItems;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>155, 17</value>
|
||||
</metadata>
|
||||
<metadata name="recordingWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>435, 17</value>
|
||||
</metadata>
|
||||
<metadata name="OpenGLWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>579, 17</value>
|
||||
</metadata>
|
||||
<metadata name="savingWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>702, 19</value>
|
||||
</metadata>
|
||||
<metadata name="updateWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>828, 19</value>
|
||||
</metadata>
|
||||
<metadata name="refineWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>958, 19</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,560 @@
|
||||
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
|
||||
// License: MIT Software License See LICENSE.txt for the full license.
|
||||
|
||||
// If you use this software in your research, then please use the following citation:
|
||||
|
||||
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
|
||||
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
|
||||
|
||||
// @INPROCEEDINGS{Kowalski15,
|
||||
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
|
||||
// booktitle={3D Vision (3DV), 2015 International Conference on},
|
||||
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
|
||||
// year={2015},
|
||||
// }
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Globalization;
|
||||
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Input;
|
||||
|
||||
enum ECameraMode
|
||||
{
|
||||
CAMERA_NONE, CAMERA_TRACK, CAMERA_DOLLY, CAMERA_ORBIT
|
||||
}
|
||||
|
||||
namespace KinectServer
|
||||
{
|
||||
class OpenGLWindow : GameWindow
|
||||
{
|
||||
int PointCount;
|
||||
int LineCount;
|
||||
|
||||
VertexC4ubV3f[] VBO;
|
||||
float PointSize = 0.0f;
|
||||
ECameraMode CameraMode = ECameraMode.CAMERA_NONE;
|
||||
|
||||
static float KEYBOARD_MOVE_SPEED = 0.01f;
|
||||
|
||||
static float MOUSE_ORBIT_SPEED = 0.30f; // 0 = SLOWEST, 1 = FASTEST
|
||||
static float MOUSE_DOLLY_SPEED = 0.2f; // same as above...but much more sensitive
|
||||
static float MOUSE_TRACK_SPEED = 0.003f; // same as above...but much more sensitive
|
||||
|
||||
float g_heading;
|
||||
float g_pitch;
|
||||
float dx = 0.0f;
|
||||
float dy = 0.0f;
|
||||
|
||||
Vector2 MousePrevious = new Vector2();
|
||||
Vector2 MouseCurrent = new Vector2();
|
||||
float[] cameraPosition = new float[3];
|
||||
float[] targetPosition = new float[3];
|
||||
|
||||
public List<float> vertices = new List<float>();
|
||||
public List<byte> colors = new List<byte>();
|
||||
public List<AffineTransform> cameraPoses = new List<AffineTransform>();
|
||||
public KinectSettings settings = new KinectSettings();
|
||||
|
||||
DateTime tFPSUpdateTimer = DateTime.Now;
|
||||
int nTickCounter = 0;
|
||||
|
||||
// this struct is used for drawing
|
||||
struct VertexC4ubV3f
|
||||
{
|
||||
public byte R, G, B, A;
|
||||
public Vector3 Position;
|
||||
|
||||
public static int SizeInBytes = 16;
|
||||
}
|
||||
|
||||
uint VBOHandle;
|
||||
|
||||
/// <summary>Creates a 800x600 window with the specified title.</summary>
|
||||
public OpenGLWindow()
|
||||
: base(800, 600)
|
||||
{
|
||||
this.VSync = VSyncMode.Off;
|
||||
MouseUp += new EventHandler<MouseButtonEventArgs>(OnMouseButtonUp);
|
||||
MouseDown += new EventHandler<MouseButtonEventArgs>(OnMouseButtonDown);
|
||||
MouseMove += new EventHandler<MouseMoveEventArgs>(OnMouseMove);
|
||||
MouseWheel += new EventHandler<MouseWheelEventArgs>(OnMouseWheelChanged);
|
||||
|
||||
KeyDown += new EventHandler<KeyboardKeyEventArgs>(OnKeyDown);
|
||||
|
||||
cameraPosition[0] = 0;
|
||||
cameraPosition[1] = 0;
|
||||
cameraPosition[2] = 1.0f;
|
||||
targetPosition[0] = 0;
|
||||
targetPosition[1] = 0;
|
||||
targetPosition[2] = 0;
|
||||
}
|
||||
|
||||
public void CloudUpdateTick()
|
||||
{
|
||||
nTickCounter++;
|
||||
}
|
||||
|
||||
void OnKeyDown(object sender, KeyboardKeyEventArgs e)
|
||||
{
|
||||
// e.Key
|
||||
}
|
||||
|
||||
/// <summary>Load resources here.</summary>
|
||||
/// <param name="e">Not used.</param>
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
Version version = new Version(GL.GetString(StringName.Version).Substring(0, 3));
|
||||
Version target = new Version(1, 5);
|
||||
if (version < target)
|
||||
{
|
||||
throw new NotSupportedException(String.Format(
|
||||
"OpenGL {0} is required (you only have {1}).", target, version));
|
||||
}
|
||||
|
||||
GL.ClearColor(.1f, 0f, .1f, 0f);
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
|
||||
// Setup parameters for Points
|
||||
GL.PointSize(PointSize);
|
||||
GL.Enable(EnableCap.PointSmooth);
|
||||
GL.Hint(HintTarget.PointSmoothHint, HintMode.Nicest);
|
||||
|
||||
// Setup VBO state
|
||||
GL.EnableClientState(EnableCap.ColorArray);
|
||||
GL.EnableClientState(EnableCap.VertexArray);
|
||||
|
||||
GL.GenBuffers(1, out VBOHandle);
|
||||
|
||||
// Since there's only 1 VBO in the app, might aswell setup here.
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, VBOHandle);
|
||||
GL.ColorPointer(4, ColorPointerType.UnsignedByte, VertexC4ubV3f.SizeInBytes, (IntPtr)0);
|
||||
GL.VertexPointer(3, VertexPointerType.Float, VertexC4ubV3f.SizeInBytes, (IntPtr)(4 * sizeof(byte)));
|
||||
|
||||
PointCount = 0;
|
||||
LineCount = 12;
|
||||
VBO = new VertexC4ubV3f[PointCount + 2 * LineCount];
|
||||
}
|
||||
|
||||
protected override void OnUnload(EventArgs e)
|
||||
{
|
||||
GL.DeleteBuffers(1, ref VBOHandle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when your window is resized. Set your viewport here. It is also
|
||||
/// a good place to set up your projection matrix (which probably changes
|
||||
/// along when the aspect ratio of your window).
|
||||
/// </summary>
|
||||
/// <param name="e">Contains information on the new Width and Size of the GameWindow.</param>
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
GL.Viewport(0, 0, Width, Height);
|
||||
|
||||
GL.MatrixMode(MatrixMode.Projection);
|
||||
Matrix4 p = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Width / (float)Height, 0.1f, 50.0f);
|
||||
GL.LoadMatrix(ref p);
|
||||
|
||||
GL.MatrixMode(MatrixMode.Modelview);
|
||||
Matrix4 mv = Matrix4.LookAt(Vector3.UnitZ, Vector3.Zero, Vector3.UnitY);
|
||||
GL.LoadMatrix(ref mv);
|
||||
}
|
||||
|
||||
void OnMouseWheelChanged(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
dy = e.Delta * MOUSE_DOLLY_SPEED;
|
||||
|
||||
cameraPosition[2] -= dy;
|
||||
|
||||
//if (cameraPosition[2] < 0)
|
||||
// cameraPosition[2] = 0;
|
||||
|
||||
}
|
||||
|
||||
void OnMouseMove(object sender, MouseMoveEventArgs e)
|
||||
{
|
||||
MouseCurrent.X = e.Mouse.X;
|
||||
MouseCurrent.Y = e.Mouse.Y;
|
||||
|
||||
// Now use mouse_delta to move the camera
|
||||
|
||||
switch (CameraMode)
|
||||
{
|
||||
case ECameraMode.CAMERA_TRACK:
|
||||
dx = MouseCurrent.X - MousePrevious.X;
|
||||
dx *= MOUSE_TRACK_SPEED;
|
||||
|
||||
dy = MouseCurrent.Y - MousePrevious.Y;
|
||||
dy *= MOUSE_TRACK_SPEED;
|
||||
|
||||
cameraPosition[0] -= dx;
|
||||
cameraPosition[1] += dy;
|
||||
|
||||
//targetPosition[0] -= dx;
|
||||
//targetPosition[1] += dy;
|
||||
|
||||
break;
|
||||
|
||||
case ECameraMode.CAMERA_DOLLY:
|
||||
dy = MouseCurrent.Y - MousePrevious.Y;
|
||||
dy *= MOUSE_DOLLY_SPEED;
|
||||
|
||||
cameraPosition[2] -= dy;
|
||||
|
||||
// if (cameraPosition[2] < 0)
|
||||
// cameraPosition[2] = 0;
|
||||
|
||||
break;
|
||||
|
||||
case ECameraMode.CAMERA_ORBIT:
|
||||
dx = MouseCurrent.X - MousePrevious.X;
|
||||
dx *= MOUSE_ORBIT_SPEED;
|
||||
|
||||
dy = MouseCurrent.Y - MousePrevious.Y;
|
||||
dy *= MOUSE_ORBIT_SPEED;
|
||||
|
||||
g_heading += dx;
|
||||
g_pitch += dy;
|
||||
|
||||
break;
|
||||
}
|
||||
MousePrevious.X = MouseCurrent.X;
|
||||
MousePrevious.Y = MouseCurrent.Y;
|
||||
}
|
||||
|
||||
void OnMouseButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
CameraMode = ECameraMode.CAMERA_NONE;
|
||||
}
|
||||
|
||||
void OnMouseButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
switch (e.Button)
|
||||
{
|
||||
case MouseButton.Left:
|
||||
CameraMode = ECameraMode.CAMERA_ORBIT;
|
||||
break;
|
||||
case MouseButton.Middle:
|
||||
CameraMode = ECameraMode.CAMERA_DOLLY;
|
||||
break;
|
||||
case MouseButton.Right:
|
||||
CameraMode = ECameraMode.CAMERA_TRACK;
|
||||
break;
|
||||
}
|
||||
MousePrevious.X = Mouse.X;
|
||||
MousePrevious.Y = Mouse.Y;
|
||||
}
|
||||
|
||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
||||
{
|
||||
if ((DateTime.Now - tFPSUpdateTimer).Seconds >= 1)
|
||||
{
|
||||
double FPS = nTickCounter / (DateTime.Now - tFPSUpdateTimer).TotalSeconds;
|
||||
this.Title = "FPS: " + string.Format("{0:F}", FPS);
|
||||
|
||||
tFPSUpdateTimer = DateTime.Now;
|
||||
nTickCounter = 0;
|
||||
}
|
||||
|
||||
var keyboard = OpenTK.Input.Keyboard.GetState();
|
||||
if (keyboard[Key.Escape])
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
if (keyboard[Key.Plus])
|
||||
{
|
||||
PointSize += 0.1f;
|
||||
GL.PointSize(PointSize);
|
||||
}
|
||||
if (keyboard[Key.Minus])
|
||||
{
|
||||
if (PointSize != 0)
|
||||
PointSize -= 0.1f;
|
||||
GL.PointSize(PointSize);
|
||||
}
|
||||
if (keyboard[Key.W])
|
||||
cameraPosition[2] -= KEYBOARD_MOVE_SPEED;
|
||||
if (keyboard[Key.A])
|
||||
cameraPosition[0] -= KEYBOARD_MOVE_SPEED;
|
||||
if (keyboard[Key.S])
|
||||
cameraPosition[2] += KEYBOARD_MOVE_SPEED;
|
||||
if (keyboard[Key.D])
|
||||
cameraPosition[0] += KEYBOARD_MOVE_SPEED;
|
||||
|
||||
lock (vertices)
|
||||
{
|
||||
lock (settings)
|
||||
{
|
||||
PointCount = vertices.Count / 3;
|
||||
//bounding box
|
||||
LineCount = 12;
|
||||
//markers
|
||||
LineCount += settings.lMarkerPoses.Count * 3;
|
||||
//cameras
|
||||
LineCount += cameraPoses.Count * 3;
|
||||
|
||||
VBO = new VertexC4ubV3f[PointCount + 2 * LineCount];
|
||||
|
||||
for (int i = 0; i < PointCount; i++)
|
||||
{
|
||||
VBO[i].R = (byte)colors[i * 3];
|
||||
VBO[i].G = (byte)colors[i * 3 + 1];
|
||||
VBO[i].B = (byte)colors[i * 3 + 2];
|
||||
VBO[i].A = 255;
|
||||
VBO[i].Position.X = vertices[i * 3];
|
||||
VBO[i].Position.Y = vertices[i * 3 + 1];
|
||||
VBO[i].Position.Z = vertices[i * 3 + 2];
|
||||
}
|
||||
|
||||
int iCurLineCount = 0;
|
||||
iCurLineCount += AddBoundingBox(PointCount + 2 * iCurLineCount);
|
||||
for (int i = 0; i < settings.lMarkerPoses.Count; i++)
|
||||
{
|
||||
iCurLineCount += AddMarker(PointCount + 2 * iCurLineCount, settings.lMarkerPoses[i].pose);
|
||||
}
|
||||
for (int i = 0; i < cameraPoses.Count; i++)
|
||||
{
|
||||
iCurLineCount += AddCamera(PointCount + 2 * iCurLineCount, cameraPoses[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when it is time to render the next frame. Add your rendering code here.
|
||||
/// </summary>
|
||||
/// <param name="e">Contains timing information.</param>
|
||||
protected override void OnRenderFrame(FrameEventArgs e)
|
||||
{
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
|
||||
GL.PushMatrix();
|
||||
|
||||
GL.MatrixMode(MatrixMode.Modelview);
|
||||
GL.Translate(-cameraPosition[0], -cameraPosition[1], -cameraPosition[2]);
|
||||
GL.Rotate(g_pitch, 1.0f, 0.0f, 0.0f);
|
||||
GL.Rotate(g_heading, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
// Tell OpenGL to discard old VBO when done drawing it and reserve memory _now_ for a new buffer.
|
||||
// without this, GL would wait until draw operations on old VBO are complete before writing to it
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(VertexC4ubV3f.SizeInBytes * (PointCount + 2 * LineCount)), IntPtr.Zero, BufferUsageHint.StreamDraw);
|
||||
// Fill newly allocated buffer
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(VertexC4ubV3f.SizeInBytes * (PointCount + 2 * LineCount)), VBO, BufferUsageHint.StreamDraw);
|
||||
|
||||
GL.DrawArrays(BeginMode.Points, 0, PointCount);
|
||||
GL.DrawArrays(BeginMode.Lines, PointCount, 2 * LineCount);
|
||||
|
||||
GL.PopMatrix();
|
||||
|
||||
SwapBuffers();
|
||||
}
|
||||
|
||||
private int AddBoundingBox(int startIdx)
|
||||
{
|
||||
int nLinesBeingAdded = 12;
|
||||
//2 points per line
|
||||
int nPointsToAdd = 2 * nLinesBeingAdded;
|
||||
|
||||
for (int i = startIdx; i < startIdx + nPointsToAdd; i++)
|
||||
{
|
||||
VBO[i].R = 255;
|
||||
VBO[i].G = 255;
|
||||
VBO[i].B = 0;
|
||||
VBO[i].A = 0;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
|
||||
//bottom vertices
|
||||
//first vertex
|
||||
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMinBounds[1], settings.aMinBounds[2],
|
||||
settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMinBounds[2]);
|
||||
n += 2;
|
||||
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMinBounds[1], settings.aMinBounds[2],
|
||||
settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2]);
|
||||
n += 2;
|
||||
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMinBounds[1], settings.aMinBounds[2],
|
||||
settings.aMinBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2]);
|
||||
n += 2;
|
||||
|
||||
//second vertex
|
||||
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMinBounds[2],
|
||||
settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2]);
|
||||
n += 2;
|
||||
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMinBounds[2],
|
||||
settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2]);
|
||||
n += 2;
|
||||
|
||||
//third vertex
|
||||
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2],
|
||||
settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2]);
|
||||
n += 2;
|
||||
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2],
|
||||
settings.aMinBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2]);
|
||||
n += 2;
|
||||
|
||||
//fourth vertex
|
||||
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2],
|
||||
settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2]);
|
||||
n += 2;
|
||||
|
||||
//top vertices
|
||||
//fifth vertex
|
||||
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2],
|
||||
settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2]);
|
||||
n += 2;
|
||||
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2],
|
||||
settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2]);
|
||||
n += 2;
|
||||
|
||||
//sixth vertex
|
||||
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2],
|
||||
settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2]);
|
||||
n += 2;
|
||||
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2],
|
||||
settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2]);
|
||||
n += 2;
|
||||
|
||||
return nLinesBeingAdded;
|
||||
}
|
||||
|
||||
private int AddMarker(int startIdx, AffineTransform pose)
|
||||
{
|
||||
int nLinesBeingAdded = 3;
|
||||
//2 points per line
|
||||
int nPointsToAdd = 2 * nLinesBeingAdded;
|
||||
|
||||
for (int i = startIdx; i < startIdx + nPointsToAdd; i++)
|
||||
{
|
||||
VBO[i].R = 255;
|
||||
VBO[i].G = 0;
|
||||
VBO[i].B = 0;
|
||||
VBO[i].A = 0;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
|
||||
float x0 = pose.t[0];
|
||||
float y0 = pose.t[1];
|
||||
float z0 = pose.t[2];
|
||||
|
||||
float x1 = 0.1f;
|
||||
float y1 = 0.1f;
|
||||
float z1 = 0.1f;
|
||||
|
||||
float x2 = pose.R[0, 0] * x1;
|
||||
float y2 = pose.R[1, 0] * x1;
|
||||
float z2 = pose.R[2, 0] * x1;
|
||||
|
||||
x2 += pose.t[0];
|
||||
y2 += pose.t[1];
|
||||
z2 += pose.t[2];
|
||||
|
||||
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
|
||||
n += 2;
|
||||
|
||||
x2 = pose.R[0, 1] * y1;
|
||||
y2 = pose.R[1, 1] * y1;
|
||||
z2 = pose.R[2, 1] * y1;
|
||||
|
||||
x2 += pose.t[0];
|
||||
y2 += pose.t[1];
|
||||
z2 += pose.t[2];
|
||||
|
||||
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
|
||||
n += 2;
|
||||
|
||||
x2 = pose.R[0, 2] * z1;
|
||||
y2 = pose.R[1, 2] * z1;
|
||||
z2 = pose.R[2, 2] * z1;
|
||||
|
||||
x2 += pose.t[0];
|
||||
y2 += pose.t[1];
|
||||
z2 += pose.t[2];
|
||||
|
||||
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
|
||||
n += 2;
|
||||
|
||||
return nLinesBeingAdded;
|
||||
}
|
||||
|
||||
private int AddCamera(int startIdx, AffineTransform pose)
|
||||
{
|
||||
int nLinesBeingAdded = 3;
|
||||
//2 points per line
|
||||
int nPointsToAdd = 2 * nLinesBeingAdded;
|
||||
|
||||
for (int i = startIdx; i < startIdx + nPointsToAdd; i++)
|
||||
{
|
||||
VBO[i].R = 0;
|
||||
VBO[i].G = 255;
|
||||
VBO[i].B = 0;
|
||||
VBO[i].A = 0;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
|
||||
float x0 = pose.t[0];
|
||||
float y0 = pose.t[1];
|
||||
float z0 = pose.t[2];
|
||||
|
||||
float x1 = 0.1f;
|
||||
float y1 = 0.1f;
|
||||
float z1 = 0.1f;
|
||||
|
||||
float x2 = pose.R[0, 0] * x1;
|
||||
float y2 = pose.R[1, 0] * x1;
|
||||
float z2 = pose.R[2, 0] * x1;
|
||||
|
||||
x2 += pose.t[0];
|
||||
y2 += pose.t[1];
|
||||
z2 += pose.t[2];
|
||||
|
||||
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
|
||||
n += 2;
|
||||
|
||||
x2 = pose.R[0, 1] * y1;
|
||||
y2 = pose.R[1, 1] * y1;
|
||||
z2 = pose.R[2, 1] * y1;
|
||||
|
||||
x2 += pose.t[0];
|
||||
y2 += pose.t[1];
|
||||
z2 += pose.t[2];
|
||||
|
||||
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
|
||||
n += 2;
|
||||
|
||||
x2 = pose.R[0, 2] * z1;
|
||||
y2 = pose.R[1, 2] * z1;
|
||||
z2 = pose.R[2, 2] * z1;
|
||||
|
||||
x2 += pose.t[0];
|
||||
y2 += pose.t[1];
|
||||
z2 += pose.t[2];
|
||||
|
||||
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
|
||||
n += 2;
|
||||
|
||||
return nLinesBeingAdded;
|
||||
}
|
||||
|
||||
private void AddLine(int startIdx, float x0, float y0, float z0,
|
||||
float x1, float y1, float z1)
|
||||
{
|
||||
VBO[startIdx].Position.X = x0;
|
||||
VBO[startIdx].Position.Y = y0;
|
||||
VBO[startIdx].Position.Z = z0;
|
||||
|
||||
VBO[startIdx + 1].Position.X = x1;
|
||||
VBO[startIdx + 1].Position.Y = y1;
|
||||
VBO[startIdx + 1].Position.Z = z1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace KinectServer
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainWindowForm());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("KinectServer")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("KinectServer")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("c781e249-f1ed-41af-89ab-4dbc1dde8bfd")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.34014
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace KinectServer.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("KinectServer.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.34014
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace KinectServer.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
Generated
+569
@@ -0,0 +1,569 @@
|
||||
namespace KinectServer
|
||||
{
|
||||
partial class SettingsForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.lbMerge = new System.Windows.Forms.Label();
|
||||
this.chMerge = new System.Windows.Forms.CheckBox();
|
||||
this.lbICPIters = new System.Windows.Forms.Label();
|
||||
this.txtICPIters = new System.Windows.Forms.TextBox();
|
||||
this.grClient = new System.Windows.Forms.GroupBox();
|
||||
this.grMarkers = new System.Windows.Forms.GroupBox();
|
||||
this.lbX2 = new System.Windows.Forms.Label();
|
||||
this.btRemove = new System.Windows.Forms.Button();
|
||||
this.txtOrientationZ = new System.Windows.Forms.TextBox();
|
||||
this.txtId = new System.Windows.Forms.TextBox();
|
||||
this.lbY2 = new System.Windows.Forms.Label();
|
||||
this.txtOrientationY = new System.Windows.Forms.TextBox();
|
||||
this.lbId = new System.Windows.Forms.Label();
|
||||
this.lbZ2 = new System.Windows.Forms.Label();
|
||||
this.txtOrientationX = new System.Windows.Forms.TextBox();
|
||||
this.btAdd = new System.Windows.Forms.Button();
|
||||
this.lbTranslation = new System.Windows.Forms.Label();
|
||||
this.lbOrientation = new System.Windows.Forms.Label();
|
||||
this.txtTranslationZ = new System.Windows.Forms.TextBox();
|
||||
this.txtTranslationX = new System.Windows.Forms.TextBox();
|
||||
this.lisMarkers = new System.Windows.Forms.ListBox();
|
||||
this.txtTranslationY = new System.Windows.Forms.TextBox();
|
||||
this.grBounding = new System.Windows.Forms.GroupBox();
|
||||
this.lbMin = new System.Windows.Forms.Label();
|
||||
this.txtMaxZ = new System.Windows.Forms.TextBox();
|
||||
this.txtMaxY = new System.Windows.Forms.TextBox();
|
||||
this.txtMinX = new System.Windows.Forms.TextBox();
|
||||
this.txtMaxX = new System.Windows.Forms.TextBox();
|
||||
this.txtMinY = new System.Windows.Forms.TextBox();
|
||||
this.lbMax = new System.Windows.Forms.Label();
|
||||
this.txtMinZ = new System.Windows.Forms.TextBox();
|
||||
this.lbZ = new System.Windows.Forms.Label();
|
||||
this.lbY = new System.Windows.Forms.Label();
|
||||
this.lbX = new System.Windows.Forms.Label();
|
||||
this.grFiltering = new System.Windows.Forms.GroupBox();
|
||||
this.txtFilterNeighbors = new System.Windows.Forms.TextBox();
|
||||
this.chFilter = new System.Windows.Forms.CheckBox();
|
||||
this.lbFilterNeighbors = new System.Windows.Forms.Label();
|
||||
this.lbFilterDistance = new System.Windows.Forms.Label();
|
||||
this.txtFilterDistance = new System.Windows.Forms.TextBox();
|
||||
this.grServer = new System.Windows.Forms.GroupBox();
|
||||
this.txtRefinIters = new System.Windows.Forms.TextBox();
|
||||
this.lbOuterIters = new System.Windows.Forms.Label();
|
||||
this.grClient.SuspendLayout();
|
||||
this.grMarkers.SuspendLayout();
|
||||
this.grBounding.SuspendLayout();
|
||||
this.grFiltering.SuspendLayout();
|
||||
this.grServer.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// lbMerge
|
||||
//
|
||||
this.lbMerge.AutoSize = true;
|
||||
this.lbMerge.Location = new System.Drawing.Point(6, 49);
|
||||
this.lbMerge.Name = "lbMerge";
|
||||
this.lbMerge.Size = new System.Drawing.Size(69, 13);
|
||||
this.lbMerge.TabIndex = 22;
|
||||
this.lbMerge.Text = "Scan saving:";
|
||||
//
|
||||
// chMerge
|
||||
//
|
||||
this.chMerge.AutoSize = true;
|
||||
this.chMerge.Location = new System.Drawing.Point(91, 48);
|
||||
this.chMerge.Name = "chMerge";
|
||||
this.chMerge.Size = new System.Drawing.Size(86, 17);
|
||||
this.chMerge.TabIndex = 23;
|
||||
this.chMerge.Text = "merge scans";
|
||||
this.chMerge.UseVisualStyleBackColor = true;
|
||||
this.chMerge.CheckedChanged += new System.EventHandler(this.chMerge_CheckedChanged);
|
||||
//
|
||||
// lbICPIters
|
||||
//
|
||||
this.lbICPIters.AutoSize = true;
|
||||
this.lbICPIters.Location = new System.Drawing.Point(6, 26);
|
||||
this.lbICPIters.Name = "lbICPIters";
|
||||
this.lbICPIters.Size = new System.Drawing.Size(86, 13);
|
||||
this.lbICPIters.TabIndex = 24;
|
||||
this.lbICPIters.Text = "Num of ICP iters:";
|
||||
//
|
||||
// txtICPIters
|
||||
//
|
||||
this.txtICPIters.Location = new System.Drawing.Point(91, 23);
|
||||
this.txtICPIters.Name = "txtICPIters";
|
||||
this.txtICPIters.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtICPIters.TabIndex = 25;
|
||||
this.txtICPIters.TextChanged += new System.EventHandler(this.txtICPIters_TextChanged);
|
||||
//
|
||||
// grClient
|
||||
//
|
||||
this.grClient.Controls.Add(this.grMarkers);
|
||||
this.grClient.Controls.Add(this.grBounding);
|
||||
this.grClient.Controls.Add(this.grFiltering);
|
||||
this.grClient.Location = new System.Drawing.Point(12, 12);
|
||||
this.grClient.Name = "grClient";
|
||||
this.grClient.Size = new System.Drawing.Size(632, 212);
|
||||
this.grClient.TabIndex = 43;
|
||||
this.grClient.TabStop = false;
|
||||
this.grClient.Text = "KinectClient settings";
|
||||
//
|
||||
// grMarkers
|
||||
//
|
||||
this.grMarkers.Controls.Add(this.lbX2);
|
||||
this.grMarkers.Controls.Add(this.btRemove);
|
||||
this.grMarkers.Controls.Add(this.txtOrientationZ);
|
||||
this.grMarkers.Controls.Add(this.txtId);
|
||||
this.grMarkers.Controls.Add(this.lbY2);
|
||||
this.grMarkers.Controls.Add(this.txtOrientationY);
|
||||
this.grMarkers.Controls.Add(this.lbId);
|
||||
this.grMarkers.Controls.Add(this.lbZ2);
|
||||
this.grMarkers.Controls.Add(this.txtOrientationX);
|
||||
this.grMarkers.Controls.Add(this.btAdd);
|
||||
this.grMarkers.Controls.Add(this.lbTranslation);
|
||||
this.grMarkers.Controls.Add(this.lbOrientation);
|
||||
this.grMarkers.Controls.Add(this.txtTranslationZ);
|
||||
this.grMarkers.Controls.Add(this.txtTranslationX);
|
||||
this.grMarkers.Controls.Add(this.lisMarkers);
|
||||
this.grMarkers.Controls.Add(this.txtTranslationY);
|
||||
this.grMarkers.Location = new System.Drawing.Point(271, 19);
|
||||
this.grMarkers.Name = "grMarkers";
|
||||
this.grMarkers.Size = new System.Drawing.Size(353, 185);
|
||||
this.grMarkers.TabIndex = 45;
|
||||
this.grMarkers.TabStop = false;
|
||||
this.grMarkers.Text = "Calibration markers";
|
||||
//
|
||||
// lbX2
|
||||
//
|
||||
this.lbX2.AutoSize = true;
|
||||
this.lbX2.Location = new System.Drawing.Point(230, 19);
|
||||
this.lbX2.Name = "lbX2";
|
||||
this.lbX2.Size = new System.Drawing.Size(14, 13);
|
||||
this.lbX2.TabIndex = 49;
|
||||
this.lbX2.Text = "X";
|
||||
//
|
||||
// btRemove
|
||||
//
|
||||
this.btRemove.Location = new System.Drawing.Point(233, 127);
|
||||
this.btRemove.Name = "btRemove";
|
||||
this.btRemove.Size = new System.Drawing.Size(92, 23);
|
||||
this.btRemove.TabIndex = 59;
|
||||
this.btRemove.Text = "Remove marker";
|
||||
this.btRemove.UseVisualStyleBackColor = true;
|
||||
this.btRemove.Click += new System.EventHandler(this.btRemove_Click);
|
||||
//
|
||||
// txtOrientationZ
|
||||
//
|
||||
this.txtOrientationZ.Location = new System.Drawing.Point(305, 38);
|
||||
this.txtOrientationZ.Name = "txtOrientationZ";
|
||||
this.txtOrientationZ.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtOrientationZ.TabIndex = 48;
|
||||
this.txtOrientationZ.TextChanged += new System.EventHandler(this.txtOrientationZ_TextChanged);
|
||||
//
|
||||
// txtId
|
||||
//
|
||||
this.txtId.Location = new System.Drawing.Point(217, 93);
|
||||
this.txtId.Name = "txtId";
|
||||
this.txtId.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtId.TabIndex = 58;
|
||||
this.txtId.TextChanged += new System.EventHandler(this.txtId_TextChanged);
|
||||
//
|
||||
// lbY2
|
||||
//
|
||||
this.lbY2.AutoSize = true;
|
||||
this.lbY2.Location = new System.Drawing.Point(274, 19);
|
||||
this.lbY2.Name = "lbY2";
|
||||
this.lbY2.Size = new System.Drawing.Size(14, 13);
|
||||
this.lbY2.TabIndex = 50;
|
||||
this.lbY2.Text = "Y";
|
||||
//
|
||||
// txtOrientationY
|
||||
//
|
||||
this.txtOrientationY.Location = new System.Drawing.Point(261, 38);
|
||||
this.txtOrientationY.Name = "txtOrientationY";
|
||||
this.txtOrientationY.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtOrientationY.TabIndex = 47;
|
||||
this.txtOrientationY.TextChanged += new System.EventHandler(this.txtOrientationY_TextChanged);
|
||||
//
|
||||
// lbId
|
||||
//
|
||||
this.lbId.AutoSize = true;
|
||||
this.lbId.Location = new System.Drawing.Point(132, 96);
|
||||
this.lbId.Name = "lbId";
|
||||
this.lbId.Size = new System.Drawing.Size(54, 13);
|
||||
this.lbId.TabIndex = 57;
|
||||
this.lbId.Text = "Marker id:";
|
||||
//
|
||||
// lbZ2
|
||||
//
|
||||
this.lbZ2.AutoSize = true;
|
||||
this.lbZ2.Location = new System.Drawing.Point(317, 19);
|
||||
this.lbZ2.Name = "lbZ2";
|
||||
this.lbZ2.Size = new System.Drawing.Size(14, 13);
|
||||
this.lbZ2.TabIndex = 51;
|
||||
this.lbZ2.Text = "Z";
|
||||
//
|
||||
// txtOrientationX
|
||||
//
|
||||
this.txtOrientationX.Location = new System.Drawing.Point(217, 38);
|
||||
this.txtOrientationX.Name = "txtOrientationX";
|
||||
this.txtOrientationX.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtOrientationX.TabIndex = 46;
|
||||
this.txtOrientationX.TextChanged += new System.EventHandler(this.txtOrientationX_TextChanged);
|
||||
//
|
||||
// btAdd
|
||||
//
|
||||
this.btAdd.Location = new System.Drawing.Point(135, 127);
|
||||
this.btAdd.Name = "btAdd";
|
||||
this.btAdd.Size = new System.Drawing.Size(92, 23);
|
||||
this.btAdd.TabIndex = 56;
|
||||
this.btAdd.Text = "Add marker";
|
||||
this.btAdd.UseVisualStyleBackColor = true;
|
||||
this.btAdd.Click += new System.EventHandler(this.btAdd_Click);
|
||||
//
|
||||
// lbTranslation
|
||||
//
|
||||
this.lbTranslation.AutoSize = true;
|
||||
this.lbTranslation.Location = new System.Drawing.Point(132, 68);
|
||||
this.lbTranslation.Name = "lbTranslation";
|
||||
this.lbTranslation.Size = new System.Drawing.Size(62, 13);
|
||||
this.lbTranslation.TabIndex = 52;
|
||||
this.lbTranslation.Text = "Translation:";
|
||||
//
|
||||
// lbOrientation
|
||||
//
|
||||
this.lbOrientation.AutoSize = true;
|
||||
this.lbOrientation.Location = new System.Drawing.Point(132, 41);
|
||||
this.lbOrientation.Name = "lbOrientation";
|
||||
this.lbOrientation.Size = new System.Drawing.Size(61, 13);
|
||||
this.lbOrientation.TabIndex = 45;
|
||||
this.lbOrientation.Text = "Orientation:";
|
||||
//
|
||||
// txtTranslationZ
|
||||
//
|
||||
this.txtTranslationZ.Location = new System.Drawing.Point(305, 65);
|
||||
this.txtTranslationZ.Name = "txtTranslationZ";
|
||||
this.txtTranslationZ.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtTranslationZ.TabIndex = 55;
|
||||
this.txtTranslationZ.TextChanged += new System.EventHandler(this.txtTranslationZ_TextChanged);
|
||||
//
|
||||
// txtTranslationX
|
||||
//
|
||||
this.txtTranslationX.Location = new System.Drawing.Point(217, 65);
|
||||
this.txtTranslationX.Name = "txtTranslationX";
|
||||
this.txtTranslationX.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtTranslationX.TabIndex = 53;
|
||||
this.txtTranslationX.TextChanged += new System.EventHandler(this.txtTranslationX_TextChanged);
|
||||
//
|
||||
// lisMarkers
|
||||
//
|
||||
this.lisMarkers.FormattingEnabled = true;
|
||||
this.lisMarkers.Location = new System.Drawing.Point(6, 41);
|
||||
this.lisMarkers.Name = "lisMarkers";
|
||||
this.lisMarkers.Size = new System.Drawing.Size(120, 108);
|
||||
this.lisMarkers.TabIndex = 43;
|
||||
//
|
||||
// txtTranslationY
|
||||
//
|
||||
this.txtTranslationY.Location = new System.Drawing.Point(261, 65);
|
||||
this.txtTranslationY.Name = "txtTranslationY";
|
||||
this.txtTranslationY.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtTranslationY.TabIndex = 54;
|
||||
this.txtTranslationY.TextChanged += new System.EventHandler(this.txtTranslationY_TextChanged);
|
||||
//
|
||||
// grBounding
|
||||
//
|
||||
this.grBounding.Controls.Add(this.lbMin);
|
||||
this.grBounding.Controls.Add(this.txtMaxZ);
|
||||
this.grBounding.Controls.Add(this.txtMaxY);
|
||||
this.grBounding.Controls.Add(this.txtMinX);
|
||||
this.grBounding.Controls.Add(this.txtMaxX);
|
||||
this.grBounding.Controls.Add(this.txtMinY);
|
||||
this.grBounding.Controls.Add(this.lbMax);
|
||||
this.grBounding.Controls.Add(this.txtMinZ);
|
||||
this.grBounding.Controls.Add(this.lbZ);
|
||||
this.grBounding.Controls.Add(this.lbY);
|
||||
this.grBounding.Controls.Add(this.lbX);
|
||||
this.grBounding.Location = new System.Drawing.Point(9, 19);
|
||||
this.grBounding.Name = "grBounding";
|
||||
this.grBounding.Size = new System.Drawing.Size(249, 91);
|
||||
this.grBounding.TabIndex = 46;
|
||||
this.grBounding.TabStop = false;
|
||||
this.grBounding.Text = "Bounding box";
|
||||
//
|
||||
// lbMin
|
||||
//
|
||||
this.lbMin.AutoSize = true;
|
||||
this.lbMin.Location = new System.Drawing.Point(8, 38);
|
||||
this.lbMin.Name = "lbMin";
|
||||
this.lbMin.Size = new System.Drawing.Size(65, 13);
|
||||
this.lbMin.TabIndex = 13;
|
||||
this.lbMin.Text = "Min bounds:";
|
||||
//
|
||||
// txtMaxZ
|
||||
//
|
||||
this.txtMaxZ.Location = new System.Drawing.Point(181, 62);
|
||||
this.txtMaxZ.Name = "txtMaxZ";
|
||||
this.txtMaxZ.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtMaxZ.TabIndex = 23;
|
||||
this.txtMaxZ.TextChanged += new System.EventHandler(this.txtMaxZ_TextChanged);
|
||||
//
|
||||
// txtMaxY
|
||||
//
|
||||
this.txtMaxY.Location = new System.Drawing.Point(137, 62);
|
||||
this.txtMaxY.Name = "txtMaxY";
|
||||
this.txtMaxY.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtMaxY.TabIndex = 22;
|
||||
this.txtMaxY.TextChanged += new System.EventHandler(this.txtMaxY_TextChanged);
|
||||
//
|
||||
// txtMinX
|
||||
//
|
||||
this.txtMinX.Location = new System.Drawing.Point(93, 35);
|
||||
this.txtMinX.Name = "txtMinX";
|
||||
this.txtMinX.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtMinX.TabIndex = 14;
|
||||
this.txtMinX.TextChanged += new System.EventHandler(this.txtMinX_TextChanged);
|
||||
//
|
||||
// txtMaxX
|
||||
//
|
||||
this.txtMaxX.Location = new System.Drawing.Point(93, 62);
|
||||
this.txtMaxX.Name = "txtMaxX";
|
||||
this.txtMaxX.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtMaxX.TabIndex = 21;
|
||||
this.txtMaxX.TextChanged += new System.EventHandler(this.txtMaxX_TextChanged);
|
||||
//
|
||||
// txtMinY
|
||||
//
|
||||
this.txtMinY.Location = new System.Drawing.Point(137, 35);
|
||||
this.txtMinY.Name = "txtMinY";
|
||||
this.txtMinY.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtMinY.TabIndex = 15;
|
||||
this.txtMinY.TextChanged += new System.EventHandler(this.txtMinY_TextChanged);
|
||||
//
|
||||
// lbMax
|
||||
//
|
||||
this.lbMax.AutoSize = true;
|
||||
this.lbMax.Location = new System.Drawing.Point(8, 65);
|
||||
this.lbMax.Name = "lbMax";
|
||||
this.lbMax.Size = new System.Drawing.Size(68, 13);
|
||||
this.lbMax.TabIndex = 20;
|
||||
this.lbMax.Text = "Max bounds:";
|
||||
//
|
||||
// txtMinZ
|
||||
//
|
||||
this.txtMinZ.Location = new System.Drawing.Point(181, 35);
|
||||
this.txtMinZ.Name = "txtMinZ";
|
||||
this.txtMinZ.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtMinZ.TabIndex = 16;
|
||||
this.txtMinZ.TextChanged += new System.EventHandler(this.txtMinZ_TextChanged);
|
||||
//
|
||||
// lbZ
|
||||
//
|
||||
this.lbZ.AutoSize = true;
|
||||
this.lbZ.Location = new System.Drawing.Point(193, 16);
|
||||
this.lbZ.Name = "lbZ";
|
||||
this.lbZ.Size = new System.Drawing.Size(14, 13);
|
||||
this.lbZ.TabIndex = 19;
|
||||
this.lbZ.Text = "Z";
|
||||
//
|
||||
// lbY
|
||||
//
|
||||
this.lbY.AutoSize = true;
|
||||
this.lbY.Location = new System.Drawing.Point(150, 16);
|
||||
this.lbY.Name = "lbY";
|
||||
this.lbY.Size = new System.Drawing.Size(14, 13);
|
||||
this.lbY.TabIndex = 18;
|
||||
this.lbY.Text = "Y";
|
||||
//
|
||||
// lbX
|
||||
//
|
||||
this.lbX.AutoSize = true;
|
||||
this.lbX.Location = new System.Drawing.Point(106, 16);
|
||||
this.lbX.Name = "lbX";
|
||||
this.lbX.Size = new System.Drawing.Size(14, 13);
|
||||
this.lbX.TabIndex = 17;
|
||||
this.lbX.Text = "X";
|
||||
//
|
||||
// grFiltering
|
||||
//
|
||||
this.grFiltering.Controls.Add(this.txtFilterNeighbors);
|
||||
this.grFiltering.Controls.Add(this.chFilter);
|
||||
this.grFiltering.Controls.Add(this.lbFilterNeighbors);
|
||||
this.grFiltering.Controls.Add(this.lbFilterDistance);
|
||||
this.grFiltering.Controls.Add(this.txtFilterDistance);
|
||||
this.grFiltering.Location = new System.Drawing.Point(9, 116);
|
||||
this.grFiltering.Name = "grFiltering";
|
||||
this.grFiltering.Size = new System.Drawing.Size(249, 88);
|
||||
this.grFiltering.TabIndex = 45;
|
||||
this.grFiltering.TabStop = false;
|
||||
this.grFiltering.Text = "Filtering";
|
||||
//
|
||||
// txtFilterNeighbors
|
||||
//
|
||||
this.txtFilterNeighbors.Location = new System.Drawing.Point(93, 39);
|
||||
this.txtFilterNeighbors.Name = "txtFilterNeighbors";
|
||||
this.txtFilterNeighbors.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtFilterNeighbors.TabIndex = 20;
|
||||
this.txtFilterNeighbors.TextChanged += new System.EventHandler(this.txtFilterNeighbors_TextChanged);
|
||||
//
|
||||
// chFilter
|
||||
//
|
||||
this.chFilter.AutoSize = true;
|
||||
this.chFilter.Location = new System.Drawing.Point(93, 16);
|
||||
this.chFilter.Name = "chFilter";
|
||||
this.chFilter.Size = new System.Drawing.Size(100, 17);
|
||||
this.chFilter.TabIndex = 18;
|
||||
this.chFilter.Text = "filtering enabled";
|
||||
this.chFilter.UseVisualStyleBackColor = true;
|
||||
this.chFilter.CheckedChanged += new System.EventHandler(this.chFilter_CheckedChanged);
|
||||
//
|
||||
// lbFilterNeighbors
|
||||
//
|
||||
this.lbFilterNeighbors.AutoSize = true;
|
||||
this.lbFilterNeighbors.Location = new System.Drawing.Point(8, 42);
|
||||
this.lbFilterNeighbors.Name = "lbFilterNeighbors";
|
||||
this.lbFilterNeighbors.Size = new System.Drawing.Size(67, 13);
|
||||
this.lbFilterNeighbors.TabIndex = 19;
|
||||
this.lbFilterNeighbors.Text = "N neighbors:";
|
||||
//
|
||||
// lbFilterDistance
|
||||
//
|
||||
this.lbFilterDistance.AutoSize = true;
|
||||
this.lbFilterDistance.Location = new System.Drawing.Point(8, 68);
|
||||
this.lbFilterDistance.Name = "lbFilterDistance";
|
||||
this.lbFilterDistance.Size = new System.Drawing.Size(73, 13);
|
||||
this.lbFilterDistance.TabIndex = 21;
|
||||
this.lbFilterDistance.Text = "Max distance:";
|
||||
//
|
||||
// txtFilterDistance
|
||||
//
|
||||
this.txtFilterDistance.Location = new System.Drawing.Point(93, 65);
|
||||
this.txtFilterDistance.Name = "txtFilterDistance";
|
||||
this.txtFilterDistance.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtFilterDistance.TabIndex = 22;
|
||||
this.txtFilterDistance.TextChanged += new System.EventHandler(this.txtFilterDistance_TextChanged);
|
||||
//
|
||||
// grServer
|
||||
//
|
||||
this.grServer.Controls.Add(this.txtRefinIters);
|
||||
this.grServer.Controls.Add(this.lbOuterIters);
|
||||
this.grServer.Controls.Add(this.lbMerge);
|
||||
this.grServer.Controls.Add(this.txtICPIters);
|
||||
this.grServer.Controls.Add(this.chMerge);
|
||||
this.grServer.Controls.Add(this.lbICPIters);
|
||||
this.grServer.Location = new System.Drawing.Point(12, 230);
|
||||
this.grServer.Name = "grServer";
|
||||
this.grServer.Size = new System.Drawing.Size(632, 78);
|
||||
this.grServer.TabIndex = 44;
|
||||
this.grServer.TabStop = false;
|
||||
this.grServer.Text = "KinectServer settings";
|
||||
//
|
||||
// txtRefinIters
|
||||
//
|
||||
this.txtRefinIters.Location = new System.Drawing.Point(271, 23);
|
||||
this.txtRefinIters.Name = "txtRefinIters";
|
||||
this.txtRefinIters.Size = new System.Drawing.Size(38, 20);
|
||||
this.txtRefinIters.TabIndex = 27;
|
||||
this.txtRefinIters.TextChanged += new System.EventHandler(this.txtRefinIters_TextChanged);
|
||||
//
|
||||
// lbOuterIters
|
||||
//
|
||||
this.lbOuterIters.AutoSize = true;
|
||||
this.lbOuterIters.Location = new System.Drawing.Point(135, 26);
|
||||
this.lbOuterIters.Name = "lbOuterIters";
|
||||
this.lbOuterIters.Size = new System.Drawing.Size(139, 13);
|
||||
this.lbOuterIters.TabIndex = 26;
|
||||
this.lbOuterIters.Text = "Max num of refinement iters:";
|
||||
//
|
||||
// SettingsForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(656, 319);
|
||||
this.Controls.Add(this.grServer);
|
||||
this.Controls.Add(this.grClient);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.Name = "SettingsForm";
|
||||
this.Text = "Settings";
|
||||
this.Load += new System.EventHandler(this.SettingsForm_Load);
|
||||
this.grClient.ResumeLayout(false);
|
||||
this.grMarkers.ResumeLayout(false);
|
||||
this.grMarkers.PerformLayout();
|
||||
this.grBounding.ResumeLayout(false);
|
||||
this.grBounding.PerformLayout();
|
||||
this.grFiltering.ResumeLayout(false);
|
||||
this.grFiltering.PerformLayout();
|
||||
this.grServer.ResumeLayout(false);
|
||||
this.grServer.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label lbMerge;
|
||||
private System.Windows.Forms.CheckBox chMerge;
|
||||
private System.Windows.Forms.Label lbICPIters;
|
||||
private System.Windows.Forms.TextBox txtICPIters;
|
||||
private System.Windows.Forms.GroupBox grClient;
|
||||
private System.Windows.Forms.GroupBox grServer;
|
||||
private System.Windows.Forms.TextBox txtRefinIters;
|
||||
private System.Windows.Forms.Label lbOuterIters;
|
||||
private System.Windows.Forms.GroupBox grFiltering;
|
||||
private System.Windows.Forms.TextBox txtFilterNeighbors;
|
||||
private System.Windows.Forms.CheckBox chFilter;
|
||||
private System.Windows.Forms.Label lbFilterNeighbors;
|
||||
private System.Windows.Forms.Label lbFilterDistance;
|
||||
private System.Windows.Forms.TextBox txtFilterDistance;
|
||||
private System.Windows.Forms.GroupBox grMarkers;
|
||||
private System.Windows.Forms.Label lbX2;
|
||||
private System.Windows.Forms.Button btRemove;
|
||||
private System.Windows.Forms.TextBox txtOrientationZ;
|
||||
private System.Windows.Forms.TextBox txtId;
|
||||
private System.Windows.Forms.Label lbY2;
|
||||
private System.Windows.Forms.TextBox txtOrientationY;
|
||||
private System.Windows.Forms.Label lbId;
|
||||
private System.Windows.Forms.Label lbZ2;
|
||||
private System.Windows.Forms.TextBox txtOrientationX;
|
||||
private System.Windows.Forms.Button btAdd;
|
||||
private System.Windows.Forms.Label lbTranslation;
|
||||
private System.Windows.Forms.Label lbOrientation;
|
||||
private System.Windows.Forms.TextBox txtTranslationZ;
|
||||
private System.Windows.Forms.TextBox txtTranslationX;
|
||||
private System.Windows.Forms.ListBox lisMarkers;
|
||||
private System.Windows.Forms.TextBox txtTranslationY;
|
||||
private System.Windows.Forms.GroupBox grBounding;
|
||||
private System.Windows.Forms.Label lbMin;
|
||||
private System.Windows.Forms.TextBox txtMaxZ;
|
||||
private System.Windows.Forms.TextBox txtMaxY;
|
||||
private System.Windows.Forms.TextBox txtMinX;
|
||||
private System.Windows.Forms.TextBox txtMaxX;
|
||||
private System.Windows.Forms.TextBox txtMinY;
|
||||
private System.Windows.Forms.Label lbMax;
|
||||
private System.Windows.Forms.TextBox txtMinZ;
|
||||
private System.Windows.Forms.Label lbZ;
|
||||
private System.Windows.Forms.Label lbY;
|
||||
private System.Windows.Forms.Label lbX;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
|
||||
// License: MIT Software License See LICENSE.txt for the full license.
|
||||
|
||||
// If you use this software in your research, then please use the following citation:
|
||||
|
||||
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
|
||||
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
|
||||
|
||||
// @INPROCEEDINGS{Kowalski15,
|
||||
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
|
||||
// booktitle={3D Vision (3DV), 2015 International Conference on},
|
||||
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
|
||||
// year={2015},
|
||||
// }
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Globalization;
|
||||
|
||||
namespace KinectServer
|
||||
{
|
||||
public partial class SettingsForm : Form
|
||||
{
|
||||
public KinectSettings oSettings;
|
||||
public KinectServer oServer;
|
||||
|
||||
public SettingsForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void SettingsForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
txtMinX.Text = oSettings.aMinBounds[0].ToString(CultureInfo.InvariantCulture);
|
||||
txtMinY.Text = oSettings.aMinBounds[1].ToString(CultureInfo.InvariantCulture);
|
||||
txtMinZ.Text = oSettings.aMinBounds[2].ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
txtMaxX.Text = oSettings.aMaxBounds[0].ToString(CultureInfo.InvariantCulture);
|
||||
txtMaxY.Text = oSettings.aMaxBounds[1].ToString(CultureInfo.InvariantCulture);
|
||||
txtMaxZ.Text = oSettings.aMaxBounds[2].ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
chFilter.Checked = oSettings.bFilter;
|
||||
txtFilterNeighbors.Text = oSettings.nFilterNeighbors.ToString();
|
||||
txtFilterDistance.Text = oSettings.fFilterThreshold.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
lisMarkers.DataSource = oSettings.lMarkerPoses;
|
||||
|
||||
|
||||
chMerge.Checked = oSettings.bMergeScansForSave;
|
||||
txtICPIters.Text = oSettings.nNumICPIterations.ToString();
|
||||
txtRefinIters.Text = oSettings.nMaxNumRefineIters.ToString();
|
||||
}
|
||||
|
||||
void UpdateClients()
|
||||
{
|
||||
oServer.SendSettings();
|
||||
}
|
||||
|
||||
void UpdateMarkerFields()
|
||||
{
|
||||
if (lisMarkers.SelectedIndex >= 0)
|
||||
{
|
||||
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
|
||||
|
||||
float X, Y, Z;
|
||||
pose.GetOrientation(out X, out Y, out Z);
|
||||
|
||||
txtOrientationX.Text = X.ToString(CultureInfo.InvariantCulture);
|
||||
txtOrientationY.Text = Y.ToString(CultureInfo.InvariantCulture);
|
||||
txtOrientationZ.Text = Z.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
txtTranslationX.Text = pose.pose.t[0].ToString(CultureInfo.InvariantCulture);
|
||||
txtTranslationY.Text = pose.pose.t[1].ToString(CultureInfo.InvariantCulture);
|
||||
txtTranslationZ.Text = pose.pose.t[2].ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
txtId.Text = pose.id.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
{
|
||||
txtOrientationX.Text = "";
|
||||
txtOrientationY.Text = "";
|
||||
txtOrientationZ.Text = "";
|
||||
|
||||
txtTranslationX.Text = "";
|
||||
txtTranslationY.Text = "";
|
||||
txtTranslationZ.Text = "";
|
||||
|
||||
txtId.Text = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void txtMinX_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Single.TryParse(txtMinX.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMinBounds[0]);
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
private void txtMinY_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Single.TryParse(txtMinY.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMinBounds[1]);
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
private void txtMinZ_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Single.TryParse(txtMinZ.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMinBounds[2]);
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
private void txtMaxX_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Single.TryParse(txtMaxX.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMaxBounds[0]);
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
private void txtMaxY_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Single.TryParse(txtMaxY.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMaxBounds[1]);
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
private void txtMaxZ_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Single.TryParse(txtMaxZ.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMaxBounds[2]);
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
private void chFilter_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
oSettings.bFilter = chFilter.Checked;
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
private void txtFilterNeighbors_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Int32.TryParse(txtFilterNeighbors.Text, out oSettings.nFilterNeighbors);
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
private void txtFilterDistance_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Single.TryParse(txtFilterDistance.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.fFilterThreshold);
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
private void txtICPIters_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Int32.TryParse(txtICPIters.Text, out oSettings.nNumICPIterations);
|
||||
}
|
||||
|
||||
private void txtRefinIters_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Int32.TryParse(txtRefinIters.Text, out oSettings.nMaxNumRefineIters);
|
||||
}
|
||||
|
||||
private void chMerge_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
oSettings.bMergeScansForSave = chMerge.Checked;
|
||||
}
|
||||
|
||||
private void btAdd_Click(object sender, EventArgs e)
|
||||
{
|
||||
lock (oSettings)
|
||||
oSettings.lMarkerPoses.Add(new MarkerPose());
|
||||
lisMarkers.SelectedIndex = oSettings.lMarkerPoses.Count - 1;
|
||||
UpdateMarkerFields();
|
||||
UpdateClients();
|
||||
}
|
||||
private void btRemove_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (oSettings.lMarkerPoses.Count > 0)
|
||||
{
|
||||
oSettings.lMarkerPoses.RemoveAt(lisMarkers.SelectedIndex);
|
||||
lisMarkers.SelectedIndex = oSettings.lMarkerPoses.Count - 1;
|
||||
UpdateMarkerFields();
|
||||
UpdateClients();
|
||||
}
|
||||
}
|
||||
|
||||
private void lisMarkers_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateMarkerFields();
|
||||
}
|
||||
|
||||
private void txtOrientationX_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lisMarkers.SelectedIndex >= 0)
|
||||
{
|
||||
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
|
||||
float X, Y, Z;
|
||||
pose.GetOrientation(out X, out Y, out Z);
|
||||
Single.TryParse(txtOrientationX.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out X);
|
||||
|
||||
pose.SetOrientation(X, Y, Z);
|
||||
UpdateClients();
|
||||
}
|
||||
}
|
||||
|
||||
private void txtOrientationY_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lisMarkers.SelectedIndex >= 0)
|
||||
{
|
||||
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
|
||||
float X, Y, Z;
|
||||
pose.GetOrientation(out X, out Y, out Z);
|
||||
Single.TryParse(txtOrientationY.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out Y);
|
||||
|
||||
pose.SetOrientation(X, Y, Z);
|
||||
UpdateClients();
|
||||
}
|
||||
}
|
||||
|
||||
private void txtOrientationZ_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lisMarkers.SelectedIndex >= 0)
|
||||
{
|
||||
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
|
||||
float X, Y, Z;
|
||||
pose.GetOrientation(out X, out Y, out Z);
|
||||
Single.TryParse(txtOrientationZ.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out Z);
|
||||
|
||||
pose.SetOrientation(X, Y, Z);
|
||||
UpdateClients();
|
||||
}
|
||||
}
|
||||
|
||||
private void txtTranslationX_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lisMarkers.SelectedIndex >= 0)
|
||||
{
|
||||
float X;
|
||||
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
|
||||
Single.TryParse(txtTranslationX.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out X);
|
||||
|
||||
pose.pose.t[0] = X;
|
||||
UpdateClients();
|
||||
}
|
||||
}
|
||||
|
||||
private void txtTranslationY_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lisMarkers.SelectedIndex >= 0)
|
||||
{
|
||||
float Y;
|
||||
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
|
||||
Single.TryParse(txtTranslationY.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out Y);
|
||||
|
||||
pose.pose.t[1] = Y;
|
||||
UpdateClients();
|
||||
}
|
||||
}
|
||||
|
||||
private void txtTranslationZ_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lisMarkers.SelectedIndex >= 0)
|
||||
{
|
||||
float Z;
|
||||
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
|
||||
Single.TryParse(txtTranslationZ.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out Z);
|
||||
|
||||
pose.pose.t[2] = Z;
|
||||
UpdateClients();
|
||||
}
|
||||
}
|
||||
|
||||
private void txtId_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lisMarkers.SelectedIndex >= 0)
|
||||
{
|
||||
int id;
|
||||
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
|
||||
Int32.TryParse(txtId.Text, out id);
|
||||
|
||||
pose.id = id;
|
||||
UpdateClients();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
|
||||
// License: MIT Software License See LICENSE.txt for the full license.
|
||||
|
||||
// If you use this software in your research, then please use the following citation:
|
||||
|
||||
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
|
||||
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
|
||||
|
||||
// @INPROCEEDINGS{Kowalski15,
|
||||
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
|
||||
// booktitle={3D Vision (3DV), 2015 International Conference on},
|
||||
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
|
||||
// year={2015},
|
||||
// }
|
||||
using System;
|
||||
|
||||
namespace KinectServer
|
||||
{
|
||||
[Serializable]
|
||||
public class AffineTransform
|
||||
{
|
||||
public float[,] R = new float[3, 3];
|
||||
public float[] t = new float[3];
|
||||
|
||||
public AffineTransform()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
if (i == j)
|
||||
R[i, j] = 1;
|
||||
else
|
||||
R[i, j] = 0;
|
||||
}
|
||||
t[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class MarkerPose
|
||||
{
|
||||
public AffineTransform pose = new AffineTransform();
|
||||
public int id = -1;
|
||||
|
||||
public MarkerPose()
|
||||
{
|
||||
UpdateRotationMatrix();
|
||||
}
|
||||
|
||||
public void SetOrientation(float X, float Y, float Z)
|
||||
{
|
||||
r[0] = X;
|
||||
r[1] = Y;
|
||||
r[2] = Z;
|
||||
|
||||
UpdateRotationMatrix();
|
||||
}
|
||||
|
||||
public void GetOrientation(out float X, out float Y, out float Z)
|
||||
{
|
||||
X = r[0];
|
||||
Y = r[1];
|
||||
Z = r[2];
|
||||
}
|
||||
|
||||
private void UpdateRotationMatrix()
|
||||
{
|
||||
float radX = r[0] * (float)Math.PI / 180.0f;
|
||||
float radY = r[1] * (float)Math.PI / 180.0f;
|
||||
float radZ = r[2] * (float)Math.PI / 180.0f;
|
||||
|
||||
float c1 = (float)Math.Cos(radZ);
|
||||
float c2 = (float)Math.Cos(radY);
|
||||
float c3 = (float)Math.Cos(radX);
|
||||
float s1 = (float)Math.Sin(radZ);
|
||||
float s2 = (float)Math.Sin(radY);
|
||||
float s3 = (float)Math.Sin(radX);
|
||||
|
||||
//Z Y X rotation
|
||||
pose.R[0, 0] = c1 * c2;
|
||||
pose.R[0, 1] = c1 * s2 * s3 - c3 * s1;
|
||||
pose.R[0, 2] = s1 * s3 + c1 * c3 * s2;
|
||||
pose.R[1, 0] = c2 * s1;
|
||||
pose.R[1, 1] = c1 * c3 + s1 * s2 * s3;
|
||||
pose.R[1, 2] = c3 * s1 * s2 - c1 * s3;
|
||||
pose.R[2, 0] = -s2;
|
||||
pose.R[2, 1] = c2 * s3;
|
||||
pose.R[2, 2] = c2 * c3;
|
||||
}
|
||||
|
||||
private float[] r = new float[3];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user