Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 73 additions & 42 deletions raysect/primitive/mesh/vtk.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,14 +46,17 @@
class VTKHandler:

@classmethod
def import_vtk(cls, filename, scaling=1.0, mode=VTK_AUTOMATIC, **kwargs):
def my_import_vtk(cls, filename, scaling=1e-3, mode=VTK_AUTOMATIC, **kwargs):
"""
Create a mesh instance from a VTK mesh data file (.vtk).

.. warning ::
Currently only supports VTK DataFile v2.0 and unstructured grid data with
3 element (triangular) cells.

.. warning ::
Trying to update the version to be able to read VTK DataFile 4.2.

:param str filename: Mesh file path.
:param double scaling: Scale the mesh by this factor (default=1.0).
:param str mode: The file format to load: 'ascii', 'binary', 'auto' (default='auto').
Expand DownExpand Up@@ -87,11 +90,11 @@ def _load_ascii(cls, filename, scaling):
with open(filename, 'r') as f:

# parse the file header
assert f.readline().strip() == "# vtk DataFile Version 2.0"
assert f.readline().strip() == "# vtk DataFile Version 4.2"
mesh_name = f.readline().strip()
assert f.readline().strip() == "ASCII"

if not f.readline().strip() == "DATASET UNSTRUCTURED_GRID":
if not f.readline().strip() == "DATASET POLYDATA":
raise RuntimeError("Unrecognised dataset encountered in vtk file.")

vertices = cls._ascii_read_vertices(f, scaling)
Expand All@@ -109,36 +112,47 @@ def _ascii_read_vertices(cls, f, scaling):

vertices = np.empty((num_points, 3))

for i in range(num_points):
i=0

while i < num_points:
coordinates = f.readline().split()
vertices[i, 0] = float(coordinates[0]) * scaling
vertices[i, 1] = float(coordinates[1]) * scaling
vertices[i, 2] = float(coordinates[2]) * scaling

j=0

while j < np.size(coordinates):
vertices[i, 0] = float(coordinates[j]) * scaling
vertices[i, 1] = float(coordinates[j+1]) * scaling
vertices[i, 2] = float(coordinates[j+2]) * scaling
j += 3
i += 1

return vertices

@classmethod
def _ascii_read_triangles(cls, f):

match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
#match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
match = False

while not match:
match = re.match("POLYGONS\s*([0-9]*)\s*([0-9]*)", f.readline())

if not match:
raise RuntimeError("Unrecognised dataset encountered in vtk file.")
num_triangles = int(match.group(1))
triangles = np.empty((num_triangles, 3), dtype=np.int32)
for i in range(num_triangles):
triangle_specification = f.readline().split()

#assert triangle specification[0] == 3
triangles[i, 0] = int(triangle_specification[1])
triangles[i, 1] = int(triangle_specification[2])
triangles[i, 2] = int(triangle_specification[3])

assert f.readline().split()[0] == 'CELL_TYPES'
for i in range(num_triangles):
assert int(f.readline().strip()) == 5

return triangles

@classmethod
def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
def my_export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
"""
Write a mesh instance to a vtk mesh file (.vtk) with optional cell and point data.

Expand All@@ -152,7 +166,8 @@ def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=V
equal to the number of vertices in the mesh.
:param str mode: The file format to write: 'ascii' or 'binary' (default='ascii').
"""

print('\n\n***WARNING***\n\nMY_EXPORT_VTK: still to be revised & NO normals & other missing data\n\n')

if not isinstance(mesh, Mesh):
raise ValueError("The mesh argument to write_vtk() must be a valid Raysect Mesh primitive object.")

Expand All@@ -170,12 +185,13 @@ def _write_ascii(cls, mesh, filename, triangle_data=None, vertex_data=None):

with open(filename, 'w') as f:

# # vtk DataFile Version 2.0
# My Raysect mesh data
# # vtk DataFile Version 4.2
# vtk output
# ASCII
mesh_name = (mesh.name or 'RaysectMesh').replace(" ", "_")
f.write('# vtk DataFile Version 2.0\n')
f.write('{}\n'.format(mesh_name))
f.write('# vtk DataFile Version 4.2\n')
#f.write('{}\n'.format(mesh_name))
f.write('vtk output\n')
f.write('ASCII\n')

cls._ascii_write_geometry(f, mesh)
Expand All@@ -194,32 +210,39 @@ def _ascii_write_geometry(cls, f, mesh):
num_triangles = mesh.data.triangles.shape[0]
num_vertices = mesh.data.vertices.shape[0]

# DATASET UNSTRUCTURED_GRID
# POINTS 5081 float
# 5.12135678592 3.59400404579 5.20377763887
# 5.07735666785 3.40460816029 5.27386350545
# DATASET POLYDATA
# POINTS 36013 float
# 5.12135678592 3.59400404579 5.20377763887 5.07735666785 3.40460816029 5.27386350545
# ...
f.write('DATASET UNSTRUCTURED_GRID\n')
f.write('DATASET POLYDATA\n')
f.write('POINTS {} float\n'.format(num_vertices))
for i in range(num_vertices):
f.write('{} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))

# CELLS 9804 39216
i = 0

while i < num_vertices:
j = 0
while i < num_vertices and j < 3:
f.write('{} {} {} '.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))
i += 1
j += 1
f.write('\n')

f.write('METADATA\nINFORMATION 2\n')
f.write('NAME L2_NORM_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n')
f.write('NAME L2_NORM_FINITE_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n\n')


# POLYGONS 9804 39216

# 3 447 4361 446
# 3 444 4248 445
# ...
f.write('CELLS {} {}\n'.format(num_triangles, 4 * num_triangles))
f.write('POLYGONS {} {}\n'.format(num_triangles, 4 * num_triangles))
for i in range(num_triangles):
f.write('3 {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2]))

# CELL_TYPES 9804
# 5
# 5
# ...
f.write('CELL_TYPES {}\n'.format(num_triangles))
for i in range(num_triangles):
f.write('5\n')

@classmethod
def _ascii_write_vertex_data(cls, f, mesh, vertex_data):
raise NotImplementedError("write_vtk() does not currently support mesh vertex data.")
Expand All@@ -237,7 +260,7 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
# ...

num_triangles = mesh.data.triangles.shape[0]
f.write('CELL_DATA {}\n'.format(num_triangles))
f.write('\nCELL_DATA {}\n'.format(num_triangles))

error_msg = "The triangle_data argument in write_vtk() must be a dictionary or arrays/lists " \
"with length equal to the number of triangles."
Expand All@@ -253,11 +276,19 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
except TypeError:
raise ValueError(error_msg)

f.write('SCALARS {} FLOAT\n'.format(var_name.replace(" ", "_")))
f.write('LOOKUP_TABLE default\n')
for value in values:
f.write('{}\n'.format(value))
f.write('FIELD FieldData 1\n')
f.write('GroupIds 1 {} float\n'.format(num_triangles))

i = 0

while i < num_triangles:
j = 0
while i < num_triangles and j < 9:
f.write('{} '.format(values[i]))
i += 1
j += 1
f.write('\n')


import_vtk = VTKHandler.import_vtk
export_vtk = VTKHandler.export_vtk
my_import_vtk = VTKHandler.my_import_vtk
my_export_vtk = VTKHandler.my_export_vtk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 73 additions & 42 deletions raysect/primitive/mesh/vtk.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,14 +46,17 @@
class VTKHandler:

@classmethod
def import_vtk(cls, filename, scaling=1.0, mode=VTK_AUTOMATIC, **kwargs):
def my_import_vtk(cls, filename, scaling=1e-3, mode=VTK_AUTOMATIC, **kwargs):
"""
Create a mesh instance from a VTK mesh data file (.vtk).

