added conversion helpers for matlab
added examples for using the python wrappers in matlab
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
V = py.igl.eigen.MatrixXd();
|
||||
F = py.igl.eigen.MatrixXi();
|
||||
py.igl.read_triangle_mesh('../tutorial/shared/fertility.off', V, F);
|
||||
|
||||
% Alternative discrete mean curvature
|
||||
HN = py.igl.eigen.MatrixXd();
|
||||
L = py.igl.eigen.SparseMatrixd();
|
||||
M = py.igl.eigen.SparseMatrixd();
|
||||
Minv = py.igl.eigen.SparseMatrixd();
|
||||
|
||||
|
||||
py.igl.cotmatrix(V,F,L)
|
||||
py.igl.massmatrix(V,F,py.igl.MASSMATRIX_TYPE_VORONOI,M)
|
||||
|
||||
py.igl.invert_diag(M,Minv)
|
||||
|
||||
% Laplace-Beltrami of position
|
||||
HN = -Minv*(L*V)
|
||||
|
||||
% Extract magnitude as mean curvature
|
||||
H = HN.rowwiseNorm()
|
||||
|
||||
% Compute curvature directions via quadric fitting
|
||||
PD1 = py.igl.eigen.MatrixXd()
|
||||
PD2 = py.igl.eigen.MatrixXd()
|
||||
|
||||
PV1 = py.igl.eigen.MatrixXd()
|
||||
PV2 = py.igl.eigen.MatrixXd()
|
||||
|
||||
py.igl.principal_curvature(V,F,PD1,PD2,PV1,PV2)
|
||||
|
||||
% Mean curvature
|
||||
H = 0.5*(PV1+PV2)
|
||||
|
||||
viewer = py.igl.viewer.Viewer()
|
||||
viewer.data.set_mesh(V, F)
|
||||
|
||||
% Compute pseudocolor
|
||||
C = py.igl.eigen.MatrixXd()
|
||||
py.igl.parula(H,true,C)
|
||||
|
||||
viewer.data.set_colors(C)
|
||||
|
||||
% Average edge length for sizing
|
||||
avg = py.igl.avg_edge_length(V,F)
|
||||
|
||||
% Draw a blue segment parallel to the minimal curvature direction
|
||||
red = py.iglhelpers.p2e(py.numpy.array([[0.8,0.2,0.2]]))
|
||||
blue = py.iglhelpers.p2e(py.numpy.array([[0.2,0.2,0.8]]))
|
||||
|
||||
viewer.data.add_edges(V + PD1*avg, V - PD1*avg, blue)
|
||||
|
||||
% Draw a red segment parallel to the maximal curvature direction
|
||||
viewer.data.add_edges(V + PD2*avg, V - PD2*avg, red)
|
||||
|
||||
% Hide wireframe
|
||||
viewer.core.show_lines = false
|
||||
|
||||
viewer.launch()
|
||||
@@ -0,0 +1,18 @@
|
||||
%% Launch the external viewer
|
||||
launch_viewer;
|
||||
|
||||
%% Load a mesh in OFF format
|
||||
V = py.igl.eigen.MatrixXd();
|
||||
F = py.igl.eigen.MatrixXi();
|
||||
py.igl.readOFF('../tutorial/shared/beetle.off', V, F);
|
||||
|
||||
%% Scale the x coordinate in matlab
|
||||
V = p2m(V);
|
||||
V(:,1) = V(:,1) * 2;
|
||||
V = m2p(V);
|
||||
|
||||
%% Plot the mesh
|
||||
viewer = py.tcpviewer_single.TCPViewer();
|
||||
viewer.data.set_mesh(V, F);
|
||||
viewer.launch();
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
% Launch the external viewer
|
||||
launch_viewer;
|
||||
|
||||
V = py.igl.eigen.MatrixXd();
|
||||
F = py.igl.eigen.MatrixXi();
|
||||
py.igl.read_triangle_mesh('../tutorial/shared/fertility.off', V, F);
|
||||
|
||||
% Alternative discrete mean curvature
|
||||
HN = py.igl.eigen.MatrixXd();
|
||||
L = py.igl.eigen.SparseMatrixd();
|
||||
M = py.igl.eigen.SparseMatrixd();
|
||||
Minv = py.igl.eigen.SparseMatrixd();
|
||||
|
||||
|
||||
py.igl.cotmatrix(V,F,L);
|
||||
py.igl.massmatrix(V,F,py.igl.MASSMATRIX_TYPE_VORONOI,M);
|
||||
|
||||
py.igl.invert_diag(M,Minv);
|
||||
|
||||
% Laplace-Beltrami of position
|
||||
HN = -Minv*(L*V);
|
||||
|
||||
% Extract magnitude as mean curvature
|
||||
H = HN.rowwiseNorm();
|
||||
|
||||
% Compute curvature directions via quadric fitting
|
||||
PD1 = py.igl.eigen.MatrixXd();
|
||||
PD2 = py.igl.eigen.MatrixXd();
|
||||
|
||||
PV1 = py.igl.eigen.MatrixXd();
|
||||
PV2 = py.igl.eigen.MatrixXd();
|
||||
|
||||
py.igl.principal_curvature(V,F,PD1,PD2,PV1,PV2);
|
||||
|
||||
% Mean curvature
|
||||
H = 0.5*(PV1+PV2);
|
||||
|
||||
viewer = py.tcpviewer_single.TCPViewer();
|
||||
viewer.data.set_mesh(V, F);
|
||||
|
||||
% Compute pseudocolor
|
||||
C = py.igl.eigen.MatrixXd();
|
||||
py.igl.parula(H,true,C);
|
||||
|
||||
viewer.data.set_colors(C);
|
||||
|
||||
% Average edge length for sizing
|
||||
avg = py.igl.avg_edge_length(V,F);
|
||||
|
||||
% Draw a blue segment parallel to the minimal curvature direction
|
||||
red = m2p([0.8,0.2,0.2]);
|
||||
blue = m2p([0.2,0.2,0.8]);
|
||||
|
||||
viewer.data.add_edges(V + PD1*avg, V - PD1*avg, blue);
|
||||
|
||||
% Draw a red segment parallel to the maximal curvature direction
|
||||
viewer.data.add_edges(V + PD2*avg, V - PD2*avg, red);
|
||||
|
||||
% Plot
|
||||
viewer.launch()
|
||||
@@ -0,0 +1,3 @@
|
||||
system('python tcpviewer_single.py&');
|
||||
|
||||
pause(0.1) % Wait a bit for the viewer to start
|
||||
@@ -0,0 +1,19 @@
|
||||
% Converts a Matlab matrix to a python-wrapped Eigen Matrix
|
||||
function [ P ] = m2p( M )
|
||||
if (isa(M, 'double'))
|
||||
% Convert the matrix to a python 1D array
|
||||
a = py.array.array('d',reshape(M,1,numel(M)));
|
||||
% Then convert it to a eigen type
|
||||
t = py.igl.eigen.MatrixXd(a.tolist());
|
||||
% Finally reshape it back
|
||||
P = t.MapMatrix(uint16(size(M,1)),uint16(size(M,2)));
|
||||
elseif (isa(M, 'integer'))
|
||||
% Convert the matrix to a python 1D array
|
||||
a = py.array.array('i',reshape(M,1,numel(M)));
|
||||
% Then convert it to a eigen type
|
||||
t = py.igl.eigen.MatrixXi(a.tolist());
|
||||
% Finally reshape it back
|
||||
P = t.MapMatrix(uint16(size(M,1)),uint16(size(M,2)));
|
||||
else
|
||||
error('Unsupported numerical type.');
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
% Converts a python-wrapped Eigen Matrix to a Matlab matrix
|
||||
function [ M ] = p2m( P )
|
||||
if py.repr(py.type(P)) == '<class ''igl.eigen.MatrixXd''>'
|
||||
% Convert it to a python array first
|
||||
t = py.array.array('d',P);
|
||||
% Reshape it
|
||||
M = reshape(double(t),P.rows(),P.cols());
|
||||
elseif py.repr(py.type(P)) == '<class ''igl.eigen.MatrixXi''>'
|
||||
% Convert it to a python array first
|
||||
t = py.array.array('i',P);
|
||||
% Reshape it
|
||||
M = reshape(int32(t),P.rows(),P.cols());
|
||||
else
|
||||
error('Unsupported numerical type.');
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
% Load a mesh in OFF format
|
||||
V = py.igl.eigen.MatrixXd();
|
||||
F = py.igl.eigen.MatrixXi();
|
||||
py.igl.readOFF('../tutorial/shared/beetle.off', V, F);
|
||||
|
||||
V
|
||||
|
||||
% Plot the mesh
|
||||
viewer = py.tcpviewer.TCPViewer()
|
||||
viewer.data.set_mesh(V, F)
|
||||
viewer.launch()
|
||||
|
||||
@@ -47,6 +47,25 @@ py::class_<Type> bind_eigen_2(py::module &m, const char *name,
|
||||
|
||||
return;
|
||||
})
|
||||
.def("__init__", [](Type &m, std::vector<Scalar>& b) {
|
||||
if (b.size() == 0)
|
||||
{
|
||||
new (&m) Type(0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Size checks
|
||||
unsigned rows = b.size();
|
||||
unsigned cols = 1;
|
||||
|
||||
new (&m) Type(rows, cols);
|
||||
|
||||
m.resize(rows,cols);
|
||||
for (unsigned i=0;i<rows;++i)
|
||||
m(i,0) = b[i];
|
||||
|
||||
return;
|
||||
})
|
||||
.def("__init__", [](Type &m, py::buffer b) {
|
||||
py::buffer_info info = b.request();
|
||||
if (info.format != py::format_descriptor<Scalar>::value())
|
||||
|
||||
+57
-22
@@ -1,45 +1,80 @@
|
||||
import socket
|
||||
import multiprocessing
|
||||
import threading
|
||||
import igl
|
||||
import array
|
||||
import time
|
||||
|
||||
HOST = 'localhost' # Symbolic name meaning all available interfaces
|
||||
PORT = 50008 # Arbitrary non-privileged port
|
||||
|
||||
def worker(data):
|
||||
viewer = igl.viewer.Viewer()
|
||||
temp = list(data)
|
||||
viewer.deserialize(temp)
|
||||
viewer.launch(True,False)
|
||||
return
|
||||
def worker(viewer,lock,s):
|
||||
|
||||
class TCPViewer(igl.viewer.Viewer):
|
||||
def launch(self):
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((HOST, PORT))
|
||||
a = array.array('u',self.serialize())
|
||||
s.sendall(a)
|
||||
s.close()
|
||||
|
||||
if __name__ == "__main__": # The main script is a server
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.bind((HOST, PORT))
|
||||
s.listen(1)
|
||||
print("TCP iglviewer server listening on port " + str(PORT))
|
||||
try:
|
||||
while True:
|
||||
conn, addr = s.accept()
|
||||
lock.acquire()
|
||||
slist = []
|
||||
while True:
|
||||
buf = conn.recv(4096)
|
||||
buf = conn.recv(10000000)
|
||||
if not buf:
|
||||
break
|
||||
slist.append(buf.decode('unicode_internal','ignore'))
|
||||
conn.close()
|
||||
|
||||
data = ''.join(slist)
|
||||
temp = list(data)
|
||||
|
||||
isempty = viewer.data.V.rows() == 0
|
||||
viewer.data.deserialize(temp)
|
||||
if isempty and viewer.data.V.rows() != 0:
|
||||
viewer.core.align_camera_center(viewer.data.V,viewer.data.F)
|
||||
|
||||
lock.release()
|
||||
|
||||
t = multiprocessing.Process(target=worker, args=(data,))
|
||||
t.start()
|
||||
except:
|
||||
s.close()
|
||||
return
|
||||
|
||||
class TCPViewer(igl.viewer.Viewer):
|
||||
def launch(self):
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((HOST, PORT))
|
||||
a = array.array('u',self.data.serialize())
|
||||
s.sendall(a)
|
||||
s.close()
|
||||
except:
|
||||
print("Failed to open socket, is tcpviewer running?")
|
||||
|
||||
if __name__ == "__main__": # The main script is a server
|
||||
|
||||
## Try to open the socket first
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
s.bind((HOST, PORT))
|
||||
except:
|
||||
print("Failed to bind, port already used.")
|
||||
exit(1)
|
||||
s.listen(1)
|
||||
|
||||
viewer = igl.viewer.Viewer()
|
||||
|
||||
lock = threading.Lock()
|
||||
t = threading.Thread(target=worker, args=(viewer,lock,s,))
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
viewer.core.is_animating = True
|
||||
# viewer.data.dirty = int(0x03FF)
|
||||
|
||||
viewer.launch_init(True,False)
|
||||
done = False
|
||||
while not done:
|
||||
lock.acquire()
|
||||
done = not viewer.launch_rendering(False)
|
||||
lock.release()
|
||||
|
||||
time.sleep(0.000001) # DO NOT REMOVE ME
|
||||
|
||||
viewer.launch_shut()
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
import socket
|
||||
import threading
|
||||
import igl
|
||||
import array
|
||||
import time
|
||||
|
||||
HOST = 'localhost' # Symbolic name meaning all available interfaces
|
||||
PORT = 50008 # Arbitrary non-privileged port
|
||||
|
||||
def worker(viewer,lock):
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.bind((HOST, PORT))
|
||||
s.listen(1)
|
||||
print("TCP iglviewer server listening on port " + str(PORT))
|
||||
try:
|
||||
while True:
|
||||
conn, addr = s.accept()
|
||||
lock.acquire()
|
||||
slist = []
|
||||
while True:
|
||||
buf = conn.recv(4096)
|
||||
if not buf:
|
||||
break
|
||||
slist.append(buf.decode('unicode_internal','ignore'))
|
||||
conn.close()
|
||||
|
||||
data = ''.join(slist)
|
||||
temp = list(data)
|
||||
|
||||
isempty = viewer.data.V.rows() == 0
|
||||
viewer.data.deserialize(temp)
|
||||
if isempty and viewer.data.V.rows() != 0:
|
||||
viewer.core.align_camera_center(viewer.data.V,viewer.data.F)
|
||||
|
||||
lock.release()
|
||||
|
||||
except:
|
||||
s.close()
|
||||
return
|
||||
|
||||
class TCPViewer(igl.viewer.Viewer):
|
||||
def launch(self):
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((HOST, PORT))
|
||||
a = array.array('u',self.data.serialize())
|
||||
s.sendall(a)
|
||||
s.close()
|
||||
|
||||
if __name__ == "__main__": # The main script is a server
|
||||
viewer = igl.viewer.Viewer()
|
||||
|
||||
lock = threading.Lock()
|
||||
t = threading.Thread(target=worker, args=(viewer,lock,))
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
viewer.core.is_animating = True
|
||||
# viewer.data.dirty = int(0x03FF)
|
||||
|
||||
viewer.launch_init(True,False)
|
||||
done = False
|
||||
while not done:
|
||||
lock.acquire()
|
||||
done = not viewer.launch_rendering(False)
|
||||
lock.release()
|
||||
|
||||
time.sleep(0.000001) # DO NOT REMOVE ME
|
||||
|
||||
viewer.launch_shut()
|
||||
@@ -1,24 +0,0 @@
|
||||
import igl
|
||||
import tcpviewer
|
||||
import time
|
||||
|
||||
# Load a mesh in OFF format
|
||||
V = igl.eigen.MatrixXd()
|
||||
F = igl.eigen.MatrixXi()
|
||||
time1 = time.time()
|
||||
# igl.read_triangle_mesh("../tutorial/shared/armadillo.obj", V, F)
|
||||
igl.readOFF("../tutorial/shared/beetle.off", V, F)
|
||||
time2 = time.time()
|
||||
|
||||
|
||||
print('Loading mesh (%d vertices) %0.3f ms' % (V.rows(),(time2-time1)*1000.0))
|
||||
|
||||
|
||||
# Plot the mesh
|
||||
viewer = tcpviewer.TCPViewer()
|
||||
viewer.data.set_mesh(V, F)
|
||||
viewer.core.align_camera_center(V,F)
|
||||
viewer.launch()
|
||||
time3 = time.time()
|
||||
|
||||
print('Sending to TCP viewer took %0.3f ms' % ((time3-time2)*1000.0))
|
||||
@@ -0,0 +1,27 @@
|
||||
## This is a test application for the TCPViewer
|
||||
|
||||
# Add the igl library to the modules search path
|
||||
import sys, os
|
||||
sys.path.insert(0, os.getcwd() + "/../")
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
# Launch the tcp viewer
|
||||
os.system("python ../tcpviewer.py&")
|
||||
|
||||
# Wait for it to set up the socket
|
||||
time.sleep(1)
|
||||
|
||||
import igl
|
||||
import tcpviewer
|
||||
|
||||
# Read a mesh
|
||||
V = igl.eigen.MatrixXd()
|
||||
F = igl.eigen.MatrixXi()
|
||||
igl.readOFF('../../tutorial/shared/beetle.off', V, F)
|
||||
|
||||
# Send it to the viewer
|
||||
viewer = tcpviewer.TCPViewer()
|
||||
viewer.data.set_mesh(V, F)
|
||||
viewer.launch()
|
||||
Reference in New Issue
Block a user