.. warning ::
Currently only supports VTK DataFile v2.0 and unstructured grid data with
3 element (triangular) cells.

.. warning ::
Trying to update the version to be able to read VTK DataFile 4.2.

:param str filename: Mesh file path.
:param double scaling: Scale the mesh by this factor (default=1.0).
:param str mode: The file format to load: 'ascii', 'binary', 'auto' (default='auto').
Expand DownExpand Up@@ -87,11 +90,11 @@ def _load_ascii(cls, filename, scaling):
with open(filename, 'r') as f:

# parse the file header
assert f.readline().strip() == "# vtk DataFile Version 2.0"
assert f.readline().strip() == "# vtk DataFile Version 4.2"
mesh_name = f.readline().strip()
assert f.readline().strip() == "ASCII"

if not f.readline().strip() == "DATASET UNSTRUCTURED_GRID":
if not f.readline().strip() == "DATASET POLYDATA":
raise RuntimeError("Unrecognised dataset encountered in vtk file.")

vertices = cls._ascii_read_vertices(f, scaling)
Expand All@@ -109,36 +112,47 @@ def _ascii_read_vertices(cls, f, scaling):

vertices = np.empty((num_points, 3))

for i in range(num_points):
i=0

while i < num_points:
coordinates = f.readline().split()
vertices[i, 0] = float(coordinates[0]) * scaling
vertices[i, 1] = float(coordinates[1]) * scaling
vertices[i, 2] = float(coordinates[2]) * scaling

j=0

while j < np.size(coordinates):
vertices[i, 0] = float(coordinates[j]) * scaling
vertices[i, 1] = float(coordinates[j+1]) * scaling
vertices[i, 2] = float(coordinates[j+2]) * scaling
j += 3
i += 1

return vertices

@classmethod
def _ascii_read_triangles(cls, f):

match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
#match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
match = False

while not match:
match = re.match("POLYGONS\s*([0-9]*)\s*([0-9]*)", f.readline())

if not match:
raise RuntimeError("Unrecognised dataset encountered in vtk file.")
num_triangles = int(match.group(1))
triangles = np.empty((num_triangles, 3), dtype=np.int32)
for i in range(num_triangles):
triangle_specification = f.readline().split()

#assert triangle specification[0] == 3
triangles[i, 0] = int(triangle_specification[1])
triangles[i, 1] = int(triangle_specification[2])
triangles[i, 2] = int(triangle_specification[3])

assert f.readline().split()[0] == 'CELL_TYPES'
for i in range(num_triangles):
assert int(f.readline().strip()) == 5

return triangles

@classmethod
def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
def my_export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
"""
Write a mesh instance to a vtk mesh file (.vtk) with optional cell and point data.

Expand All@@ -152,7 +166,8 @@ def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=V
equal to the number of vertices in the mesh.
:param str mode: The file format to write: 'ascii' or 'binary' (default='ascii').
"""

print('\n\n***WARNING***\n\nMY_EXPORT_VTK: still to be revised & NO normals & other missing data\n\n')

if not isinstance(mesh, Mesh):
raise ValueError("The mesh argument to write_vtk() must be a valid Raysect Mesh primitive object.")

Expand All@@ -170,12 +185,13 @@ def _write_ascii(cls, mesh, filename, triangle_data=None, vertex_data=None):

with open(filename, 'w') as f:

# # vtk DataFile Version 2.0
# My Raysect mesh data
# # vtk DataFile Version 4.2
# vtk output
# ASCII
mesh_name = (mesh.name or 'RaysectMesh').replace(" ", "_")
f.write('# vtk DataFile Version 2.0\n')
f.write('{}\n'.format(mesh_name))
f.write('# vtk DataFile Version 4.2\n')
#f.write('{}\n'.format(mesh_name))
f.write('vtk output\n')
f.write('ASCII\n')

cls._ascii_write_geometry(f, mesh)
Expand All@@ -194,32 +210,39 @@ def _ascii_write_geometry(cls, f, mesh):
num_triangles = mesh.data.triangles.shape[0]
num_vertices = mesh.data.vertices.shape[0]

# DATASET UNSTRUCTURED_GRID
# POINTS 5081 float
# 5.12135678592 3.59400404579 5.20377763887
# 5.07735666785 3.40460816029 5.27386350545
# DATASET POLYDATA
# POINTS 36013 float
# 5.12135678592 3.59400404579 5.20377763887 5.07735666785 3.40460816029 5.27386350545
# ...
f.write('DATASET UNSTRUCTURED_GRID\n')
f.write('DATASET POLYDATA\n')
f.write('POINTS {} float\n'.format(num_vertices))
for i in range(num_vertices):
f.write('{} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))

# CELLS 9804 39216
i = 0

while i < num_vertices:
j = 0
while i < num_vertices and j < 3:
f.write('{} {} {} '.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))
i += 1
j += 1
f.write('\n')

f.write('METADATA\nINFORMATION 2\n')
f.write('NAME L2_NORM_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n')
f.write('NAME L2_NORM_FINITE_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n\n')


# POLYGONS 9804 39216

# 3 447 4361 446
# 3 444 4248 445
# ...
f.write('CELLS {} {}\n'.format(num_triangles, 4 * num_triangles))
f.write('POLYGONS {} {}\n'.format(num_triangles, 4 * num_triangles))
for i in range(num_triangles):
f.write('3 {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2]))

# CELL_TYPES 9804
# 5
# 5
# ...
f.write('CELL_TYPES {}\n'.format(num_triangles))
for i in range(num_triangles):
f.write('5\n')

@classmethod
def _ascii_write_vertex_data(cls, f, mesh, vertex_data):
raise NotImplementedError("write_vtk() does not currently support mesh vertex data.")
Expand All@@ -237,7 +260,7 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
# ...

num_triangles = mesh.data.triangles.shape[0]
f.write('CELL_DATA {}\n'.format(num_triangles))
f.write('\nCELL_DATA {}\n'.format(num_triangles))

error_msg = "The triangle_data argument in write_vtk() must be a dictionary or arrays/lists " \
"with length equal to the number of triangles."
Expand All@@ -253,11 +276,19 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
except TypeError:
raise ValueError(error_msg)

f.write('SCALARS {} FLOAT\n'.format(var_name.replace(" ", "_")))
f.write('LOOKUP_TABLE default\n')
for value in values:
f.write('{}\n'.format(value))
f.write('FIELD FieldData 1\n')
f.write('GroupIds 1 {} float\n'.format(num_triangles))

i = 0

while i < num_triangles:
j = 0
while i < num_triangles and j < 9:
f.write('{} '.format(values[i]))
i += 1
j += 1
f.write('\n')


import_vtk = VTKHandler.import_vtk
export_vtk = VTKHandler.export_vtk
my_import_vtk = VTKHandler.my_import_vtk
my_export_vtk = VTKHandler.my_export_vtk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 73 additions & 42 deletions raysect/primitive/mesh/vtk.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,14 +46,17 @@
class VTKHandler:

@classmethod
def import_vtk(cls, filename, scaling=1.0, mode=VTK_AUTOMATIC, **kwargs):
def my_import_vtk(cls, filename, scaling=1e-3, mode=VTK_AUTOMATIC, **kwargs):
"""
Create a mesh instance from a VTK mesh data file (.vtk).

.. warning ::
Currently only supports VTK DataFile v2.0 and unstructured grid data with
3 element (triangular) cells.

.. warning ::
Trying to update the version to be able to read VTK DataFile 4.2.

:param str filename: Mesh file path.
:param double scaling: Scale the mesh by this factor (default=1.0).
:param str mode: The file format to load: 'ascii', 'binary', 'auto' (default='auto').
Expand DownExpand Up@@ -87,11 +90,11 @@ def _load_ascii(cls, filename, scaling):
with open(filename, 'r') as f:

# parse the file header
assert f.readline().strip() == "# vtk DataFile Version 2.0"
assert f.readline().strip() == "# vtk DataFile Version 4.2"
mesh_name = f.readline().strip()
assert f.readline().strip() == "ASCII"

if not f.readline().strip() == "DATASET UNSTRUCTURED_GRID":
if not f.readline().strip() == "DATASET POLYDATA":
raise RuntimeError("Unrecognised dataset encountered in vtk file.")

vertices = cls._ascii_read_vertices(f, scaling)
Expand All@@ -109,36 +112,47 @@ def _ascii_read_vertices(cls, f, scaling):

vertices = np.empty((num_points, 3))

for i in range(num_points):
i=0

while i < num_points:
coordinates = f.readline().split()
vertices[i, 0] = float(coordinates[0]) * scaling
vertices[i, 1] = float(coordinates[1]) * scaling
vertices[i, 2] = float(coordinates[2]) * scaling

j=0

while j < np.size(coordinates):
vertices[i, 0] = float(coordinates[j]) * scaling
vertices[i, 1] = float(coordinates[j+1]) * scaling
vertices[i, 2] = float(coordinates[j+2]) * scaling
j += 3
i += 1

return vertices

@classmethod
def _ascii_read_triangles(cls, f):

match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
#match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
match = False

while not match:
match = re.match("POLYGONS\s*([0-9]*)\s*([0-9]*)", f.readline())

if not match:
raise RuntimeError("Unrecognised dataset encountered in vtk file.")
num_triangles = int(match.group(1))
triangles = np.empty((num_triangles, 3), dtype=np.int32)
for i in range(num_triangles):
triangle_specification = f.readline().split()

#assert triangle specification[0] == 3
triangles[i, 0] = int(triangle_specification[1])
triangles[i, 1] = int(triangle_specification[2])
triangles[i, 2] = int(triangle_specification[3])

assert f.readline().split()[0] == 'CELL_TYPES'
for i in range(num_triangles):
assert int(f.readline().strip()) == 5

return triangles

@classmethod
def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
def my_export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
"""
Write a mesh instance to a vtk mesh file (.vtk) with optional cell and point data.

Expand All@@ -152,7 +166,8 @@ def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=V
equal to the number of vertices in the mesh.
:param str mode: The file format to write: 'ascii' or 'binary' (default='ascii').
"""

print('\n\n***WARNING***\n\nMY_EXPORT_VTK: still to be revised & NO normals & other missing data\n\n')

if not isinstance(mesh, Mesh):
raise ValueError("The mesh argument to write_vtk() must be a valid Raysect Mesh primitive object.")

Expand All@@ -170,12 +185,13 @@ def _write_ascii(cls, mesh, filename, triangle_data=None, vertex_data=None):

with open(filename, 'w') as f:

# # vtk DataFile Version 2.0
# My Raysect mesh data
# # vtk DataFile Version 4.2
# vtk output
# ASCII
mesh_name = (mesh.name or 'RaysectMesh').replace(" ", "_")
f.write('# vtk DataFile Version 2.0\n')
f.write('{}\n'.format(mesh_name))
f.write('# vtk DataFile Version 4.2\n')
#f.write('{}\n'.format(mesh_name))
f.write('vtk output\n')
f.write('ASCII\n')

cls._ascii_write_geometry(f, mesh)
Expand All@@ -194,32 +210,39 @@ def _ascii_write_geometry(cls, f, mesh):
num_triangles = mesh.data.triangles.shape[0]
num_vertices = mesh.data.vertices.shape[0]

# DATASET UNSTRUCTURED_GRID
# POINTS 5081 float
# 5.12135678592 3.59400404579 5.20377763887
# 5.07735666785 3.40460816029 5.27386350545
# DATASET POLYDATA
# POINTS 36013 float
# 5.12135678592 3.59400404579 5.20377763887 5.07735666785 3.40460816029 5.27386350545
# ...
f.write('DATASET UNSTRUCTURED_GRID\n')
f.write('DATASET POLYDATA\n')
f.write('POINTS {} float\n'.format(num_vertices))
for i in range(num_vertices):
f.write('{} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))

# CELLS 9804 39216
i = 0

while i < num_vertices:
j = 0
while i < num_vertices and j < 3:
f.write('{} {} {} '.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))
i += 1
j += 1
f.write('\n')

f.write('METADATA\nINFORMATION 2\n')
f.write('NAME L2_NORM_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n')
f.write('NAME L2_NORM_FINITE_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n\n')


# POLYGONS 9804 39216

# 3 447 4361 446
# 3 444 4248 445
# ...
f.write('CELLS {} {}\n'.format(num_triangles, 4 * num_triangles))
f.write('POLYGONS {} {}\n'.format(num_triangles, 4 * num_triangles))
for i in range(num_triangles):
f.write('3 {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2]))

# CELL_TYPES 9804
# 5
# 5
# ...
f.write('CELL_TYPES {}\n'.format(num_triangles))
for i in range(num_triangles):
f.write('5\n')

@classmethod
def _ascii_write_vertex_data(cls, f, mesh, vertex_data):
raise NotImplementedError("write_vtk() does not currently support mesh vertex data.")
Expand All@@ -237,7 +260,7 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
# ...

num_triangles = mesh.data.triangles.shape[0]
f.write('CELL_DATA {}\n'.format(num_triangles))
f.write('\nCELL_DATA {}\n'.format(num_triangles))

error_msg = "The triangle_data argument in write_vtk() must be a dictionary or arrays/lists " \
"with length equal to the number of triangles."
Expand All@@ -253,11 +276,19 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
except TypeError:
raise ValueError(error_msg)

f.write('SCALARS {} FLOAT\n'.format(var_name.replace(" ", "_")))
f.write('LOOKUP_TABLE default\n')
for value in values:
f.write('{}\n'.format(value))
f.write('FIELD FieldData 1\n')
f.write('GroupIds 1 {} float\n'.format(num_triangles))

i = 0

while i < num_triangles:
j = 0
while i < num_triangles and j < 9:
f.write('{} '.format(values[i]))
i += 1
j += 1
f.write('\n')


import_vtk = VTKHandler.import_vtk
export_vtk = VTKHandler.export_vtk
my_import_vtk = VTKHandler.my_import_vtk
my_export_vtk = VTKHandler.my_export_vtk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 73 additions & 42 deletions raysect/primitive/mesh/vtk.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,14 +46,17 @@
class VTKHandler:

@classmethod
def import_vtk(cls, filename, scaling=1.0, mode=VTK_AUTOMATIC, **kwargs):
def my_import_vtk(cls, filename, scaling=1e-3, mode=VTK_AUTOMATIC, **kwargs):
"""
Create a mesh instance from a VTK mesh data file (.vtk).

.. warning ::
Currently only supports VTK DataFile v2.0 and unstructured grid data with
3 element (triangular) cells.

.. warning ::
Trying to update the version to be able to read VTK DataFile 4.2.

:param str filename: Mesh file path.
:param double scaling: Scale the mesh by this factor (default=1.0).
:param str mode: The file format to load: 'ascii', 'binary', 'auto' (default='auto').
Expand DownExpand Up@@ -87,11 +90,11 @@ def _load_ascii(cls, filename, scaling):
with open(filename, 'r') as f:

# parse the file header
assert f.readline().strip() == "# vtk DataFile Version 2.0"
assert f.readline().strip() == "# vtk DataFile Version 4.2"
mesh_name = f.readline().strip()
assert f.readline().strip() == "ASCII"

if not f.readline().strip() == "DATASET UNSTRUCTURED_GRID":
if not f.readline().strip() == "DATASET POLYDATA":
raise RuntimeError("Unrecognised dataset encountered in vtk file.")

vertices = cls._ascii_read_vertices(f, scaling)
Expand All@@ -109,36 +112,47 @@ def _ascii_read_vertices(cls, f, scaling):

vertices = np.empty((num_points, 3))

for i in range(num_points):
i=0

while i < num_points:
coordinates = f.readline().split()
vertices[i, 0] = float(coordinates[0]) * scaling
vertices[i, 1] = float(coordinates[1]) * scaling
vertices[i, 2] = float(coordinates[2]) * scaling

j=0

while j < np.size(coordinates):
vertices[i, 0] = float(coordinates[j]) * scaling
vertices[i, 1] = float(coordinates[j+1]) * scaling
vertices[i, 2] = float(coordinates[j+2]) * scaling
j += 3
i += 1

return vertices

@classmethod
def _ascii_read_triangles(cls, f):

match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
#match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
match = False

while not match:
match = re.match("POLYGONS\s*([0-9]*)\s*([0-9]*)", f.readline())

if not match:
raise RuntimeError("Unrecognised dataset encountered in vtk file.")
num_triangles = int(match.group(1))
triangles = np.empty((num_triangles, 3), dtype=np.int32)
for i in range(num_triangles):
triangle_specification = f.readline().split()

#assert triangle specification[0] == 3
triangles[i, 0] = int(triangle_specification[1])
triangles[i, 1] = int(triangle_specification[2])
triangles[i, 2] = int(triangle_specification[3])

assert f.readline().split()[0] == 'CELL_TYPES'
for i in range(num_triangles):
assert int(f.readline().strip()) == 5

return triangles

@classmethod
def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
def my_export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
"""
Write a mesh instance to a vtk mesh file (.vtk) with optional cell and point data.

Expand All@@ -152,7 +166,8 @@ def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=V
equal to the number of vertices in the mesh.
:param str mode: The file format to write: 'ascii' or 'binary' (default='ascii').
"""

print('\n\n***WARNING***\n\nMY_EXPORT_VTK: still to be revised & NO normals & other missing data\n\n')

if not isinstance(mesh, Mesh):
raise ValueError("The mesh argument to write_vtk() must be a valid Raysect Mesh primitive object.")

Expand All@@ -170,12 +185,13 @@ def _write_ascii(cls, mesh, filename, triangle_data=None, vertex_data=None):

with open(filename, 'w') as f:

# # vtk DataFile Version 2.0
# My Raysect mesh data
# # vtk DataFile Version 4.2
# vtk output
# ASCII
mesh_name = (mesh.name or 'RaysectMesh').replace(" ", "_")
f.write('# vtk DataFile Version 2.0\n')
f.write('{}\n'.format(mesh_name))
f.write('# vtk DataFile Version 4.2\n')
#f.write('{}\n'.format(mesh_name))
f.write('vtk output\n')
f.write('ASCII\n')

cls._ascii_write_geometry(f, mesh)
Expand All@@ -194,32 +210,39 @@ def _ascii_write_geometry(cls, f, mesh):
num_triangles = mesh.data.triangles.shape[0]
num_vertices = mesh.data.vertices.shape[0]

# DATASET UNSTRUCTURED_GRID
# POINTS 5081 float
# 5.12135678592 3.59400404579 5.20377763887
# 5.07735666785 3.40460816029 5.27386350545
# DATASET POLYDATA
# POINTS 36013 float
# 5.12135678592 3.59400404579 5.20377763887 5.07735666785 3.40460816029 5.27386350545
# ...
f.write('DATASET UNSTRUCTURED_GRID\n')
f.write('DATASET POLYDATA\n')
f.write('POINTS {} float\n'.format(num_vertices))
for i in range(num_vertices):
f.write('{} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))

# CELLS 9804 39216
i = 0

while i < num_vertices:
j = 0
while i < num_vertices and j < 3:
f.write('{} {} {} '.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))
i += 1
j += 1
f.write('\n')

f.write('METADATA\nINFORMATION 2\n')
f.write('NAME L2_NORM_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n')
f.write('NAME L2_NORM_FINITE_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n\n')


# POLYGONS 9804 39216

# 3 447 4361 446
# 3 444 4248 445
# ...
f.write('CELLS {} {}\n'.format(num_triangles, 4 * num_triangles))
f.write('POLYGONS {} {}\n'.format(num_triangles, 4 * num_triangles))
for i in range(num_triangles):
f.write('3 {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2]))

# CELL_TYPES 9804
# 5
# 5
# ...
f.write('CELL_TYPES {}\n'.format(num_triangles))
for i in range(num_triangles):
f.write('5\n')

@classmethod
def _ascii_write_vertex_data(cls, f, mesh, vertex_data):
raise NotImplementedError("write_vtk() does not currently support mesh vertex data.")
Expand All@@ -237,7 +260,7 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
# ...

num_triangles = mesh.data.triangles.shape[0]
f.write('CELL_DATA {}\n'.format(num_triangles))
f.write('\nCELL_DATA {}\n'.format(num_triangles))

error_msg = "The triangle_data argument in write_vtk() must be a dictionary or arrays/lists " \
"with length equal to the number of triangles."
Expand All@@ -253,11 +276,19 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
except TypeError:
raise ValueError(error_msg)

f.write('SCALARS {} FLOAT\n'.format(var_name.replace(" ", "_")))
f.write('LOOKUP_TABLE default\n')
for value in values:
f.write('{}\n'.format(value))
f.write('FIELD FieldData 1\n')
f.write('GroupIds 1 {} float\n'.format(num_triangles))

i = 0

while i < num_triangles:
j = 0
while i < num_triangles and j < 9:
f.write('{} '.format(values[i]))
i += 1
j += 1
f.write('\n')


import_vtk = VTKHandler.import_vtk
export_vtk = VTKHandler.export_vtk
my_import_vtk = VTKHandler.my_import_vtk
my_export_vtk = VTKHandler.my_export_vtk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 73 additions & 42 deletions raysect/primitive/mesh/vtk.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,14 +46,17 @@
class VTKHandler:

@classmethod
def import_vtk(cls, filename, scaling=1.0, mode=VTK_AUTOMATIC, **kwargs):
def my_import_vtk(cls, filename, scaling=1e-3, mode=VTK_AUTOMATIC, **kwargs):
"""
Create a mesh instance from a VTK mesh data file (.vtk).

.. warning ::
Currently only supports VTK DataFile v2.0 and unstructured grid data with
3 element (triangular) cells.

.. warning ::
Trying to update the version to be able to read VTK DataFile 4.2.

:param str filename: Mesh file path.
:param double scaling: Scale the mesh by this factor (default=1.0).
:param str mode: The file format to load: 'ascii', 'binary', 'auto' (default='auto').
Expand DownExpand Up@@ -87,11 +90,11 @@ def _load_ascii(cls, filename, scaling):
with open(filename, 'r') as f:

# parse the file header
assert f.readline().strip() == "# vtk DataFile Version 2.0"
assert f.readline().strip() == "# vtk DataFile Version 4.2"
mesh_name = f.readline().strip()
assert f.readline().strip() == "ASCII"

if not f.readline().strip() == "DATASET UNSTRUCTURED_GRID":
if not f.readline().strip() == "DATASET POLYDATA":
raise RuntimeError("Unrecognised dataset encountered in vtk file.")

vertices = cls._ascii_read_vertices(f, scaling)
Expand All@@ -109,36 +112,47 @@ def _ascii_read_vertices(cls, f, scaling):

vertices = np.empty((num_points, 3))

for i in range(num_points):
i=0

while i < num_points:
coordinates = f.readline().split()
vertices[i, 0] = float(coordinates[0]) * scaling
vertices[i, 1] = float(coordinates[1]) * scaling
vertices[i, 2] = float(coordinates[2]) * scaling

j=0

while j < np.size(coordinates):
vertices[i, 0] = float(coordinates[j]) * scaling
vertices[i, 1] = float(coordinates[j+1]) * scaling
vertices[i, 2] = float(coordinates[j+2]) * scaling
j += 3
i += 1

return vertices

@classmethod
def _ascii_read_triangles(cls, f):

match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
#match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
match = False

while not match:
match = re.match("POLYGONS\s*([0-9]*)\s*([0-9]*)", f.readline())

if not match:
raise RuntimeError("Unrecognised dataset encountered in vtk file.")
num_triangles = int(match.group(1))
triangles = np.empty((num_triangles, 3), dtype=np.int32)
for i in range(num_triangles):
triangle_specification = f.readline().split()

#assert triangle specification[0] == 3
triangles[i, 0] = int(triangle_specification[1])
triangles[i, 1] = int(triangle_specification[2])
triangles[i, 2] = int(triangle_specification[3])

assert f.readline().split()[0] == 'CELL_TYPES'
for i in range(num_triangles):
assert int(f.readline().strip()) == 5

return triangles

@classmethod
def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
def my_export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
"""
Write a mesh instance to a vtk mesh file (.vtk) with optional cell and point data.

Expand All@@ -152,7 +166,8 @@ def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=V
equal to the number of vertices in the mesh.
:param str mode: The file format to write: 'ascii' or 'binary' (default='ascii').
"""

print('\n\n***WARNING***\n\nMY_EXPORT_VTK: still to be revised & NO normals & other missing data\n\n')

if not isinstance(mesh, Mesh):
raise ValueError("The mesh argument to write_vtk() must be a valid Raysect Mesh primitive object.")

Expand All@@ -170,12 +185,13 @@ def _write_ascii(cls, mesh, filename, triangle_data=None, vertex_data=None):

with open(filename, 'w') as f:

# # vtk DataFile Version 2.0
# My Raysect mesh data
# # vtk DataFile Version 4.2
# vtk output
# ASCII
mesh_name = (mesh.name or 'RaysectMesh').replace(" ", "_")
f.write('# vtk DataFile Version 2.0\n')
f.write('{}\n'.format(mesh_name))
f.write('# vtk DataFile Version 4.2\n')
#f.write('{}\n'.format(mesh_name))
f.write('vtk output\n')
f.write('ASCII\n')

cls._ascii_write_geometry(f, mesh)
Expand All@@ -194,32 +210,39 @@ def _ascii_write_geometry(cls, f, mesh):
num_triangles = mesh.data.triangles.shape[0]
num_vertices = mesh.data.vertices.shape[0]

# DATASET UNSTRUCTURED_GRID
# POINTS 5081 float
# 5.12135678592 3.59400404579 5.20377763887
# 5.07735666785 3.40460816029 5.27386350545
# DATASET POLYDATA
# POINTS 36013 float
# 5.12135678592 3.59400404579 5.20377763887 5.07735666785 3.40460816029 5.27386350545
# ...
f.write('DATASET UNSTRUCTURED_GRID\n')
f.write('DATASET POLYDATA\n')
f.write('POINTS {} float\n'.format(num_vertices))
for i in range(num_vertices):
f.write('{} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))

# CELLS 9804 39216
i = 0

while i < num_vertices:
j = 0
while i < num_vertices and j < 3:
f.write('{} {} {} '.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))
i += 1
j += 1
f.write('\n')

f.write('METADATA\nINFORMATION 2\n')
f.write('NAME L2_NORM_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n')
f.write('NAME L2_NORM_FINITE_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n\n')


# POLYGONS 9804 39216

# 3 447 4361 446
# 3 444 4248 445
# ...
f.write('CELLS {} {}\n'.format(num_triangles, 4 * num_triangles))
f.write('POLYGONS {} {}\n'.format(num_triangles, 4 * num_triangles))
for i in range(num_triangles):
f.write('3 {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2]))

# CELL_TYPES 9804
# 5
# 5
# ...
f.write('CELL_TYPES {}\n'.format(num_triangles))
for i in range(num_triangles):
f.write('5\n')

@classmethod
def _ascii_write_vertex_data(cls, f, mesh, vertex_data):
raise NotImplementedError("write_vtk() does not currently support mesh vertex data.")
Expand All@@ -237,7 +260,7 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
# ...

num_triangles = mesh.data.triangles.shape[0]
f.write('CELL_DATA {}\n'.format(num_triangles))
f.write('\nCELL_DATA {}\n'.format(num_triangles))

error_msg = "The triangle_data argument in write_vtk() must be a dictionary or arrays/lists " \
"with length equal to the number of triangles."
Expand All@@ -253,11 +276,19 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
except TypeError:
raise ValueError(error_msg)

f.write('SCALARS {} FLOAT\n'.format(var_name.replace(" ", "_")))
f.write('LOOKUP_TABLE default\n')
for value in values:
f.write('{}\n'.format(value))
f.write('FIELD FieldData 1\n')
f.write('GroupIds 1 {} float\n'.format(num_triangles))

i = 0

while i < num_triangles:
j = 0
while i < num_triangles and j < 9:
f.write('{} '.format(values[i]))
i += 1
j += 1
f.write('\n')


import_vtk = VTKHandler.import_vtk
export_vtk = VTKHandler.export_vtk
my_import_vtk = VTKHandler.my_import_vtk
my_export_vtk = VTKHandler.my_export_vtk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 73 additions & 42 deletions raysect/primitive/mesh/vtk.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,14 +46,17 @@
class VTKHandler:

@classmethod
def import_vtk(cls, filename, scaling=1.0, mode=VTK_AUTOMATIC, **kwargs):
def my_import_vtk(cls, filename, scaling=1e-3, mode=VTK_AUTOMATIC, **kwargs):
"""
Create a mesh instance from a VTK mesh data file (.vtk).

.. warning ::
Currently only supports VTK DataFile v2.0 and unstructured grid data with
3 element (triangular) cells.

.. warning ::
Trying to update the version to be able to read VTK DataFile 4.2.

:param str filename: Mesh file path.
:param double scaling: Scale the mesh by this factor (default=1.0).
:param str mode: The file format to load: 'ascii', 'binary', 'auto' (default='auto').
Expand DownExpand Up@@ -87,11 +90,11 @@ def _load_ascii(cls, filename, scaling):
with open(filename, 'r') as f:

# parse the file header
assert f.readline().strip() == "# vtk DataFile Version 2.0"
assert f.readline().strip() == "# vtk DataFile Version 4.2"
mesh_name = f.readline().strip()
assert f.readline().strip() == "ASCII"

if not f.readline().strip() == "DATASET UNSTRUCTURED_GRID":
if not f.readline().strip() == "DATASET POLYDATA":
raise RuntimeError("Unrecognised dataset encountered in vtk file.")

vertices = cls._ascii_read_vertices(f, scaling)
Expand All@@ -109,36 +112,47 @@ def _ascii_read_vertices(cls, f, scaling):

vertices = np.empty((num_points, 3))

for i in range(num_points):
i=0

while i < num_points:
coordinates = f.readline().split()
vertices[i, 0] = float(coordinates[0]) * scaling
vertices[i, 1] = float(coordinates[1]) * scaling
vertices[i, 2] = float(coordinates[2]) * scaling

j=0

while j < np.size(coordinates):
vertices[i, 0] = float(coordinates[j]) * scaling
vertices[i, 1] = float(coordinates[j+1]) * scaling
vertices[i, 2] = float(coordinates[j+2]) * scaling
j += 3
i += 1

return vertices

@classmethod
def _ascii_read_triangles(cls, f):

match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
#match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
match = False

while not match:
match = re.match("POLYGONS\s*([0-9]*)\s*([0-9]*)", f.readline())

if not match:
raise RuntimeError("Unrecognised dataset encountered in vtk file.")
num_triangles = int(match.group(1))
triangles = np.empty((num_triangles, 3), dtype=np.int32)
for i in range(num_triangles):
triangle_specification = f.readline().split()

#assert triangle specification[0] == 3
triangles[i, 0] = int(triangle_specification[1])
triangles[i, 1] = int(triangle_specification[2])
triangles[i, 2] = int(triangle_specification[3])

assert f.readline().split()[0] == 'CELL_TYPES'
for i in range(num_triangles):
assert int(f.readline().strip()) == 5

return triangles

@classmethod
def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
def my_export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
"""
Write a mesh instance to a vtk mesh file (.vtk) with optional cell and point data.

Expand All@@ -152,7 +166,8 @@ def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=V
equal to the number of vertices in the mesh.
:param str mode: The file format to write: 'ascii' or 'binary' (default='ascii').
"""

print('\n\n***WARNING***\n\nMY_EXPORT_VTK: still to be revised & NO normals & other missing data\n\n')

if not isinstance(mesh, Mesh):
raise ValueError("The mesh argument to write_vtk() must be a valid Raysect Mesh primitive object.")

Expand All@@ -170,12 +185,13 @@ def _write_ascii(cls, mesh, filename, triangle_data=None, vertex_data=None):

with open(filename, 'w') as f:

# # vtk DataFile Version 2.0
# My Raysect mesh data
# # vtk DataFile Version 4.2
# vtk output
# ASCII
mesh_name = (mesh.name or 'RaysectMesh').replace(" ", "_")
f.write('# vtk DataFile Version 2.0\n')
f.write('{}\n'.format(mesh_name))
f.write('# vtk DataFile Version 4.2\n')
#f.write('{}\n'.format(mesh_name))
f.write('vtk output\n')
f.write('ASCII\n')

cls._ascii_write_geometry(f, mesh)
Expand All@@ -194,32 +210,39 @@ def _ascii_write_geometry(cls, f, mesh):
num_triangles = mesh.data.triangles.shape[0]
num_vertices = mesh.data.vertices.shape[0]

# DATASET UNSTRUCTURED_GRID
# POINTS 5081 float
# 5.12135678592 3.59400404579 5.20377763887
# 5.07735666785 3.40460816029 5.27386350545
# DATASET POLYDATA
# POINTS 36013 float
# 5.12135678592 3.59400404579 5.20377763887 5.07735666785 3.40460816029 5.27386350545
# ...
f.write('DATASET UNSTRUCTURED_GRID\n')
f.write('DATASET POLYDATA\n')
f.write('POINTS {} float\n'.format(num_vertices))
for i in range(num_vertices):
f.write('{} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))

# CELLS 9804 39216
i = 0

while i < num_vertices:
j = 0
while i < num_vertices and j < 3:
f.write('{} {} {} '.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))
i += 1
j += 1
f.write('\n')

f.write('METADATA\nINFORMATION 2\n')
f.write('NAME L2_NORM_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n')
f.write('NAME L2_NORM_FINITE_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n\n')


# POLYGONS 9804 39216

# 3 447 4361 446
# 3 444 4248 445
# ...
f.write('CELLS {} {}\n'.format(num_triangles, 4 * num_triangles))
f.write('POLYGONS {} {}\n'.format(num_triangles, 4 * num_triangles))
for i in range(num_triangles):
f.write('3 {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2]))

# CELL_TYPES 9804
# 5
# 5
# ...
f.write('CELL_TYPES {}\n'.format(num_triangles))
for i in range(num_triangles):
f.write('5\n')

@classmethod
def _ascii_write_vertex_data(cls, f, mesh, vertex_data):
raise NotImplementedError("write_vtk() does not currently support mesh vertex data.")
Expand All@@ -237,7 +260,7 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
# ...

num_triangles = mesh.data.triangles.shape[0]
f.write('CELL_DATA {}\n'.format(num_triangles))
f.write('\nCELL_DATA {}\n'.format(num_triangles))

error_msg = "The triangle_data argument in write_vtk() must be a dictionary or arrays/lists " \
"with length equal to the number of triangles."
Expand All@@ -253,11 +276,19 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
except TypeError:
raise ValueError(error_msg)

f.write('SCALARS {} FLOAT\n'.format(var_name.replace(" ", "_")))
f.write('LOOKUP_TABLE default\n')
for value in values:
f.write('{}\n'.format(value))
f.write('FIELD FieldData 1\n')
f.write('GroupIds 1 {} float\n'.format(num_triangles))

i = 0

while i < num_triangles:
j = 0
while i < num_triangles and j < 9:
f.write('{} '.format(values[i]))
i += 1
j += 1
f.write('\n')


import_vtk = VTKHandler.import_vtk
export_vtk = VTKHandler.export_vtk
my_import_vtk = VTKHandler.my_import_vtk
my_export_vtk = VTKHandler.my_export_vtk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 73 additions & 42 deletions raysect/primitive/mesh/vtk.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,14 +46,17 @@
class VTKHandler:

@classmethod
def import_vtk(cls, filename, scaling=1.0, mode=VTK_AUTOMATIC, **kwargs):
def my_import_vtk(cls, filename, scaling=1e-3, mode=VTK_AUTOMATIC, **kwargs):
"""
Create a mesh instance from a VTK mesh data file (.vtk).

.. warning ::
Currently only supports VTK DataFile v2.0 and unstructured grid data with
3 element (triangular) cells.

.. warning ::
Trying to update the version to be able to read VTK DataFile 4.2.

:param str filename: Mesh file path.
:param double scaling: Scale the mesh by this factor (default=1.0).
:param str mode: The file format to load: 'ascii', 'binary', 'auto' (default='auto').
Expand DownExpand Up@@ -87,11 +90,11 @@ def _load_ascii(cls, filename, scaling):
with open(filename, 'r') as f:

# parse the file header
assert f.readline().strip() == "# vtk DataFile Version 2.0"
assert f.readline().strip() == "# vtk DataFile Version 4.2"
mesh_name = f.readline().strip()
assert f.readline().strip() == "ASCII"

if not f.readline().strip() == "DATASET UNSTRUCTURED_GRID":
if not f.readline().strip() == "DATASET POLYDATA":
raise RuntimeError("Unrecognised dataset encountered in vtk file.")

vertices = cls._ascii_read_vertices(f, scaling)
Expand All@@ -109,36 +112,47 @@ def _ascii_read_vertices(cls, f, scaling):

vertices = np.empty((num_points, 3))

for i in range(num_points):
i=0

while i < num_points:
coordinates = f.readline().split()
vertices[i, 0] = float(coordinates[0]) * scaling
vertices[i, 1] = float(coordinates[1]) * scaling
vertices[i, 2] = float(coordinates[2]) * scaling

j=0

while j < np.size(coordinates):
vertices[i, 0] = float(coordinates[j]) * scaling
vertices[i, 1] = float(coordinates[j+1]) * scaling
vertices[i, 2] = float(coordinates[j+2]) * scaling
j += 3
i += 1

return vertices

@classmethod
def _ascii_read_triangles(cls, f):

match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
#match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
match = False

while not match:
match = re.match("POLYGONS\s*([0-9]*)\s*([0-9]*)", f.readline())

if not match:
raise RuntimeError("Unrecognised dataset encountered in vtk file.")
num_triangles = int(match.group(1))
triangles = np.empty((num_triangles, 3), dtype=np.int32)
for i in range(num_triangles):
triangle_specification = f.readline().split()

#assert triangle specification[0] == 3
triangles[i, 0] = int(triangle_specification[1])
triangles[i, 1] = int(triangle_specification[2])
triangles[i, 2] = int(triangle_specification[3])

assert f.readline().split()[0] == 'CELL_TYPES'
for i in range(num_triangles):
assert int(f.readline().strip()) == 5

return triangles

@classmethod
def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
def my_export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
"""
Write a mesh instance to a vtk mesh file (.vtk) with optional cell and point data.

Expand All@@ -152,7 +166,8 @@ def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=V
equal to the number of vertices in the mesh.
:param str mode: The file format to write: 'ascii' or 'binary' (default='ascii').
"""

print('\n\n***WARNING***\n\nMY_EXPORT_VTK: still to be revised & NO normals & other missing data\n\n')

if not isinstance(mesh, Mesh):
raise ValueError("The mesh argument to write_vtk() must be a valid Raysect Mesh primitive object.")

Expand All@@ -170,12 +185,13 @@ def _write_ascii(cls, mesh, filename, triangle_data=None, vertex_data=None):

with open(filename, 'w') as f:

# # vtk DataFile Version 2.0
# My Raysect mesh data
# # vtk DataFile Version 4.2
# vtk output
# ASCII
mesh_name = (mesh.name or 'RaysectMesh').replace(" ", "_")
f.write('# vtk DataFile Version 2.0\n')
f.write('{}\n'.format(mesh_name))
f.write('# vtk DataFile Version 4.2\n')
#f.write('{}\n'.format(mesh_name))
f.write('vtk output\n')
f.write('ASCII\n')

cls._ascii_write_geometry(f, mesh)
Expand All@@ -194,32 +210,39 @@ def _ascii_write_geometry(cls, f, mesh):
num_triangles = mesh.data.triangles.shape[0]
num_vertices = mesh.data.vertices.shape[0]

# DATASET UNSTRUCTURED_GRID
# POINTS 5081 float
# 5.12135678592 3.59400404579 5.20377763887
# 5.07735666785 3.40460816029 5.27386350545
# DATASET POLYDATA
# POINTS 36013 float
# 5.12135678592 3.59400404579 5.20377763887 5.07735666785 3.40460816029 5.27386350545
# ...
f.write('DATASET UNSTRUCTURED_GRID\n')
f.write('DATASET POLYDATA\n')
f.write('POINTS {} float\n'.format(num_vertices))
for i in range(num_vertices):
f.write('{} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))

# CELLS 9804 39216
i = 0

while i < num_vertices:
j = 0
while i < num_vertices and j < 3:
f.write('{} {} {} '.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))
i += 1
j += 1
f.write('\n')

f.write('METADATA\nINFORMATION 2\n')
f.write('NAME L2_NORM_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n')
f.write('NAME L2_NORM_FINITE_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n\n')


# POLYGONS 9804 39216

# 3 447 4361 446
# 3 444 4248 445
# ...
f.write('CELLS {} {}\n'.format(num_triangles, 4 * num_triangles))
f.write('POLYGONS {} {}\n'.format(num_triangles, 4 * num_triangles))
for i in range(num_triangles):
f.write('3 {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2]))

# CELL_TYPES 9804
# 5
# 5
# ...
f.write('CELL_TYPES {}\n'.format(num_triangles))
for i in range(num_triangles):
f.write('5\n')

@classmethod
def _ascii_write_vertex_data(cls, f, mesh, vertex_data):
raise NotImplementedError("write_vtk() does not currently support mesh vertex data.")
Expand All@@ -237,7 +260,7 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
# ...

num_triangles = mesh.data.triangles.shape[0]
f.write('CELL_DATA {}\n'.format(num_triangles))
f.write('\nCELL_DATA {}\n'.format(num_triangles))

error_msg = "The triangle_data argument in write_vtk() must be a dictionary or arrays/lists " \
"with length equal to the number of triangles."
Expand All@@ -253,11 +276,19 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
except TypeError:
raise ValueError(error_msg)

f.write('SCALARS {} FLOAT\n'.format(var_name.replace(" ", "_")))
f.write('LOOKUP_TABLE default\n')
for value in values:
f.write('{}\n'.format(value))
f.write('FIELD FieldData 1\n')
f.write('GroupIds 1 {} float\n'.format(num_triangles))

i = 0

while i < num_triangles:
j = 0
while i < num_triangles and j < 9:
f.write('{} '.format(values[i]))
i += 1
j += 1
f.write('\n')


import_vtk = VTKHandler.import_vtk
export_vtk = VTKHandler.export_vtk
my_import_vtk = VTKHandler.my_import_vtk
my_export_vtk = VTKHandler.my_export_vtk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 73 additions & 42 deletions raysect/primitive/mesh/vtk.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,14 +46,17 @@
class VTKHandler:

@classmethod
def import_vtk(cls, filename, scaling=1.0, mode=VTK_AUTOMATIC, **kwargs):
def my_import_vtk(cls, filename, scaling=1e-3, mode=VTK_AUTOMATIC, **kwargs):
"""
Create a mesh instance from a VTK mesh data file (.vtk).

.. warning ::
Currently only supports VTK DataFile v2.0 and unstructured grid data with
3 element (triangular) cells.

.. warning ::
Trying to update the version to be able to read VTK DataFile 4.2.

:param str filename: Mesh file path.
:param double scaling: Scale the mesh by this factor (default=1.0).
:param str mode: The file format to load: 'ascii', 'binary', 'auto' (default='auto').
Expand DownExpand Up@@ -87,11 +90,11 @@ def _load_ascii(cls, filename, scaling):
with open(filename, 'r') as f:

# parse the file header
assert f.readline().strip() == "# vtk DataFile Version 2.0"
assert f.readline().strip() == "# vtk DataFile Version 4.2"
mesh_name = f.readline().strip()
assert f.readline().strip() == "ASCII"

if not f.readline().strip() == "DATASET UNSTRUCTURED_GRID":
if not f.readline().strip() == "DATASET POLYDATA":
raise RuntimeError("Unrecognised dataset encountered in vtk file.")

vertices = cls._ascii_read_vertices(f, scaling)
Expand All@@ -109,36 +112,47 @@ def _ascii_read_vertices(cls, f, scaling):

vertices = np.empty((num_points, 3))

for i in range(num_points):
i=0

while i < num_points:
coordinates = f.readline().split()
vertices[i, 0] = float(coordinates[0]) * scaling
vertices[i, 1] = float(coordinates[1]) * scaling
vertices[i, 2] = float(coordinates[2]) * scaling

j=0

while j < np.size(coordinates):
vertices[i, 0] = float(coordinates[j]) * scaling
vertices[i, 1] = float(coordinates[j+1]) * scaling
vertices[i, 2] = float(coordinates[j+2]) * scaling
j += 3
i += 1

return vertices

@classmethod
def _ascii_read_triangles(cls, f):

match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
#match = re.match("CELLS\s*([0-9]*)\s*([0-9]*)", f.readline())
match = False

while not match:
match = re.match("POLYGONS\s*([0-9]*)\s*([0-9]*)", f.readline())

if not match:
raise RuntimeError("Unrecognised dataset encountered in vtk file.")
num_triangles = int(match.group(1))
triangles = np.empty((num_triangles, 3), dtype=np.int32)
for i in range(num_triangles):
triangle_specification = f.readline().split()

#assert triangle specification[0] == 3
triangles[i, 0] = int(triangle_specification[1])
triangles[i, 1] = int(triangle_specification[2])
triangles[i, 2] = int(triangle_specification[3])

assert f.readline().split()[0] == 'CELL_TYPES'
for i in range(num_triangles):
assert int(f.readline().strip()) == 5

return triangles

@classmethod
def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
def my_export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=VTK_ASCII):
"""
Write a mesh instance to a vtk mesh file (.vtk) with optional cell and point data.

Expand All@@ -152,7 +166,8 @@ def export_vtk(cls, mesh, filename, triangle_data=None, vertex_data=None, mode=V
equal to the number of vertices in the mesh.
:param str mode: The file format to write: 'ascii' or 'binary' (default='ascii').
"""

print('\n\n***WARNING***\n\nMY_EXPORT_VTK: still to be revised & NO normals & other missing data\n\n')

if not isinstance(mesh, Mesh):
raise ValueError("The mesh argument to write_vtk() must be a valid Raysect Mesh primitive object.")

Expand All@@ -170,12 +185,13 @@ def _write_ascii(cls, mesh, filename, triangle_data=None, vertex_data=None):

with open(filename, 'w') as f:

# # vtk DataFile Version 2.0
# My Raysect mesh data
# # vtk DataFile Version 4.2
# vtk output
# ASCII
mesh_name = (mesh.name or 'RaysectMesh').replace(" ", "_")
f.write('# vtk DataFile Version 2.0\n')
f.write('{}\n'.format(mesh_name))
f.write('# vtk DataFile Version 4.2\n')
#f.write('{}\n'.format(mesh_name))
f.write('vtk output\n')
f.write('ASCII\n')

cls._ascii_write_geometry(f, mesh)
Expand All@@ -194,32 +210,39 @@ def _ascii_write_geometry(cls, f, mesh):
num_triangles = mesh.data.triangles.shape[0]
num_vertices = mesh.data.vertices.shape[0]

# DATASET UNSTRUCTURED_GRID
# POINTS 5081 float
# 5.12135678592 3.59400404579 5.20377763887
# 5.07735666785 3.40460816029 5.27386350545
# DATASET POLYDATA
# POINTS 36013 float
# 5.12135678592 3.59400404579 5.20377763887 5.07735666785 3.40460816029 5.27386350545
# ...
f.write('DATASET UNSTRUCTURED_GRID\n')
f.write('DATASET POLYDATA\n')
f.write('POINTS {} float\n'.format(num_vertices))
for i in range(num_vertices):
f.write('{} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))

# CELLS 9804 39216
i = 0

while i < num_vertices:
j = 0
while i < num_vertices and j < 3:
f.write('{} {} {} '.format(vertices[i, 0], vertices[i, 1], vertices[i, 2]))
i += 1
j += 1
f.write('\n')

f.write('METADATA\nINFORMATION 2\n')
f.write('NAME L2_NORM_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n')
f.write('NAME L2_NORM_FINITE_RANGE LOCATION vtkDataArray\n')
f.write('DATA 2 2.37105 2.7879\n\n')


# POLYGONS 9804 39216

# 3 447 4361 446
# 3 444 4248 445
# ...
f.write('CELLS {} {}\n'.format(num_triangles, 4 * num_triangles))
f.write('POLYGONS {} {}\n'.format(num_triangles, 4 * num_triangles))
for i in range(num_triangles):
f.write('3 {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2]))

# CELL_TYPES 9804
# 5
# 5
# ...
f.write('CELL_TYPES {}\n'.format(num_triangles))
for i in range(num_triangles):
f.write('5\n')

@classmethod
def _ascii_write_vertex_data(cls, f, mesh, vertex_data):
raise NotImplementedError("write_vtk() does not currently support mesh vertex data.")
Expand All@@ -237,7 +260,7 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
# ...

num_triangles = mesh.data.triangles.shape[0]
f.write('CELL_DATA {}\n'.format(num_triangles))
f.write('\nCELL_DATA {}\n'.format(num_triangles))

error_msg = "The triangle_data argument in write_vtk() must be a dictionary or arrays/lists " \
"with length equal to the number of triangles."
Expand All@@ -253,11 +276,19 @@ def _ascii_write_triangle_data(cls, f, mesh, triangle_data):
except TypeError:
raise ValueError(error_msg)

f.write('SCALARS {} FLOAT\n'.format(var_name.replace(" ", "_")))
f.write('LOOKUP_TABLE default\n')
for value in values:
f.write('{}\n'.format(value))
f.write('FIELD FieldData 1\n')
f.write('GroupIds 1 {} float\n'.format(num_triangles))

i = 0

while i < num_triangles:
j = 0
while i < num_triangles and j < 9:
f.write('{} '.format(values[i]))
i += 1
j += 1
f.write('\n')


import_vtk = VTKHandler.import_vtk
export_vtk = VTKHandler.export_vtk
my_import_vtk = VTKHandler.my_import_vtk
my_export_vtk = VTKHandler.my_export_vtk