mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-20 12:40:31 +08:00
Merge pull request #2052 from almarklein/mc_lewiner
FEAT: Lewiner marching cubes algorithm
This commit is contained in:
+5
-1
@@ -35,7 +35,8 @@
|
||||
and more.
|
||||
|
||||
- Almar Klein
|
||||
Binary heap class for graph algorithms
|
||||
Binary heap class and other improvements for graph algorithms
|
||||
Lewiner variant of marching cubes algorithm
|
||||
|
||||
- Lee Kamentsky and Thouis Jones of the CellProfiler team, Broad Institute, MIT
|
||||
Constant time per pixel median filter, edge detectors, and more.
|
||||
@@ -229,6 +230,9 @@
|
||||
- Alex Izvorski
|
||||
Color spaces for YUV and related spaces
|
||||
|
||||
- Thomas Lewiner
|
||||
Design and original implementation of the Lewiner marching cubes algorithm
|
||||
|
||||
- Jeff Hemmelgarn
|
||||
Minimum threshold
|
||||
|
||||
|
||||
+5
-2
@@ -50,9 +50,12 @@ Library:
|
||||
Extension: skimage.measure._moments_cy
|
||||
Sources:
|
||||
skimage/measure/_moments_cy.pyx
|
||||
Extension: skimage.measure._marching_cubes_cy
|
||||
Extension: skimage.measure._marching_cubes_classic_cy
|
||||
Sources:
|
||||
skimage/measure/_marching_cubes_cy.pyx
|
||||
skimage/measure/_marching_cubes_classic_cy.pyx
|
||||
Extension: skimage.measure._marching_cubes_lewiner_cy
|
||||
Sources:
|
||||
skimage/measure/_marching_cubes_lewiner_cy.pyx
|
||||
Extension: skimage.graph._mcp
|
||||
Sources:
|
||||
skimage/graph/_mcp.pyx
|
||||
|
||||
@@ -33,10 +33,10 @@ ellip_double = np.concatenate((ellip_base[:-1, ...],
|
||||
ellip_base[2:, ...]), axis=0)
|
||||
|
||||
# Use marching cubes to obtain the surface mesh of these ellipsoids
|
||||
verts, faces = measure.marching_cubes(ellip_double, 0)
|
||||
verts, faces, normals, values = measure.marching_cubes(ellip_double, 0)
|
||||
|
||||
# Display resulting triangular mesh using Matplotlib. This can also be done
|
||||
# with mayavi (see skimage.measure.marching_cubes docstring).
|
||||
# with mayavi or visvis (see skimage.measure.marching_cubes docstring).
|
||||
fig = plt.figure(figsize=(10, 12))
|
||||
ax = fig.add_subplot(111, projection='3d')
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from ._find_contours import find_contours
|
||||
from ._marching_cubes import (marching_cubes, mesh_surface_area,
|
||||
correct_mesh_orientation)
|
||||
from ._marching_cubes_lewiner import marching_cubes, marching_cubes_lewiner
|
||||
from ._marching_cubes_classic import (marching_cubes_classic,
|
||||
mesh_surface_area,
|
||||
correct_mesh_orientation)
|
||||
from ._regionprops import regionprops, perimeter
|
||||
from .simple_metrics import compare_mse, compare_nrmse, compare_psnr
|
||||
from ._structural_similarity import compare_ssim, structural_similarity
|
||||
@@ -29,6 +31,8 @@ __all__ = ['find_contours',
|
||||
'moments_normalized',
|
||||
'moments_hu',
|
||||
'marching_cubes',
|
||||
'marching_cubes_lewiner',
|
||||
'marching_cubes_classic',
|
||||
'mesh_surface_area',
|
||||
'correct_mesh_orientation',
|
||||
'profile_line',
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import numpy as np
|
||||
import scipy.ndimage as ndi
|
||||
from .._shared.utils import warn
|
||||
from . import _marching_cubes_cy
|
||||
from . import _marching_cubes_classic_cy
|
||||
|
||||
|
||||
def marching_cubes(volume, level, spacing=(1., 1., 1.),
|
||||
gradient_direction='descent'):
|
||||
def marching_cubes_classic(volume, level=None, spacing=(1., 1., 1.),
|
||||
gradient_direction='descent'):
|
||||
"""
|
||||
Marching cubes algorithm to find iso-valued surfaces in 3d volumetric data
|
||||
Classic marching cubes algorithm to find surfaces in 3d volumetric data.
|
||||
|
||||
Note that the ``marching_cubes()`` algorithm is recommended over
|
||||
this algorithm, because it's faster and produces better results.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
volume : (M, N, P) array of doubles
|
||||
Input data volume to find isosurfaces. Will be cast to `np.float64`.
|
||||
level : float
|
||||
Contour value to search for isosurfaces in `volume`.
|
||||
Contour value to search for isosurfaces in `volume`. If not
|
||||
given or None, the average of the min and max of vol is used.
|
||||
spacing : length-3 tuple of floats
|
||||
Voxel spacing in spatial dimensions corresponding to numpy array
|
||||
indexing dimensions (M, N, P) as in `volume`.
|
||||
@@ -82,34 +86,27 @@ def marching_cubes(volume, level, spacing=(1., 1., 1.),
|
||||
To quantify the area of an isosurface generated by this algorithm, pass
|
||||
outputs directly into `skimage.measure.mesh_surface_area`.
|
||||
|
||||
Regarding visualization of algorithm output, the ``mayavi`` package
|
||||
is recommended. To contour a volume named `myvolume` about the level 0.0::
|
||||
|
||||
>>> from mayavi import mlab # doctest: +SKIP
|
||||
>>> verts, faces = marching_cubes(myvolume, 0.0, (1., 1., 2.)) # doctest: +SKIP
|
||||
>>> mlab.triangular_mesh([vert[0] for vert in verts],
|
||||
... [vert[1] for vert in verts],
|
||||
... [vert[2] for vert in verts],
|
||||
... faces) # doctest: +SKIP
|
||||
>>> mlab.show() # doctest: +SKIP
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] Lorensen, William and Harvey E. Cline. Marching Cubes: A High
|
||||
Resolution 3D Surface Construction Algorithm. Computer Graphics
|
||||
(SIGGRAPH 87 Proceedings) 21(4) July 1987, p. 163-170).
|
||||
|
||||
DOI: 10.1145/37401.37422
|
||||
|
||||
See Also
|
||||
--------
|
||||
skimage.measure.correct_mesh_orientation
|
||||
skimage.measure.marching_cubes
|
||||
skimage.measure.mesh_surface_area
|
||||
|
||||
"""
|
||||
# Check inputs and ensure `volume` is C-contiguous for memoryviews
|
||||
if volume.ndim != 3:
|
||||
raise ValueError("Input volume must have 3 dimensions.")
|
||||
if level < volume.min() or level > volume.max():
|
||||
raise ValueError("Contour level must be within volume data range.")
|
||||
if level is None:
|
||||
level = 0.5 * (volume.min() + volume.max())
|
||||
else:
|
||||
level = float(level)
|
||||
if level < volume.min() or level > volume.max():
|
||||
raise ValueError("Surface level must be within volume data range.")
|
||||
if len(spacing) != 3:
|
||||
raise ValueError("`spacing` must consist of three floats.")
|
||||
|
||||
@@ -121,18 +118,16 @@ def marching_cubes(volume, level, spacing=(1., 1., 1.),
|
||||
# Note: this algorithm is fast, but returns degenerate "triangles" which
|
||||
# have repeated vertices - and equivalent vertices are redundantly
|
||||
# placed in every triangle they connect with.
|
||||
raw_faces = _marching_cubes_cy.iterate_and_store_3d(volume, float(level))
|
||||
raw_faces = _marching_cubes_classic_cy.iterate_and_store_3d(volume,
|
||||
float(level))
|
||||
|
||||
# Find and collect unique vertices, storing triangle verts as indices.
|
||||
# Returns a true mesh with no degenerate faces.
|
||||
verts, faces = _marching_cubes_cy.unpack_unique_verts(raw_faces)
|
||||
verts, faces = _marching_cubes_classic_cy.unpack_unique_verts(raw_faces)
|
||||
|
||||
verts = np.asarray(verts)
|
||||
faces = np.asarray(faces)
|
||||
|
||||
# Calculate gradient of `volume`, then interpolate to vertices in `verts`
|
||||
grad_x, grad_y, grad_z = np.gradient(volume)
|
||||
|
||||
# Fancy indexing to define two vector arrays from triangle vertices
|
||||
faces = _correct_mesh_orientation(volume, verts[faces], faces, spacing,
|
||||
gradient_direction)
|
||||
@@ -160,7 +155,7 @@ def mesh_surface_area(verts, faces):
|
||||
|
||||
Notes
|
||||
-----
|
||||
The arguments expected by this function are the exact outputs from
|
||||
The arguments expected by this function are the first two outputs from
|
||||
`skimage.measure.marching_cubes`. For unit correct output, ensure correct
|
||||
`spacing` was passed to `skimage.measure.marching_cubes`.
|
||||
|
||||
@@ -170,6 +165,7 @@ def mesh_surface_area(verts, faces):
|
||||
See Also
|
||||
--------
|
||||
skimage.measure.marching_cubes
|
||||
skimage.measure.marching_cubes_classic
|
||||
skimage.measure.correct_mesh_orientation
|
||||
|
||||
"""
|
||||
@@ -217,7 +213,7 @@ def correct_mesh_orientation(volume, verts, faces, spacing=(1., 1., 1.),
|
||||
Certain applications and mesh processing algorithms require all faces
|
||||
to be oriented in a consistent way. Generally, this means a normal vector
|
||||
points "out" of the meshed shapes. This algorithm corrects the output from
|
||||
`skimage.measure.marching_cubes` by flipping the orientation of
|
||||
`skimage.measure.marching_cubes_classic` by flipping the orientation of
|
||||
mis-oriented faces.
|
||||
|
||||
Because marching cubes could be used to find isosurfaces either on
|
||||
@@ -228,21 +224,21 @@ def correct_mesh_orientation(volume, verts, faces, spacing=(1., 1., 1.),
|
||||
completely incorrectly, try changing this option.
|
||||
|
||||
The arguments expected by this function are the exact outputs from
|
||||
`skimage.measure.marching_cubes`. Only `faces` is corrected and returned,
|
||||
as the vertices do not change; only the order in which they are
|
||||
`skimage.measure.marching_cubes_classic`. Only `faces` is corrected and
|
||||
returned, as the vertices do not change; only the order in which they are
|
||||
referenced.
|
||||
|
||||
This algorithm assumes ``faces`` provided are all triangles.
|
||||
|
||||
See Also
|
||||
--------
|
||||
skimage.measure.marching_cubes
|
||||
skimage.measure.marching_cubes_classic
|
||||
skimage.measure.mesh_surface_area
|
||||
|
||||
"""
|
||||
warn(DeprecationWarning("`correct_mesh_orientation` is deprecated for "
|
||||
"removal as `marching_cubes` now guarantess "
|
||||
"correct mesh orientation."))
|
||||
"removal as `marching_cubes_classic` now "
|
||||
"guarantees correct mesh orientation."))
|
||||
|
||||
verts = verts.copy()
|
||||
verts[:, 0] /= spacing[0]
|
||||
@@ -291,7 +287,7 @@ def _correct_mesh_orientation(volume, actual_verts, faces,
|
||||
Certain applications and mesh processing algorithms require all faces
|
||||
to be oriented in a consistent way. Generally, this means a normal vector
|
||||
points "out" of the meshed shapes. This algorithm corrects the output from
|
||||
`skimage.measure.marching_cubes` by flipping the orientation of
|
||||
`skimage.measure.marching_cubes_classic` by flipping the orientation of
|
||||
mis-oriented faces.
|
||||
|
||||
Because marching cubes could be used to find isosurfaces either on
|
||||
@@ -302,7 +298,7 @@ def _correct_mesh_orientation(volume, actual_verts, faces,
|
||||
completely incorrectly, try changing this option.
|
||||
|
||||
The arguments expected by this function are the exact outputs from
|
||||
`skimage.measure.marching_cubes` except `actual_verts`, which is an
|
||||
`skimage.measure.marching_cubes_classic` except `actual_verts`, which is an
|
||||
uncorrected version of the fancy indexing operation `verts[faces]`.
|
||||
Only `faces` is corrected and returned as the vertices do not change,
|
||||
only the order in which they are referenced.
|
||||
@@ -311,7 +307,7 @@ def _correct_mesh_orientation(volume, actual_verts, faces,
|
||||
|
||||
See Also
|
||||
--------
|
||||
skimage.measure.marching_cubes
|
||||
skimage.measure.marching_cubes_classic
|
||||
skimage.measure.mesh_surface_area
|
||||
|
||||
"""
|
||||
@@ -0,0 +1,278 @@
|
||||
import sys
|
||||
import base64
|
||||
import dis
|
||||
import inspect
|
||||
|
||||
import numpy as np
|
||||
|
||||
if sys.version_info >= (3, ):
|
||||
base64decode = base64.decodebytes
|
||||
ordornot = lambda x:x
|
||||
else:
|
||||
base64decode = base64.decodestring
|
||||
ordornot = ord
|
||||
|
||||
from . import _marching_cubes_lewiner_luts as mcluts
|
||||
from . import _marching_cubes_lewiner_cy
|
||||
from .._shared.utils import skimage_deprecation, warn
|
||||
|
||||
|
||||
def _expected_output_args():
|
||||
""" Get number of expected output args.
|
||||
|
||||
Please don't use this to influence the algorithmic bahaviour of a function.
|
||||
For ``a, b, rest*, c = ...`` syntax, returns n + 0.1 (3.1 in this example).
|
||||
"""
|
||||
f = inspect.currentframe().f_back.f_back
|
||||
i = f.f_lasti + 3
|
||||
bytecode = f.f_code.co_code
|
||||
instruction = ordornot(bytecode[i])
|
||||
while True:
|
||||
if instruction == dis.opmap['DUP_TOP']:
|
||||
if ordornot(bytecode[i + 1]) == dis.opmap['UNPACK_SEQUENCE']:
|
||||
return ordornot(bytecode[i + 2])
|
||||
i += 4
|
||||
instruction = ordornot(bytecode[i])
|
||||
continue
|
||||
if instruction == dis.opmap['STORE_NAME']:
|
||||
return 1
|
||||
if instruction == dis.opmap['UNPACK_SEQUENCE']:
|
||||
return ordornot(bytecode[i + 1])
|
||||
if instruction == dis.opmap.get('UNPACK_EX', -1): # py3k
|
||||
return ordornot(bytecode[i + 1]) + ordornot(bytecode[i + 2]) + 0.1
|
||||
return 0
|
||||
|
||||
|
||||
def marching_cubes(volume, level=None, spacing=(1., 1., 1.),
|
||||
gradient_direction='descent', step_size=1,
|
||||
allow_degenerate=True, use_classic=False):
|
||||
"""
|
||||
Lewiner marching cubes algorithm to find surfaces in 3d volumetric data.
|
||||
|
||||
In contrast to ``marching_cubes_classic()``, this algorithm is faster,
|
||||
resolves ambiguities, and guarantees topologically correct results.
|
||||
Therefore, this algorithm generally a better choice, unless there
|
||||
is a specific need for the classic algorithm.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
volume : (M, N, P) array
|
||||
Input data volume to find isosurfaces. Will internally be
|
||||
converted to float32 if necessary.
|
||||
level : float
|
||||
Contour value to search for isosurfaces in `volume`. If not
|
||||
given or None, the average of the min and max of vol is used.
|
||||
spacing : length-3 tuple of floats
|
||||
Voxel spacing in spatial dimensions corresponding to numpy array
|
||||
indexing dimensions (M, N, P) as in `volume`.
|
||||
gradient_direction : string
|
||||
Controls if the mesh was generated from an isosurface with gradient
|
||||
descent toward objects of interest (the default), or the opposite,
|
||||
considering the *left-hand* rule.
|
||||
The two options are:
|
||||
* descent : Object was greater than exterior
|
||||
* ascent : Exterior was greater than object
|
||||
step_size : int
|
||||
Step size in voxels. Default 1. Larger steps yield faster but
|
||||
coarser results. The result will always be topologically correct
|
||||
though.
|
||||
allow_degenerate : bool
|
||||
Whether to allow degenerate (i.e. zero-area) triangles in the
|
||||
end-result. Default True. If False, degenerate triangles are
|
||||
removed, at the cost of making the algorithm slower.
|
||||
use_classic : bool
|
||||
If given and True, the classic marching cubes by Lorensen (1987)
|
||||
is used. This option is included for reference purposes. Note
|
||||
that this algorithm has ambiguities and is not guaranteed to
|
||||
produce a topologically correct result. The results with using
|
||||
this option are *not* generally the same as the
|
||||
``marching_cubes_classic()`` function.
|
||||
|
||||
Returns
|
||||
-------
|
||||
verts : (V, 3) array
|
||||
Spatial coordinates for V unique mesh vertices. Coordinate order
|
||||
matches input `volume` (M, N, P).
|
||||
faces : (F, 3) array
|
||||
Define triangular faces via referencing vertex indices from ``verts``.
|
||||
This algorithm specifically outputs triangles, so each face has
|
||||
exactly three indices.
|
||||
normals : (V, 3) array
|
||||
The normal direction at each vertex, as calculated from the
|
||||
data.
|
||||
values : (V, ) array
|
||||
Gives a measure for the maximum value of the data in the local region
|
||||
near each vertex. This can be used by visualization tools to apply
|
||||
a colormap to the mesh.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The algorithm [1] is an improved version of Chernyaev's Marching
|
||||
Cubes 33 algorithm. It is an efficient algorithm that relies on
|
||||
heavy use of lookup tables to handle the many different cases,
|
||||
keeping the algorithm relatively easy. This implementation is
|
||||
written in Cython, ported from Lewiner's C++ implementation.
|
||||
|
||||
To quantify the area of an isosurface generated by this algorithm, pass
|
||||
verts and faces to `skimage.measure.mesh_surface_area`.
|
||||
|
||||
Regarding visualization of algorithm output, to contour a volume
|
||||
named `myvolume` about the level 0.0, using the ``mayavi`` package::
|
||||
|
||||
>>> from mayavi import mlab # doctest: +SKIP
|
||||
>>> verts, faces, normals, values = marching_cubes(myvolume, 0.0) # doctest: +SKIP
|
||||
>>> mlab.triangular_mesh([vert[0] for vert in verts],
|
||||
... [vert[1] for vert in verts],
|
||||
... [vert[2] for vert in verts],
|
||||
... faces) # doctest: +SKIP
|
||||
>>> mlab.show() # doctest: +SKIP
|
||||
|
||||
Similarly using the ``visvis`` package::
|
||||
|
||||
>>> import visvis as vv # doctest: +SKIP
|
||||
>>> verts, faces, normals, values = marching_cubes_classic(myvolume, 0.0) # doctest: +SKIP
|
||||
>>> vv.mesh(np.fliplr(verts), faces, normals, values) # doctest: +SKIP
|
||||
>>> vv.use().Run() # doctest: +SKIP
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] Thomas Lewiner, Helio Lopes, Antonio Wilson Vieira and Geovan
|
||||
Tavares. Efficient implementation of Marching Cubes' cases with
|
||||
topological guarantees. Journal of Graphics Tools 8(2)
|
||||
pp. 1-15 (december 2003).
|
||||
DOI: 10.1080/10867651.2003.10487582
|
||||
|
||||
See Also
|
||||
--------
|
||||
skimage.measure.marching_cubes_classic
|
||||
skimage.measure.mesh_surface_area
|
||||
"""
|
||||
|
||||
# This signature (output args) of this func changed after 0.12
|
||||
try:
|
||||
nout = _expected_output_args()
|
||||
except Exception:
|
||||
nout = 0 # always warn if, for whaterver reason, the black magic in above call fails
|
||||
if nout <= 2:
|
||||
warn(skimage_deprecation('`marching_cubes` now uses a better and '
|
||||
'faster algorithm, and returns four instead '
|
||||
'of two outputs (see docstring for details). '
|
||||
'Backwards compatibility with 0.12 and prior '
|
||||
'is available with `marching_cubes_classic`.'))
|
||||
|
||||
return marching_cubes_lewiner(volume, level, spacing, gradient_direction,
|
||||
step_size, allow_degenerate, use_classic)
|
||||
|
||||
|
||||
def marching_cubes_lewiner(volume, level=None, spacing=(1., 1., 1.),
|
||||
gradient_direction='descent', step_size=1,
|
||||
allow_degenerate=True, use_classic=False):
|
||||
""" Alias for ``marching_cubes()``.
|
||||
"""
|
||||
|
||||
# Check volume and ensure its in the format that the alg needs
|
||||
if not isinstance(volume, np.ndarray) or (volume.ndim != 3):
|
||||
raise ValueError('Input volume should be a 3D numpy array.')
|
||||
if volume.shape[0] < 2 or volume.shape[1] < 2 or volume.shape[2] < 2:
|
||||
raise ValueError("Input array must be at least 2x2x2.")
|
||||
volume = np.ascontiguousarray(volume, np.float32) # no copy if not necessary
|
||||
|
||||
# Check/convert other inputs:
|
||||
# level
|
||||
if level is None:
|
||||
level = 0.5 * (volume.min() + volume.max())
|
||||
else:
|
||||
level = float(level)
|
||||
if level < volume.min() or level > volume.max():
|
||||
raise ValueError("Surface level must be within volume data range.")
|
||||
# spacing
|
||||
if len(spacing) != 3:
|
||||
raise ValueError("`spacing` must consist of three floats.")
|
||||
# step_size
|
||||
step_size = int(step_size)
|
||||
if step_size < 1:
|
||||
raise ValueError('step_size must be at least one.')
|
||||
# use_classic
|
||||
use_classic = bool(use_classic)
|
||||
|
||||
# Get LutProvider class (reuse if possible)
|
||||
L = _get_mc_luts()
|
||||
|
||||
# Apply algorithm
|
||||
func = _marching_cubes_lewiner_cy.marching_cubes
|
||||
vertices, faces , normals, values = func(volume, level, L, step_size, use_classic)
|
||||
|
||||
if not len(vertices):
|
||||
raise RuntimeError('No surface found at the given iso value.')
|
||||
|
||||
# Output in z-y-x order, as is common in skimage
|
||||
vertices = np.fliplr(vertices)
|
||||
normals = np.fliplr(normals)
|
||||
|
||||
# Finishing touches to output
|
||||
faces.shape = -1, 3
|
||||
if gradient_direction == 'descent':
|
||||
# MC implementation is right-handed, but gradient_direction is left-handed
|
||||
faces = np.fliplr(faces)
|
||||
elif not gradient_direction == 'ascent':
|
||||
raise ValueError("Incorrect input %s in `gradient_direction`, see "
|
||||
"docstring." % (gradient_direction))
|
||||
if spacing != (1, 1, 1):
|
||||
vertices = vertices * np.r_[spacing]
|
||||
|
||||
if allow_degenerate:
|
||||
return vertices, faces, normals, values
|
||||
else:
|
||||
fun = _marching_cubes_lewiner_cy.remove_degenerate_faces
|
||||
return fun(vertices, faces, normals, values)
|
||||
|
||||
|
||||
def _to_array(args):
|
||||
shape, text = args
|
||||
byts = base64decode(text.encode('utf-8'))
|
||||
ar = np.frombuffer(byts, dtype='int8')
|
||||
ar.shape = shape
|
||||
return ar
|
||||
|
||||
|
||||
# Map an edge-index to two relative pixel positions. The ege index
|
||||
# represents a point that lies somewhere in between these pixels.
|
||||
# Linear interpolation should be used to determine where it is exactly.
|
||||
# 0
|
||||
# 3 1 -> 0x
|
||||
# 2 xx
|
||||
EDGETORELATIVEPOSX = np.array([ [0,1],[1,1],[1,0],[0,0], [0,1],[1,1],[1,0],[0,0], [0,0],[1,1],[1,1],[0,0] ], 'int8')
|
||||
EDGETORELATIVEPOSY = np.array([ [0,0],[0,1],[1,1],[1,0], [0,0],[0,1],[1,1],[1,0], [0,0],[0,0],[1,1],[1,1] ], 'int8')
|
||||
EDGETORELATIVEPOSZ = np.array([ [0,0],[0,0],[0,0],[0,0], [1,1],[1,1],[1,1],[1,1], [0,1],[0,1],[0,1],[0,1] ], 'int8')
|
||||
|
||||
|
||||
def _get_mc_luts():
|
||||
""" Kind of lazy obtaining of the luts.
|
||||
"""
|
||||
if not hasattr(mcluts, 'THE_LUTS'):
|
||||
|
||||
mcluts.THE_LUTS = _marching_cubes_lewiner_cy.LutProvider(
|
||||
EDGETORELATIVEPOSX, EDGETORELATIVEPOSY, EDGETORELATIVEPOSZ,
|
||||
|
||||
_to_array(mcluts.CASESCLASSIC), _to_array(mcluts.CASES),
|
||||
|
||||
_to_array(mcluts.TILING1), _to_array(mcluts.TILING2), _to_array(mcluts.TILING3_1), _to_array(mcluts.TILING3_2),
|
||||
_to_array(mcluts.TILING4_1), _to_array(mcluts.TILING4_2), _to_array(mcluts.TILING5), _to_array(mcluts.TILING6_1_1),
|
||||
_to_array(mcluts.TILING6_1_2), _to_array(mcluts.TILING6_2), _to_array(mcluts.TILING7_1),
|
||||
_to_array(mcluts.TILING7_2), _to_array(mcluts.TILING7_3), _to_array(mcluts.TILING7_4_1),
|
||||
_to_array(mcluts.TILING7_4_2), _to_array(mcluts.TILING8), _to_array(mcluts.TILING9),
|
||||
_to_array(mcluts.TILING10_1_1), _to_array(mcluts.TILING10_1_1_), _to_array(mcluts.TILING10_1_2),
|
||||
_to_array(mcluts.TILING10_2), _to_array(mcluts.TILING10_2_), _to_array(mcluts.TILING11),
|
||||
_to_array(mcluts.TILING12_1_1), _to_array(mcluts.TILING12_1_1_), _to_array(mcluts.TILING12_1_2),
|
||||
_to_array(mcluts.TILING12_2), _to_array(mcluts.TILING12_2_), _to_array(mcluts.TILING13_1),
|
||||
_to_array(mcluts.TILING13_1_), _to_array(mcluts.TILING13_2), _to_array(mcluts.TILING13_2_),
|
||||
_to_array(mcluts.TILING13_3), _to_array(mcluts.TILING13_3_), _to_array(mcluts.TILING13_4),
|
||||
_to_array(mcluts.TILING13_5_1), _to_array(mcluts.TILING13_5_2), _to_array(mcluts.TILING14),
|
||||
|
||||
_to_array(mcluts.TEST3), _to_array(mcluts.TEST4), _to_array(mcluts.TEST6),
|
||||
_to_array(mcluts.TEST7), _to_array(mcluts.TEST10), _to_array(mcluts.TEST12),
|
||||
_to_array(mcluts.TEST13), _to_array(mcluts.SUBCONFIG13),
|
||||
)
|
||||
|
||||
return mcluts.THE_LUTS
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,528 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This file was auto-generated from LookUpTable.h by createluts.py.
|
||||
# The luts are Copyright (C) 2002 by Thomas Lewiner
|
||||
|
||||
#static const char casesClassic[256][16]
|
||||
CASESCLASSIC = (256, 16), """
|
||||
/////////////////////wAIA/////////////////8AAQn/////////////////AQgDCQgB////
|
||||
/////////wECCv////////////////8ACAMBAgr/////////////CQIKAAIJ/////////////wII
|
||||
AwIKCAoJCP////////8DCwL/////////////////AAsCCAsA/////////////wEJAAIDC///////
|
||||
//////8BCwIBCQsJCAv/////////AwoBCwoD/////////////wAKAQAICggLCv////////8DCQAD
|
||||
CwkLCgn/////////CQgKCggL/////////////wQHCP////////////////8EAwAHAwT/////////
|
||||
////AAEJCAQH/////////////wQBCQQHAQcDAf////////8BAgoIBAf/////////////AwQHAwAE
|
||||
AQIK/////////wkCCgkAAggEB/////////8CCgkCCQcCBwMHCQT/////CAQHAwsC////////////
|
||||
/wsEBwsCBAIABP////////8JAAEIBAcCAwv/////////BAcLCQQLCQsCCQIB/////wMKAQMLCgcI
|
||||
BP////////8BCwoBBAsBAAQHCwT/////BAcICQALCQsKCwAD/////wQHCwQLCQkLCv////////8J
|
||||
BQT/////////////////CQUEAAgD/////////////wAFBAEFAP////////////8IBQQIAwUDAQX/
|
||||
////////AQIKCQUE/////////////wMACAECCgQJBf////////8FAgoFBAIEAAL/////////AgoF
|
||||
AwIFAwUEAwQI/////wkFBAIDC/////////////8ACwIACAsECQX/////////AAUEAAEFAgML////
|
||||
/////wIBBQIFCAIICwQIBf////8KAwsKAQMJBQT/////////BAkFAAgBCAoBCAsK/////wUEAAUA
|
||||
CwULCgsAA/////8FBAgFCAoKCAv/////////CQcIBQcJ/////////////wkDAAkFAwUHA///////
|
||||
//8ABwgAAQcBBQf/////////AQUDAwUH/////////////wkHCAkFBwoBAv////////8KAQIJBQAF
|
||||
AwAFBwP/////CAACCAIFCAUHCgUC/////wIKBQIFAwMFB/////////8HCQUHCAkDCwL/////////
|
||||
CQUHCQcCCQIAAgcL/////wIDCwABCAEHCAEFB/////8LAgELAQcHAQX/////////CQUICAUHCgED
|
||||
CgML/////wUHAAUACQcLAAEACgsKAP8LCgALAAMKBQAIAAcFBwD/CwoFBwsF/////////////woG
|
||||
Bf////////////////8ACAMFCgb/////////////CQABBQoG/////////////wEIAwEJCAUKBv//
|
||||
//////8BBgUCBgH/////////////AQYFAQIGAwAI/////////wkGBQkABgACBv////////8FCQgF
|
||||
CAIFAgYDAgj/////AgMLCgYF/////////////wsACAsCAAoGBf////////8AAQkCAwsFCgb/////
|
||||
////BQoGAQkCCQsCCQgL/////wYDCwYFAwUBA/////////8ACAsACwUABQEFCwb/////AwsGAAMG
|
||||
AAYFAAUJ/////wYFCQYJCwsJCP////////8FCgYEBwj/////////////BAMABAcDBgUK////////
|
||||
/wEJAAUKBggEB/////////8KBgUBCQcBBwMHCQT/////BgECBgUBBAcI/////////wECBQUCBgMA
|
||||
BAMEB/////8IBAcJAAUABgUAAgb/////BwMJBwkEAwIJBQkGAgYJ/wMLAgcIBAoGBf////////8F
|
||||
CgYEBwIEAgACBwv/////AAEJBAcIAgMLBQoG/////wkCAQkLAgkECwcLBAUKBv8IBAcDCwUDBQEF
|
||||
Cwb/////BQELBQsGAQALBwsEAAQL/wAFCQAGBQADBgsGAwgEB/8GBQkGCQsEBwkHCwn/////CgQJ
|
||||
BgQK/////////////wQKBgQJCgAIA/////////8KAAEKBgAGBAD/////////CAMBCAEGCAYEBgEK
|
||||
/////wEECQECBAIGBP////////8DAAgBAgkCBAkCBgT/////AAIEBAIG/////////////wgDAggC
|
||||
BAQCBv////////8KBAkKBgQLAgP/////////AAgCAggLBAkKBAoG/////wMLAgABBgAGBAYBCv//
|
||||
//8GBAEGAQoECAECAQsICwH/CQYECQMGCQEDCwYD/////wgLAQgBAAsGAQkBBAYEAf8DCwYDBgAA
|
||||
BgT/////////BgQICwYI/////////////wcKBgcICggJCv////////8ABwMACgcACQoGBwr/////
|
||||
CgYHAQoHAQcIAQgA/////woGBwoHAQEHA/////////8BAgYBBggBCAkIBgf/////AgYJAgkBBgcJ
|
||||
AAkDBwMJ/wcIAAcABgYAAv////////8HAwIGBwL/////////////AgMLCgYICggJCAYH/////wIA
|
||||
BwIHCwAJBwYHCgkKB/8BCAABBwgBCgcGBwoCAwv/CwIBCwEHCgYBBgcB/////wgJBggGBwkBBgsG
|
||||
AwEDBv8ACQELBgf/////////////BwgABwAGAwsACwYA/////wcLBv////////////////8HBgv/
|
||||
////////////////AwAICwcG/////////////wABCQsHBv////////////8IAQkIAwELBwb/////
|
||||
////CgECBgsH/////////////wECCgMACAYLB/////////8CCQACCgkGCwf/////////BgsHAgoD
|
||||
CggDCgkI/////wcCAwYCB/////////////8HAAgHBgAGAgD/////////AgcGAgMHAAEJ////////
|
||||
/wEGAgEIBgEJCAgHBv////8KBwYKAQcBAwf/////////CgcGAQcKAQgHAQAI/////wADBwAHCgAK
|
||||
CQYKB/////8HBgoHCggICgn/////////BggECwgG/////////////wMGCwMABgAEBv////////8I
|
||||
BgsIBAYJAAH/////////CQQGCQYDCQMBCwMG/////wYIBAYLCAIKAf////////8BAgoDAAsABgsA
|
||||
BAb/////BAsIBAYLAAIJAgoJ/////woJAwoDAgkEAwsDBgQGA/8IAgMIBAIEBgL/////////AAQC
|
||||
BAYC/////////////wEJAAIDBAIEBgQDCP////8BCQQBBAICBAb/////////CAEDCAYBCAQGBgoB
|
||||
/////woBAAoABgYABP////////8EBgMEAwgGCgMAAwkKCQP/CgkEBgoE/////////////wQJBQcG
|
||||
C/////////////8ACAMECQULBwb/////////BQABBQQABwYL/////////wsHBggDBAMFBAMBBf//
|
||||
//8JBQQKAQIHBgv/////////BgsHAQIKAAgDBAkF/////wcGCwUECgQCCgQAAv////8DBAgDBQQD
|
||||
AgUKBQILBwb/BwIDBwYCBQQJ/////////wkFBAAIBgAGAgYIB/////8DBgIDBwYBBQAFBAD/////
|
||||
BgIIBggHAgEIBAgFAQUI/wkFBAoBBgEHBgEDB/////8BBgoBBwYBAAcIBwAJBQT/BAAKBAoFAAMK
|
||||
BgoHAwcK/wcGCgcKCAUECgQICv////8GCQUGCwkLCAn/////////AwYLAAYDAAUGAAkF/////wAL
|
||||
CAAFCwABBQUGC/////8GCwMGAwUFAwH/////////AQIKCQULCQsICwUG/////wALAwAGCwAJBgUG
|
||||
CQECCv8LCAULBQYIAAUKBQIAAgX/BgsDBgMFAgoDCgUD/////wUICQUCCAUGAgMIAv////8JBQYJ
|
||||
BgAABgL/////////AQUIAQgABQYIAwgCBgII/wEFBgIBBv////////////8BAwYBBgoDCAYFBgkI
|
||||
CQb/CgEACgAGCQUABQYA/////wADCAUGCv////////////8KBQb/////////////////CwUKBwUL
|
||||
/////////////wsFCgsHBQgDAP////////8FCwcFCgsBCQD/////////CgcFCgsHCQgBCAMB////
|
||||
/wsBAgsHAQcFAf////////8ACAMBAgcBBwUHAgv/////CQcFCQIHCQACAgsH/////wcFAgcCCwUJ
|
||||
AgMCCAkIAv8CBQoCAwUDBwX/////////CAIACAUCCAcFCgIF/////wkAAQUKAwUDBwMKAv////8J
|
||||
CAIJAgEIBwIKAgUHBQL/AQMFAwcF/////////////wAIBwAHAQEHBf////////8JAAMJAwUFAwf/
|
||||
////////CQgHBQkH/////////////wUIBAUKCAoLCP////////8FAAQFCwAFCgsLAwD/////AAEJ
|
||||
CAQKCAoLCgQF/////woLBAoEBQsDBAkEAQMBBP8CBQECCAUCCwgEBQj/////AAQLAAsDBAULAgsB
|
||||
BQEL/wACBQAFCQILBQQFCAsIBf8JBAUCCwP/////////////AgUKAwUCAwQFAwgE/////wUKAgUC
|
||||
BAQCAP////////8DCgIDBQoDCAUEBQgAAQn/BQoCBQIEAQkCCQQC/////wgEBQgFAwMFAf//////
|
||||
//8ABAUBAAX/////////////CAQFCAUDCQAFAAMF/////wkEBf////////////////8ECwcECQsJ
|
||||
Cgv/////////AAgDBAkHCQsHCQoL/////wEKCwELBAEEAAcEC/////8DAQQDBAgBCgQHBAsKCwT/
|
||||
BAsHCQsECQILCQEC/////wkHBAkLBwkBCwILAQAIA/8LBwQLBAICBAD/////////CwcECwQCCAME
|
||||
AwIE/////wIJCgIHCQIDBwcECf////8JCgcJBwQKAgcIBwACAAf/AwcKAwoCBwQKAQoABAAK/wEK
|
||||
AggHBP////////////8ECQEEAQcHAQP/////////BAkBBAEHAAgBCAcB/////wQAAwcEA///////
|
||||
//////8ECAf/////////////////CQoICgsI/////////////wMACQMJCwsJCv////////8AAQoA
|
||||
CggICgv/////////AwEKCwMK/////////////wECCwELCQkLCP////////8DAAkDCQsBAgkCCwn/
|
||||
////AAILCAAL/////////////wMCC/////////////////8CAwgCCAoKCAn/////////CQoCAAkC
|
||||
/////////////wIDCAIICgABCAEKCP////8BCgL/////////////////AQMICQEI////////////
|
||||
/wAJAf////////////////8AAwj//////////////////////////////////////w==
|
||||
"""
|
||||
|
||||
#static const char cases[256][2]
|
||||
CASES = (256, 2), """
|
||||
AP8BAAEBAgABAgMAAgMFAAEDAgEDAwUBAgUFBAUJCAABBAICAwQFAgQCBgIGCQsAAwgFBQcDCQEG
|
||||
EA4DDAwFGAEFAwECBAUDAwYHAAUKCQAEAwYEBgsOAQYRDAQLBgUZAggFBwUMCAEGEgwFDgcFHAYV
|
||||
CwQMDwUeCgUGIAYnAgwBBgQAAwUGAAIGBgMFCw4AAwkGBQcEDAEFDgsDCQQFGgMKBgYHBQwCBhMK
|
||||
AQwNBhgHBwwJDQEHCQwUBiEHDQMMAgoGBwUNCwIFEAwHCAMFHQYWCgIMEQYbDgkGIgUnAg4FFA4F
|
||||
CQUFIAsKBiMFKQIQDBcGJQcOAxAGLgQGAxUBCAEHAwIEAQYBAwcHAQYKDAACBwUGBgwLAQUPCQIO
|
||||
BgUbAgkFCAYNDgIGFAwGCgMGGQUSCAIMEAUfCwkFIgYoAg0DCwcCBg4MAwcGDQAMDgcIBhcMCgoE
|
||||
BhwMFQcKBikDDQUVCQMLCAUhDBYHCwYqAw4OCwUkBiwCEQYvAxIEBwEJAgsGCAYPCgAFEQwICwcG
|
||||
GgUTDgQMEgYdCAQFIwUoAg8FFgsFDBMGHg4KBiQGKwQECQcFJQcPAxEFLAITAxYBCgUXDAsOCAYf
|
||||
CQYHDAUqAw8LCwYmBi0EBQUtAxMCFQELCAUFJgUrAhIFLgMUAhYBDAUvAhQDFwENAhcBDgEPAP8=
|
||||
"""
|
||||
|
||||
#static const char tiling1[16][3]
|
||||
TILING1 = (16, 3), """
|
||||
AAgDAAEJAQIKAwsCBAcICQUECgYFBwYLBwsGCgUGCQQFBAgHAwILAQoCAAkBAAMI
|
||||
"""
|
||||
|
||||
#static const char tiling2[24][6]
|
||||
TILING2 = (24, 6), """
|
||||
AQgDCQgBAAsCCAsABAMABwMECQIKAAIJAAUEAQUAAwoBCwoDAQYFAgYBBwIDBgIHCQcIBQcJBggE
|
||||
CwgGCgQJBgQKCwUKBwULCwoFBwsFCgkEBgoEBgQICwYICQgHBQkHBwMCBgcCAQUGAgEGAwEKCwMK
|
||||
AAQFAQAFCQoCAAkCBAADBwQDAAILCAALAQMICQEI
|
||||
"""
|
||||
|
||||
#static const char tiling3_1[24][6]
|
||||
TILING3_1 = (24, 6), """
|
||||
AAgDAQIKCQUEAAgDAwAICwcGAQkAAgMLAAEJCAQHCQABBQoGAQIKCQUECgECBgsHCAQHAwsCAgML
|
||||
CgYFBQoGBAcIBAkFBwYLBQkECwYHBgoFCAcECwMCBQYKBwQIAgsDAgEKBwsGCgIBBAUJAQAJBgoF
|
||||
CQEABwQIAAkBCwMCCAADBgcLBAUJAwgAAwgACgIB
|
||||
"""
|
||||
|
||||
#static const char tiling3_2[24][12]
|
||||
TILING3_2 = (24, 12), """
|
||||
CgMCCggDCgEACAoAAwQIAwUEAwAJBQMJBggHBgAIBgsDAAYDCwADCwkACwIBCQsBBwkEBwEJBwgA
|
||||
AQcABgEKBgABCQAGCQYFBAoFBAIKBAkBAgQBBwILBwECBwYKAQcKAgcLAgQHAgMIBAIIBQsGBQML
|
||||
BQoCAwUCCAYHCAoGCAQFCggFCwUGCwkFCwcECQsEBgULBQkLBAcLBAsJBwYIBgoIBQQIBQgKBgsF
|
||||
CwMFAgoFAgUDCwcCBwQCCAMCCAIECwIHAgEHCgYHCgcBBQoECgIEAQkEAQQCCgEGAQAGBgAJBQYJ
|
||||
BAkHCQEHAAgHAAcBAwALAAkLAQILAQsJBwgGCAAGAwsGAwYACAQDBAUDCQADCQMFAgMKAwgKAAEK
|
||||
AAoI
|
||||
"""
|
||||
|
||||
#static const char tiling4_1[8][6]
|
||||
TILING4_1 = (8, 6), """
|
||||
AAgDBQoGAAEJCwcGAQIKCAQHCQUEAgMLBAUJCwMCCgIBBwQICQEABgcLAwgABgoF
|
||||
"""
|
||||
|
||||
#static const char tiling4_2[8][18]
|
||||
TILING4_2 = (8, 18), """
|
||||
CAUABQgGAwYIBgMKAAoDCgAFCQYBBgkHAAcJBwALAQsACwEGCgcCBwoEAQQKBAEIAggBCAIHCwQD
|
||||
BAsFAgULBQIJAwkCCQMEAwQLBQsECwUCCQIFAgkDBAMJAgcKBAoHCgQBCAEEAQgCBwIIAQYJBwkG
|
||||
CQcACwAHAAsBBgELAAUIBggFCAYDCgMGAwoABQAK
|
||||
"""
|
||||
|
||||
#static const char tiling5[48][9]
|
||||
TILING5 = (48, 9), """
|
||||
AggDAgoICgkIAQsCAQkLCQgLBAEJBAcBBwMBCAUECAMFAwEFAAoBAAgKCAsKCwQHCwIEAgAEBwAI
|
||||
BwYABgIACQMACQUDBQcDAwYLAwAGAAQGAwkAAwsJCwoJBQIKBQQCBAACCQYFCQAGAAIGAAcIAAEH
|
||||
AQUHCgABCgYABgQABgMLBgUDBQEDCgcGCgEHAQMHAQQJAQIEAgYECwECCwcBBwUBCAIDCAQCBAYC
|
||||
AgUKAgMFAwcFBwoGBwgKCAkKBgkFBgsJCwgJBQgEBQoICgsIBAsHBAkLCQoLBAcLBAsJCQsKBQQI
|
||||
BQgKCggLBgUJBgkLCwkIBwYKBwoICAoJAgoFAgUDAwUHCAMCCAIEBAIGCwIBCwEHBwEFAQkEAQQC
|
||||
AgQGCgYHCgcBAQcDBgsDBgMFBQMBCgEACgAGBgAEAAgHAAcBAQcFCQUGCQYAAAYCBQoCBQIEBAIA
|
||||
AwAJAwkLCwkKAwsGAwYAAAYECQADCQMFBQMHBwgABwAGBgACCwcECwQCAgQAAAEKAAoICAoLCAQF
|
||||
CAUDAwUBBAkBBAEHBwEDAQILAQsJCQsIAgMIAggKCggJ
|
||||
"""
|
||||
|
||||
#static const char tiling6_1_1[48][9]
|
||||
TILING6_1_1 = (48, 9), """
|
||||
BgUKAwEICQgBCwcGCQMBAwkIAQIKBwAEAAcDAwAIBQIGAgUBBQQJAgALCAsACgYFCAIAAggLCgYF
|
||||
AAQDBwMEAwAIBgQKCQoECAMACgcFBwoLCAQHCgACAAoJBwYLAAIJCgkCAgMLBAEFAQQAAAEJBgMH
|
||||
AwYCCQABCwQGBAsICwcGAQUABAAFAAEJBwULCgsFBAcIAQMKCwoDCQUECwEDAQsKCgECCAUHBQgJ
|
||||
CAQHAgYBBQEGAQIKBAYICwgGAgMLBQcJCAkHCwIDCQYEBgkKCQUEAwcCBgIHBAUJAgcDBwIGAwIL
|
||||
BAYJCgkGCwMCCQcFBwkICgIBCAYEBggLBwQIAQYCBgEFAgEKBwUICQgFBAUJAwELCgsBCAcECgMB
|
||||
AwoLCQEACwUHBQsKBgcLAAUBBQAEAQAJBgQLCAsECQEABwMGAgYDCwMCBQEEAAQBCwYHCQIAAgkK
|
||||
BwQIAgAKCQoAAAMIBQcKCwoHCAADCgQGBAoJBQYKAwQABAMHBQYKAAIICwgCCQQFCwACAAsICAAD
|
||||
BgIFAQUCCgIBBAAHAwcABgcLAQMJCAkDCgUGCAEDAQgJ
|
||||
"""
|
||||
|
||||
#static const char tiling6_1_2[48][27]
|
||||
TILING6_1_2 = (48, 27), """
|
||||
AQwDDAoDBgMKAwYIBQgGCAUMDAkIAQkMDAUKAQwDAQsMCwEGCQYBBgkHDAcJCQgMDAgDCwcMBAwA
|
||||
BAEMAQQKBwoECgcCDAIHBwMMDAMAAQIMBgwCBgMMAwYIBQgGCAUADAAFBQEMDAECAwAMAAwCDAkC
|
||||
BQIJAgULBAsFCwQMDAgLAAgMDAQJAAwCAAoMCgAFCAUABQgGDAYICAsMDAsCCgYMBAwADAUACgAF
|
||||
AAoDBgMKAwYMDAcDBAcMDAYFBAwGDAgGAwYIBgMKAAoDCgAMDAkKBAkMDAAIBQwHBQgMCAUACgAF
|
||||
AAoDDAMKCgsMDAsHCAMMAgwAAggMCAIHCgcCBwoEDAQKCgkMDAkACAQMAgwADAsABwALAAcJBgkH
|
||||
CQYMDAoJAgoMDAYLBQwBBQIMAgULBAsFCwQDDAMEBAAMDAABAgMMBwwDBwAMAAcJBgkHCQYBDAEG
|
||||
BgIMDAIDAAEMBgwEBgkMCQYBCwEGAQsADAALCwgMDAgECQAMBQwBDAYBCwEGAQsABwALAAcMDAQA
|
||||
BQQMDAcGBQwHDAkHAAcJBwALAQsACwEMDAoLBQoMDAEJAwwBDAgBBAEIAQQKBwoECgcMDAsKAwsM
|
||||
DAcIAwwBAwkMCQMECwQDBAsFDAULCwoMDAoBCQUMBwwFBwoMCgcCCAIHAggBDAEICAkMDAkFCgEM
|
||||
BgwCDAcCCAIHAggBBAEIAQQMDAUBBgUMDAQHBgwEDAoEAQQKBAEIAggBCAIMDAsIBgsMDAIKBwwF
|
||||
DAsFAgULBQIJAwkCCQMMDAgJBwgMDAMLBAwGBAsMCwQDCQMEAwkCDAIJCQoMDAoGCwIMBwwDDAQD
|
||||
CQMEAwkCBQIJAgUMDAYCBwYMDAUEAwwHAwQMBAMJAgkDCQIFDAUCAgYMDAYHBAUMBgwEDAsEAwQL
|
||||
BAMJAgkDCQIMDAoJBgoMDAILBQwHBQsMCwUCCQIFAgkDDAMJCQgMDAgHCwMMBAwGBAoMCgQBCAEE
|
||||
AQgCDAIICAsMDAsGCgIMAgwGAgcMBwIIAQgCCAEEDAQBAQUMDAUGBwQMBQwHDAoHAgcKBwIIAQgC
|
||||
CAEMDAkIBQkMDAEKAQwDDAkDBAMJAwQLBQsECwUMDAoLAQoMDAUJAQwDAQgMCAEECgQBBAoHDAcK
|
||||
CgsMDAsDCAcMBwwFBwkMCQcACwAHAAsBDAELCwoMDAoFCQEMAQwFAQYMBgELAAsBCwAHDAcAAAQM
|
||||
DAQFBgcMBAwGDAkGAQYJBgELAAsBCwAMDAgLBAgMDAAJAwwHDAAHCQcABwkGAQYJBgEMDAIGAwIM
|
||||
DAEAAQwFDAIFCwUCBQsEAwQLBAMMDAAEAQAMDAMCAAwCAAsMCwAHCQcABwkGDAYJCQoMDAoCCwYM
|
||||
AAwCDAgCBwIIAgcKBAoHCgQMDAkKAAkMDAQIBwwFDAgFAAUIBQAKAwoACgMMDAsKBwsMDAMIBgwE
|
||||
BggMCAYDCgMGAwoADAAKCgkMDAkECAAMAAwEAAUMBQAKAwoACgMGDAYDAwcMDAcEBQYMAgwADAoA
|
||||
BQAKAAUIBggFCAYMDAsIAgsMDAYKAgwAAgkMCQIFCwUCBQsEDAQLCwgMDAgACQQMAgwGDAMGCAYD
|
||||
BggFAAUIBQAMDAEFAgEMDAADAAwEDAEECgQBBAoHAgcKBwIMDAMHAAMMDAIBAwwBDAsBBgELAQYJ
|
||||
BwkGCQcMDAgJAwgMDAcLAwwBAwoMCgMGCAYDBggFDAUICAkMDAkBCgUM
|
||||
"""
|
||||
|
||||
#static const char tiling6_2[48][15]
|
||||
TILING6_2 = (48, 15), """
|
||||
AQoDBgMKAwYIBQgGCAUJAQsDCwEGCQYBBgkHCAcJBAEAAQQKBwoECgcCAwIHBgMCAwYIBQgGCAUA
|
||||
AQAFAAkCBQIJAgULBAsFCwQIAAoCCgAFCAUABQgGCwYIBAUACgAFAAoDBgMKAwYHBAgGAwYIBgMK
|
||||
AAoDCgAJBQgHCAUACgAFAAoDCwMKAggACAIHCgcCBwoECQQKAgsABwALAAcJBgkHCQYKBQIBAgUL
|
||||
BAsFCwQDAAMEBwADAAcJBgkHCQYBAgEGBgkECQYBCwEGAQsACAALBQYBCwEGAQsABwALAAcEBQkH
|
||||
AAcJBwALAQsACwEKAwgBBAEIAQQKBwoECgcLAwkBCQMECwQDBAsFCgULBwoFCgcCCAIHAggBCQEI
|
||||
BgcCCAIHAggBBAEIAQQFBgoEAQQKBAEIAggBCAILBwsFAgULBQIJAwkCCQMIBAsGCwQDCQMEAwkC
|
||||
CgIJBwQDCQMEAwkCBQIJAgUGAwQHBAMJAgkDCQIFBgUCBgsEAwQLBAMJAgkDCQIKBQsHCwUCCQIF
|
||||
AgkDCAMJBAoGCgQBCAEEAQgCCwIIAgcGBwIIAQgCCAEEBQQBBQoHAgcKBwIIAQgCCAEJAQkDBAMJ
|
||||
AwQLBQsECwUKAQgDCAEECgQBBAoHCwcKBwkFCQcACwAHAAsBCgELAQYFBgELAAsBCwAHBAcABAkG
|
||||
AQYJBgELAAsBCwAIAwAHCQcABwkGAQYJBgECAQIFCwUCBQsEAwQLBAMAAAsCCwAHCQcABwkGCgYJ
|
||||
AAgCBwIIAgcKBAoHCgQJBwgFAAUIBQAKAwoACgMLBggECAYDCgMGAwoACQAKAAUEBQAKAwoACgMG
|
||||
BwYDAgoABQAKAAUIBggFCAYLAgkACQIFCwUCBQsECAQLAgMGCAYDBggFAAUIBQABAAEECgQBBAoH
|
||||
AgcKBwIDAwsBBgELAQYJBwkGCQcIAwoBCgMGCAYDBggFCQUI
|
||||
"""
|
||||
|
||||
#static const char tiling7_1[16][9]
|
||||
TILING7_1 = (16, 9), """
|
||||
CQUECgECCAMACwcGCAMACgECAwAIBQQJBwYLCAQHCQABCwIDCgYFCwIDCQABAAEJBgUKBAcIAQIK
|
||||
BwYLBQQJAgMLBAcIBgUKCwMCCAcECgUGCgIBCwYHCQQFCQEACgUGCAcEBQYKAwILAQAJBwQIAQAJ
|
||||
AwILCAADCQQFCwYHBgcLAAMIAgEKBAUJAgEKAAMI
|
||||
"""
|
||||
|
||||
#static const char tiling7_2[16][3][15]
|
||||
TILING7_2 = (16, 3, 15), """
|
||||
AQIKAwQIBAMFAAUDBQAJAwAICQEEAgQBBAIFCgUCCQUEAAoBCgAICggCAwIIAwAIAQYKBgEHAgcB
|
||||
BwILAQIKCwMGAAYDBgAHCAcACwcGAggDCAIKCAoAAQAKCQUECwMGAAYDBgAHCAcACwcGAwQIBAMF
|
||||
AAUDBQAJAwAIBAkHCwcJBQsJCwUGAAEJAgcLBwIEAwQCBAMIAgMLCAAHAQcABwEECQQBCAQHAwkA
|
||||
CQMLCQsBAgELAgMLAAUJBQAGAQYABgEKAAEJCgIFAwUCBQMGCwYDBgUKAQsCCwEJCwkDAAMJBgUK
|
||||
CAAHAQcABwEECQQBCAQHAAUJBQAGAQYABgEKAAEJBQoECAQKBggKCAYHCwcGCQEEAgQBBAIFCgUC
|
||||
CQUEAQYKBgEHAgcBBwILAQIKBgsFCQULBwkLCQcECAQHCgIFAwUCBQMGCwYDBgUKAgcLBwIEAwQC
|
||||
BAMIAgMLBwgGCgYIBAoICgQFBwQIBQIKAgUDBgMFAwYLCgUGCwcCBAIHAgQDCAMECwMCBggHCAYK
|
||||
CAoEBQQKBgcLBAEJAQQCBQIEAgUKBAUJCgYBBwEGAQcCCwIHCgIBBQsGCwUJCwkHBAcJCgUGBwAI
|
||||
AAcBBAEHAQQJBwQICQUABgAFAAYBCgEGCQEABAoFCgQICggGBwYICwMCCQUABgAFAAYBCgEGCQEA
|
||||
BQIKAgUDBgMFAwYLCgUGAgsBCQELAwkLCQMACQEACwcCBAIHAgQDCAMECwMCBwAIAAcBBAEHAQQJ
|
||||
BwQIAAkDCwMJAQsJCwECBAUJBgMLAwYABwAGAAcIBgcLCAQDBQMEAwUACQAFCAADBwkECQcLCQsF
|
||||
BgULCAADCgYBBwEGAQcCCwIHCgIBBgMLAwYABwAGAAcIBgcLAwgCCgIIAAoICgABCgIBCAQDBQME
|
||||
AwUACQAFCAADBAEJAQQCBQIEAgUKBAUJAQoACAAKAggKCAID
|
||||
"""
|
||||
|
||||
#static const char tiling7_3[16][3][27]
|
||||
TILING7_3 = (16, 3, 27), """
|
||||
DAIKDAoFDAUEDAQIDAgDDAMADAAJDAkBDAECDAUEDAQIDAgDDAMCDAIKDAoBDAEADAAJDAkFBQQM
|
||||
CgUMAgoMAwIMCAMMAAgMAQAMCQEMBAkMDAAIDAgHDAcGDAYKDAoBDAECDAILDAsDDAMADAcGDAYK
|
||||
DAoBDAEADAAIDAgDDAMCDAILDAsHBwYMCAcMAAgMAQAMCgEMAgoMAwIMCwMMBgsMCQUMAAkMAwAM
|
||||
CwMMBgsMBwYMCAcMBAgMBQQMAwAMCwMMBgsMBQYMCQUMBAkMBwQMCAcMAAgMDAMADAAJDAkFDAUG
|
||||
DAYLDAsHDAcEDAQIDAgDDAEJDAkEDAQHDAcLDAsCDAIDDAMIDAgADAABDAQHDAcLDAsCDAIBDAEJ
|
||||
DAkADAADDAMIDAgEBAcMCQQMAQkMAgEMCwIMAwsMAAMMCAAMBwgMDAMLDAsGDAYFDAUJDAkADAAB
|
||||
DAEKDAoCDAIDDAYFDAUJDAkADAADDAMLDAsCDAIBDAEKDAoGBgUMCwYMAwsMAAMMCQAMAQkMAgEM
|
||||
CgIMBQoMCgYMAQoMAAEMCAAMBwgMBAcMCQQMBQkMBgUMAAEMCAAMBwgMBgcMCgYMBQoMBAUMCQQM
|
||||
AQkMDAABDAEKDAoGDAYHDAcIDAgEDAQFDAUJDAkACwcMAgsMAQIMCQEMBAkMBQQMCgUMBgoMBwYM
|
||||
AQIMCQEMBAkMBwQMCwcMBgsMBQYMCgUMAgoMDAECDAILDAsHDAcEDAQJDAkFDAUGDAYKDAoBCAQM
|
||||
AwgMAgMMCgIMBQoMBgUMCwYMBwsMBAcMAgMMCgIMBQoMBAUMCAQMBwgMBgcMCwYMAwsMDAIDDAMI
|
||||
DAgEDAQFDAUKDAoGDAYHDAcLDAsCDAQIDAgDDAMCDAIKDAoFDAUGDAYLDAsHDAcEDAMCDAIKDAoF
|
||||
DAUEDAQIDAgHDAcGDAYLDAsDAwIMCAMMBAgMBQQMCgUMBgoMBwYMCwcMAgsMDAcLDAsCDAIBDAEJ
|
||||
DAkEDAQFDAUKDAoGDAYHDAIBDAEJDAkEDAQHDAcLDAsGDAYFDAUKDAoCAgEMCwIMBwsMBAcMCQQM
|
||||
BQkMBgUMCgYMAQoMDAYKDAoBDAEADAAIDAgHDAcEDAQJDAkFDAUGDAEADAAIDAgHDAcGDAYKDAoF
|
||||
DAUEDAQJDAkBAQAMCgEMBgoMBwYMCAcMBAgMBQQMCQUMAAkMCwMMBgsMBQYMCQUMAAkMAQAMCgEM
|
||||
AgoMAwIMBQYMCQUMAAkMAwAMCwMMAgsMAQIMCgEMBgoMDAUGDAYLDAsDDAMADAAJDAkBDAECDAIK
|
||||
DAoFCQEMBAkMBwQMCwcMAgsMAwIMCAMMAAgMAQAMBwQMCwcMAgsMAQIMCQEMAAkMAwAMCAMMBAgM
|
||||
DAcEDAQJDAkBDAECDAILDAsDDAMADAAIDAgHDAUJDAkADAADDAMLDAsGDAYHDAcIDAgEDAQFDAAD
|
||||
DAMLDAsGDAYFDAUJDAkEDAQHDAcIDAgAAAMMCQAMBQkMBgUMCwYMBwsMBAcMCAQMAwgMCAAMBwgM
|
||||
BgcMCgYMAQoMAgEMCwIMAwsMAAMMBgcMCgYMAQoMAAEMCAAMAwgMAgMMCwIMBwsMDAYHDAcIDAgA
|
||||
DAABDAEKDAoCDAIDDAMLDAsGCgIMBQoMBAUMCAQMAwgMAAMMCQAMAQkMAgEMBAUMCAQMAwgMAgMM
|
||||
CgIMAQoMAAEMCQAMBQkMDAQFDAUKDAoCDAIDDAMIDAgADAABDAEJDAkE
|
||||
"""
|
||||
|
||||
#static const char tiling7_4_1[16][15]
|
||||
TILING7_4_1 = (16, 15), """
|
||||
AwQIBAMKAgoDBAoFCQEAAQYKBgEIAAgBBggHCwMCCwMGCQYDBgkFAAkDBwQIAgcLBwIJAQkCBwkE
|
||||
CAADAAUJBQALAwsABQsGCgIBCAAHCgcABwoGAQoABAUJCQEECwQBBAsHAgsBBQYKCgIFCAUCBQgE
|
||||
AwgCBgcLBQIKAgUIBAgFAggDCwcGBAEJAQQLBwsEAQsCCgYFBwAIAAcKBgoHAAoBCQUECQUACwAF
|
||||
AAsDBgsFAQIKCwcCCQIHAgkBBAkHAwAIBgMLAwYJBQkGAwkACAQHCgYBCAEGAQgABwgGAgMLCAQD
|
||||
CgMEAwoCBQoEAAEJ
|
||||
"""
|
||||
|
||||
#static const char tiling7_4_2[16][27]
|
||||
TILING7_4_2 = (16, 27), """
|
||||
CQQIBAkFCgUJAQoJCgECAAIBAgADCAMACQgACwYKBgsHCAcLAwgLCAMAAgADAAIBCgECCwoCCwMI
|
||||
AAgDCAAJCAkEBQQJBAUHBgcFBwYLBwsICAcLBwgECQQIAAkICQABAwEAAQMCCwIDCAsDCgUJBQoG
|
||||
CwYKAgsKCwIDAQMCAwEACQABCgkBCAAJAQkACQEKCQoFBgUKBQYEBwQGBAcIBAgJCQEKAgoBCgIL
|
||||
CgsGBwYLBgcFBAUHBQQJBQkKCgILAwsCCwMICwgHBAcIBwQGBQYEBgUKBgoLCwIKAgsDCAMLBwgL
|
||||
CAcEBgQHBAYFCgUGCwoGCgEJAQoCCwIKBgsKCwYHBQcGBwUECQQFCgkFCQAIAAkBCgEJBQoJCgUG
|
||||
BAYFBgQHCAcECQgECQUKBgoFCgYLCgsCAwILAgMBAAEDAQAJAQkKCwcIBAgHCAQJCAkAAQAJAAED
|
||||
AgMBAwILAwsICAMLAwgACQAIBAkICQQFBwUEBQcGCwYHCAsHCgYLBwsGCwcICwgDAAMIAwACAQIA
|
||||
AgEKAgoLCAQJBQkECQUKCQoBAgEKAQIAAwACAAMIAAgJ
|
||||
"""
|
||||
|
||||
#static const char tiling8[6][6]
|
||||
TILING8 = (6, 6), """
|
||||
CQgKCggLAQUDAwUHAAQCBAYCAAIEBAIGAQMFAwcFCQoICgsI
|
||||
"""
|
||||
|
||||
#static const char tiling9[8][12]
|
||||
TILING9 = (8, 12), """
|
||||
AgoFAwIFAwUEAwQIBAcLCQQLCQsCCQIBCgcGAQcKAQgHAQAIAwYLAAYDAAUGAAkFAwsGAAMGAAYF
|
||||
AAUJCgYHAQoHAQcIAQgABAsHCQsECQILCQECAgUKAwUCAwQFAwgE
|
||||
"""
|
||||
|
||||
#static const char tiling10_1_1[6][12]
|
||||
TILING10_1_1 = (6, 12), """
|
||||
BQoHCwcKCAEJAQgDAQIFBgUCBAMAAwQHCwAIAAsCBAkGCgYJCQAKAgoABggECAYLBwIDAgcGAAEE
|
||||
BQQBBwkFCQcICgELAwsB
|
||||
"""
|
||||
|
||||
#static const char tiling10_1_1_[6][12]
|
||||
TILING10_1_1_ = (6, 12), """
|
||||
BQkHCAcJCwEKAQsDAwIHBgcCBAEAAQQFCgAJAAoCBAgGCwYICAALAgsABgkECQYKBQIBAgUGAAME
|
||||
BwQDBwoFCgcLCQEIAwgB
|
||||
"""
|
||||
|
||||
#static const char tiling10_1_2[6][24]
|
||||
TILING10_1_2 = (6, 24), """
|
||||
AwsHAwcICQgHBQkHCQUKCQoBAwEKCwMKBwYFBwUEAAQFAQAFAAECAAIDBwMCBgcCCwIKBgsKCwYE
|
||||
CwQIAAgECQAEAAkKAAoCCwIKCwoGBAYKCQQKBAkABAAICwgAAgsABwYFBAcFBwQABwADAgMAAQIA
|
||||
AgEFAgUGBwgDCwcDBwsKBwoFCQUKAQkKCQEDCQMI
|
||||
"""
|
||||
|
||||
#static const char tiling10_2[6][24]
|
||||
TILING10_2 = (6, 24), """
|
||||
DAUJDAkIDAgDDAMBDAEKDAoLDAsHDAcFDAEADAAEDAQHDAcDDAMCDAIGDAYFDAUBBAgMBgQMCgYM
|
||||
CQoMAAkMAgAMCwIMCAsMDAkEDAQGDAYLDAsIDAgADAACDAIKDAoJAAMMBAAMBQQMAQUMAgEMBgIM
|
||||
BwYMAwcMCgUMCwoMAwsMAQMMCQEMCAkMBwgMBQcM
|
||||
"""
|
||||
|
||||
#static const char tiling10_2_[6][24]
|
||||
TILING10_2_ = (6, 24), """
|
||||
CAcMCQgMAQkMAwEMCwMMCgsMBQoMBwUMBAUMAAQMAwAMBwMMBgcMAgYMAQIMBQEMDAsGDAYEDAQJ
|
||||
DAkKDAoCDAIADAAIDAgLBgoMBAYMCAQMCwgMAgsMAAIMCQAMCgkMDAcEDAQADAABDAEFDAUGDAYC
|
||||
DAIDDAMHDAcLDAsKDAoBDAEDDAMIDAgJDAkFDAUH
|
||||
"""
|
||||
|
||||
#static const char tiling11[12][12]
|
||||
TILING11 = (12, 12), """
|
||||
AgoJAgkHAgcDBwkEAQYCAQgGAQkICAcGCAMBCAEGCAYEBgEKAAgLAAsFAAUBBQsGCQUHCQcCCQIA
|
||||
AgcLBQAEBQsABQoLCwMABQQABQALBQsKCwADCQcFCQIHCQACAgsHAAsIAAULAAEFBQYLCAEDCAYB
|
||||
CAQGBgoBAQIGAQYIAQgJCAYHAgkKAgcJAgMHBwQJ
|
||||
"""
|
||||
|
||||
#static const char tiling12_1_1[24][12]
|
||||
TILING12_1_1 = (24, 12), """
|
||||
BwYLCgMCAwoICQgKBgUKCQIBAgkLCAsJCgYFBwkECQcBAwEHBwYLBAgFAwUIBQMBBQQJCAEAAQgK
|
||||
CwoIAQIKAAkDBQMJAwUHCgECAAsDCwAGBAYACAMAAgkBCQIEBgQCAwAIAgsBBwELAQcFBgUKBwsE
|
||||
AgQLBAIACQUEBggHCAYAAgAGCAMABwQLCQsECwkKBAcICwADAAsJCgkLBAcIBQkGAAYJBgACCwcG
|
||||
BAoFCgQCAAIECwIDAQgACAEHBQcBAAEJAwgCBAIIAgQGAgMLAQoABgAKAAYECQABAwoCCgMFBwUD
|
||||
CQABBAUICggFCAoLCAQHBQsGCwUDAQMFBQQJBgoHAQcKBwEDCgECBQYJCwkGCQsICwIDBgcKCAoH
|
||||
CggJ
|
||||
"""
|
||||
|
||||
#static const char tiling12_1_1_[24][12]
|
||||
TILING12_1_1_ = (24, 12), """
|
||||
AwILCgcGBwoICQgKAgEKCQYFBgkLCAsJCQQFBwoGCgcBAwEHBwQIBgsFAwULBQMBAQAJCAUEBQgK
|
||||
CwoIAQAJAgoDBQMKAwUHCwMCAAoBCgAGBAYACQEAAggDCAIEBgQCAwILAAgBBwEIAQcFBgcLBQoE
|
||||
AgQKBAIACAcEBgkFCQYAAgAGCAcEAwALCQsACwkKAAMICwQHBAsJCgkLBAUJBwgGAAYIBgACCgUG
|
||||
BAsHCwQCAAIECAADAQsCCwEHBQcBAAMIAQkCBAIJAgQGAgEKAwsABgALAAYECgIBAwkACQMFBwUD
|
||||
CQQFAAEICggBCAoLCwYHBQgECAUDAQMFBQYKBAkHAQcJBwEDCgUGAQIJCwkCCQsICwYHAgMKCAoD
|
||||
CggJ
|
||||
"""
|
||||
|
||||
#static const char tiling12_1_2[24][24]
|
||||
TILING12_1_2 = (24, 24), """
|
||||
BwMLAwcICQgHBgkHCQYKAgoGCwIGAgsDBgIKAgYLCAsGBQgGCAUJAQkFCgEFAQoCCgkFCQoBAwEK
|
||||
BgMKAwYHBAcGBQQGBAUJBwgLAwsICwMBCwEGBQYBBgUEBgQHCAcEBQEJAQUKCwoFBAsFCwQIAAgE
|
||||
CQAEAAkBAQkKBQoJCgUHCgcCAwIHAgMAAgABCQEACgsCCwoGBAYKAQQKBAEAAwABAgMBAwILCAkA
|
||||
CQgEBgQIAwYIBgMCAQIDAAEDAQAJAwsIBwgLCAcFCAUAAQAFAAECAAIDCwMCBgsKAgoLCgIACgAF
|
||||
BAUABQQHBQcGCwYHCQgECAkAAgAJBQIJAgUGBwYFBAcFBwQICAQACQAEAAkKAAoDCwMKAwsHAwcI
|
||||
BAgHBAAIAAQJCgkEBwoECgcLAwsHCAMHAwgABAkIAAgJCAACCAIHBgcCBwYFBwUECQQFCwoGCgsC
|
||||
AAILBwALAAcEBQQHBgUHBQYKCwgDCAsHBQcLAgULBQIBAAECAwACAAMIAAgJBAkICQQGCQYBAgEG
|
||||
AQIDAQMACAADAgoLBgsKCwYECwQDAAMEAwABAwECCgIBCQoBCgkFBwUJAAcJBwADAgMAAQIAAgEK
|
||||
CQUBCgEFAQoLAQsACAALAAgEAAQJBQkECAsHCwgDAQMIBAEIAQQFBgUEBwYEBgcLBQoJAQkKCQED
|
||||
CQMEBwQDBAcGBAYFCgUGCgYCCwIGAgsIAggBCQEIAQkFAQUKBgoFCwcDCAMHAwgJAwkCCgIJAgoG
|
||||
AgYLBwsG
|
||||
"""
|
||||
|
||||
#static const char tiling12_2[24][24]
|
||||
TILING12_2 = (24, 24), """
|
||||
CQgMCgkMAgoMAwIMCwMMBgsMBwYMCAcMCAsMCQgMAQkMAgEMCgIMBQoMBgUMCwYMAwEMBwMMBAcM
|
||||
CQQMBQkMBgUMCgYMAQoMDAMBDAEFDAUGDAYLDAsHDAcEDAQIDAgDCwoMCAsMAAgMAQAMCQEMBAkM
|
||||
BQQMCgUMDAUHDAcDDAMCDAIKDAoBDAEADAAJDAkFBAYMAAQMAQAMCgEMAgoMAwIMCwMMBgsMBgQM
|
||||
AgYMAwIMCAMMAAgMAQAMCQEMBAkMDAcFDAUBDAEADAAIDAgDDAMCDAILDAsHDAIADAAEDAQFDAUK
|
||||
DAoGDAYHDAcLDAsCAgAMBgIMBwYMCAcMBAgMBQQMCQUMAAkMDAkKDAoLDAsHDAcEDAQIDAgDDAMA
|
||||
DAAJCgkMCwoMBwsMBAcMCAQMAwgMAAMMCQAMDAACDAIGDAYHDAcIDAgEDAQFDAUJDAkAAAIMBAAM
|
||||
BQQMCgUMBgoMBwYMCwcMAgsMBQcMAQUMAAEMCAAMAwgMAgMMCwIMBwsMDAQGDAYCDAIDDAMIDAgA
|
||||
DAABDAEJDAkEDAYEDAQADAABDAEKDAoCDAIDDAMLDAsGBwUMAwcMAgMMCgIMAQoMAAEMCQAMBQkM
|
||||
DAoLDAsIDAgADAABDAEJDAkEDAQFDAUKAQMMBQEMBgUMCwYMBwsMBAcMCAQMAwgMDAEDDAMHDAcE
|
||||
DAQJDAkFDAUGDAYKDAoBDAsIDAgJDAkBDAECDAIKDAoFDAUGDAYLDAgJDAkKDAoCDAIDDAMLDAsG
|
||||
DAYHDAcI
|
||||
"""
|
||||
|
||||
#static const char tiling12_2_[24][24]
|
||||
TILING12_2_ = (24, 24), """
|
||||
DAILDAsHDAcGDAYKDAoJDAkIDAgDDAMCDAEKDAoGDAYFDAUJDAkIDAgLDAsCDAIBDAQFDAUKDAoG
|
||||
DAYHDAcDDAMBDAEJDAkEBwYMCAcMBAgMBQQMAQUMAwEMCwMMBgsMDAAJDAkFDAUEDAQIDAgLDAsK
|
||||
DAoBDAEAAQIMCQEMAAkMAwAMBwMMBQcMCgUMAgoMDAECDAILDAsDDAMADAAEDAQGDAYKDAoBDAMA
|
||||
DAAJDAkBDAECDAIGDAYEDAQIDAgDAwAMCwMMAgsMAQIMBQEMBwUMCAcMAAgMBgUMCwYMBwsMBAcM
|
||||
AAQMAgAMCgIMBQoMDAcEDAQJDAkFDAUGDAYCDAIADAAIDAgHCAcMAAgMAwAMCwMMCgsMCQoMBAkM
|
||||
BwQMDAcIDAgADAADDAMLDAsKDAoJDAkEDAQHBAcMCQQMBQkMBgUMAgYMAAIMCAAMBwgMDAUGDAYL
|
||||
DAsHDAcEDAQADAACDAIKDAoFDAADDAMLDAsCDAIBDAEFDAUHDAcIDAgAAAMMCQAMAQkMAgEMBgIM
|
||||
BAYMCAQMAwgMAgEMCwIMAwsMAAMMBAAMBgQMCgYMAQoMDAIBDAEJDAkADAADDAMHDAcFDAUKDAoC
|
||||
CQAMBQkMBAUMCAQMCwgMCgsMAQoMAAEMDAYHDAcIDAgEDAQFDAUBDAEDDAMLDAsGBQQMCgUMBgoM
|
||||
BwYMAwcMAQMMCQEMBAkMCgEMBgoMBQYMCQUMCAkMCwgMAgsMAQIMCwIMBwsMBgcMCgYMCQoMCAkM
|
||||
AwgMAgMM
|
||||
"""
|
||||
|
||||
#static const char tiling13_1[2][12]
|
||||
TILING13_1 = (2, 12), """
|
||||
CwcGAQIKCAMACQUECAQHAgMLCQABCgYF
|
||||
"""
|
||||
|
||||
#static const char tiling13_1_[2][12]
|
||||
TILING13_1_ = (2, 12), """
|
||||
BwQICwMCAQAJBQYKBgcLCgIBAAMIBAUJ
|
||||
"""
|
||||
|
||||
#static const char tiling13_2[2][6][18]
|
||||
TILING13_2 = (2, 6, 18), """
|
||||
AQIKCwcGAwQIBAMFAAUDBQAJCAMACwcGCQEEAgQBBAIFCgUCCQUECAMAAQYKBgEHAgcBBwILCQUE
|
||||
AQIKCwMGAAYDBgAHCAcACQUECwcGAAoBCgAICggCAwIIAQIKAwAIBAkHCwcJBQsJCwUGAgMLCAQH
|
||||
AAUJBQAGAQYABgEKCQABCAQHCgIFAwUCBQMGCwYDBgUKCQABAgcLBwIEAwQCBAMIBgUKAgMLCAAH
|
||||
AQcABwEECQQBBgUKCAQHAQsCCwEJCwkDAAMJAgMLAAEJBQoECAQKBggKCAYH
|
||||
"""
|
||||
|
||||
#static const char tiling13_2_[2][6][18]
|
||||
TILING13_2_ = (2, 6, 18), """
|
||||
CgUGCwMCBwAIAAcBBAEHAQQJCwMCBwQICQUABgAFAAYBCgEGAQAJBwQIBQIKAgUDBgMFAwYLCgUG
|
||||
AQAJCwcCBAIHAgQDCAMECgUGBwQIAgsBCQELAwkLCQMACwMCCQEABAoFCgQICggGBwYIBgcLCAAD
|
||||
BAEJAQQCBQIEAgUKCAADBAUJCgYBBwEGAQcCCwIHAgEKBAUJBgMLAwYABwAGAAcIBgcLAgEKCAQD
|
||||
BQMEAwUACQAFBgcLBAUJAwgCCgIIAAoICgABCAADCgIBBQsGCwUJCwkHBAcJ
|
||||
"""
|
||||
|
||||
#static const char tiling13_3[2][12][30]
|
||||
TILING13_3 = (2, 12, 30), """
|
||||
CwcGDAIKDAoFDAUEDAQIDAgDDAMADAAJDAkBDAECAQIKCQUMAAkMAwAMCwMMBgsMBwYMCAcMBAgM
|
||||
BQQMCwcGDAUEDAQIDAgDDAMCDAIKDAoBDAEADAAJDAkFAQIKDAMADAAJDAkFDAUGDAYLDAsHDAcE
|
||||
DAQIDAgDCAMACwcMAgsMAQIMCQEMBAkMBQQMCgUMBgoMBwYMCwcGBQQMCgUMAgoMAwIMCAMMAAgM
|
||||
AQAMCQEMBAkMCAMAAQIMCQEMBAkMBwQMCwcMBgsMBQYMCgUMAgoMCQUEDAAIDAgHDAcGDAYKDAoB
|
||||
DAECDAILDAsDDAMACQUEDAcGDAYKDAoBDAEADAAIDAgDDAMCDAILDAsHCAMADAECDAILDAsHDAcE
|
||||
DAQJDAkFDAUGDAYKDAoBCQUEBwYMCAcMAAgMAQAMCgEMAgoMAwIMCwMMBgsMAQIKAwAMCwMMBgsM
|
||||
BQYMCQUMBAkMBwQMCAcMAAgMCAQHDAMLDAsGDAYFDAUJDAkADAABDAEKDAoCDAIDAgMLCgYMAQoM
|
||||
AAEMCAAMBwgMBAcMCQQMBQkMBgUMCAQHDAYFDAUJDAkADAADDAMLDAsCDAIBDAEKDAoGAgMLDAAB
|
||||
DAEKDAoGDAYHDAcIDAgEDAQFDAUJDAkAAAEJCAQMAwgMAgMMCgIMBQoMBgUMCwYMBwsMBAcMCAQH
|
||||
BgUMCwYMAwsMAAMMCQAMAQkMAgEMCgIMBQoMCQABAgMMCgIMBQoMBAUMCAQMBwgMBgcMCwYMAwsM
|
||||
BgUKDAEJDAkEDAQHDAcLDAsCDAIDDAMIDAgADAABBgUKDAQHDAcLDAsCDAIBDAEJDAkADAADDAMI
|
||||
DAgECQABDAIDDAMIDAgEDAQFDAUKDAoGDAYHDAcLDAsCBgUKBAcMCQQMAQkMAgEMCwIMAwsMAAMM
|
||||
CAAMBwgMAgMLAAEMCAAMBwgMBgcMCgYMBQoMBAUMCQQMAQkM
|
||||
"""
|
||||
|
||||
#static const char tiling13_3_[2][12][30]
|
||||
TILING13_3_ = (2, 12, 30), """
|
||||
AwILCAcMAAgMAQAMCgEMBgoMBQYMCQUMBAkMBwQMBQYKDAILDAsHDAcEDAQJDAkBDAEADAAIDAgD
|
||||
DAMCCgUGDAcEDAQJDAkBDAECDAILDAsDDAMADAAIDAgHCwMCDAEADAAIDAgHDAcGDAYKDAoFDAUE
|
||||
DAQJDAkBBwQICwMMBgsMBQYMCQUMAAkMAQAMCgEMAgoMAwIMBwQIBQYMCQUMAAkMAwAMCwMMAgsM
|
||||
AQIMCgEMBgoMCwMCAQAMCgEMBgoMBwYMCAcMBAgMBQQMCQUMAAkMAQAJDAQIDAgDDAMCDAIKDAoF
|
||||
DAUGDAYLDAsHDAcEBwQIDAUGDAYLDAsDDAMADAAJDAkBDAECDAIKDAoFAQAJDAMCDAIKDAoFDAUE
|
||||
DAQIDAgHDAcGDAYLDAsDCgUGBwQMCwcMAgsMAQIMCQEMAAkMAwAMCAMMBAgMCQEAAwIMCAMMBAgM
|
||||
BQQMCgUMBgoMBwYMCwcMAgsMAAMICQQMAQkMAgEMCwIMBwsMBgcMCgYMBQoMBAUMCwYHDAMIDAgE
|
||||
DAQFDAUKDAoCDAIBDAEJDAkADAADBgcLDAQFDAUKDAoCDAIDDAMIDAgADAABDAEJDAkECAADDAIB
|
||||
DAEJDAkEDAQHDAcLDAsGDAYFDAUKDAoCBAUJCAAMBwgMBgcMCgYMAQoMAgEMCwIMAwsMAAMMBAUJ
|
||||
BgcMCgYMAQoMAAEMCAAMAwgMAgMMCwIMBwsMCAADAgEMCwIMBwsMBAcMCQQMBQkMBgUMCgYMAQoM
|
||||
AgEKDAUJDAkADAADDAMLDAsGDAYHDAcIDAgEDAQFBAUJDAYHDAcIDAgADAABDAEKDAoCDAIDDAML
|
||||
DAsGAgEKDAADDAMLDAsGDAYFDAUJDAkEDAQHDAcIDAgABgcLBAUMCAQMAwgMAgMMCgIMAQoMAAEM
|
||||
CQAMBQkMCgIBAAMMCQAMBQkMBgUMCwYMBwsMBAcMCAQMAwgM
|
||||
"""
|
||||
|
||||
#static const char tiling13_4[2][4][36]
|
||||
TILING13_4 = (2, 4, 36), """
|
||||
DAIKDAoFDAUGDAYLDAsHDAcEDAQIDAgDDAMADAAJDAkBDAECCwMMBgsMBwYMCAcMBAgMBQQMCQUM
|
||||
AAkMAQAMCgEMAgoMAwIMCQEMBAkMBQQMCgUMBgoMBwYMCwcMAgsMAwIMCAMMAAgMAQAMDAAIDAgH
|
||||
DAcEDAQJDAkFDAUGDAYKDAoBDAECDAILDAsDDAMADAMLDAsGDAYHDAcIDAgEDAQFDAUJDAkADAAB
|
||||
DAEKDAoCDAIDCAAMBwgMBAcMCQQMBQkMBgUMCgYMAQoMAgEMCwIMAwsMAAMMCgIMBQoMBgUMCwYM
|
||||
BwsMBAcMCAQMAwgMAAMMCQAMAQkMAgEMDAEJDAkEDAQFDAUKDAoGDAYHDAcLDAsCDAIDDAMIDAgA
|
||||
DAAB
|
||||
"""
|
||||
|
||||
#static const char tiling13_5_1[2][4][18]
|
||||
TILING13_5_1 = (2, 4, 18), """
|
||||
BwYLAQAJCgMCAwoFAwUIBAgFAQIKBwQIAwALBgsACQYABgkFAwAIBQYKAQIJBAkCCwQCBAsHBQQJ
|
||||
AwILCAEAAQgHAQcKBgoHBAcIAgEKCwADAAsGAAYJBQkGAgMLBAUJAAEIBwgBCgcBBwoGAAEJBgcL
|
||||
AgMKBQoDCAUDBQgEBgUKAAMICQIBAgkEAgQLBwsE
|
||||
"""
|
||||
|
||||
#static const char tiling13_5_2[2][4][30]
|
||||
TILING13_5_2 = (2, 4, 30), """
|
||||
AQAJBwQIBwgDBwMLAgsDCwIKCwoGBQYKBgUHBAcFBwQICwMCBgsCCgYCBgoFCQUKAQkKCQEAAgAB
|
||||
AAIDBQYKCQEABAkACAQABAgHCwcIAwsICwMCAAIDAgABAwILBQYKBQoBBQEJAAkBCQAICQgEBAgH
|
||||
BAcFBgUHAgEKBAUJBAkABAAIAwgACAMLCAsHBgcLBwYEBQQGBAUJCAADBwgDCwcDBwsGCgYLAgoL
|
||||
CgIBAwECAQMABgcLCgIBBQoBCQUBBQkECAQJAAgJCAADAQMAAwECAAMIBgcLBgsCBgIKAQoCCgEJ
|
||||
CgkFBQkEBQQGBwYE
|
||||
"""
|
||||
|
||||
#static const char tiling14[12][12]
|
||||
TILING14 = (12, 12), """
|
||||
BQkIBQgCBQIGAwIIAgEFAgUIAggLBAgFCQQGCQYDCQMBCwMGAQsKAQQLAQAEBwsECAIACAUCCAcF
|
||||
CgIFAAcDAAoHAAkKBgcKAAMHAAcKAAoJBgoHCAACCAIFCAUHCgUCAQoLAQsEAQQABwQLCQYECQMG
|
||||
CQEDCwYDAgUBAggFAgsIBAUIBQgJBQIIBQYCAwgC
|
||||
"""
|
||||
|
||||
#static const char test3[24]
|
||||
TEST3 = (24,), """
|
||||
BQEEBQECAgMEAwYG+vr9/P3+/v/7/P/7
|
||||
"""
|
||||
|
||||
#static const char test4[8]
|
||||
TEST4 = (8,), """
|
||||
BwcHB/n5+fk=
|
||||
"""
|
||||
|
||||
#static const char test6[48][3]
|
||||
TEST6 = (48, 3), """
|
||||
AgcKBAcLBQcBBQcDAQcJAwcKBgcFAQcIBAcIAQcIAwcLBQcCBQcAAQcJBgcGAgcJBAcIAgcJAgcK
|
||||
BgcHAwcKBAcLAwcLBgcE+vkE/fkL/PkL/fkK+vkH/vkK/vkJ/PkI/vkJ+vkG//kJ+/kA+/kC/fkL
|
||||
//kI/PkI//kI+vkF/fkK//kJ+/kD+/kB/PkL/vkK
|
||||
"""
|
||||
|
||||
#static const char test7[16][5]
|
||||
TEST7 = (16, 5), """
|
||||
AQIFBwEDBAUHAwQBBgcEBAEFBwACAwUHAgECBgcFAgMGBwYDBAYHB/38+vkH/v36+Qb//vr5Bf79
|
||||
+/kC/P/7+QD8//r5BP38+/kD//77+QE=
|
||||
"""
|
||||
|
||||
#static const char test10[6][3]
|
||||
TEST10 = (6, 3), """
|
||||
AgQHBQYHAQMHAQMHBQYHAgQH
|
||||
"""
|
||||
|
||||
#static const char test12[24][4]
|
||||
TEST12 = (24, 4), """
|
||||
BAMHCwMCBwoCBgcFBgQHBwIBBwkFAgcBBQMHAgUBBwAFBAcDBgMHBgEGBwQBBAcIBAEHCAYBBwQD
|
||||
BgcGBAUHAwEFBwADBQcCAgUHAQECBwkEBgcHBgIHBQIDBwoDBAcL
|
||||
"""
|
||||
|
||||
#static const char test13[2][7]
|
||||
TEST13 = (2, 7), """
|
||||
AQIDBAUGBwIDBAEFBgc=
|
||||
"""
|
||||
|
||||
#static const char subconfig13[64]
|
||||
SUBCONFIG13 = (64,), """
|
||||
AAECBwP/C/8ECP//Dv///wUJDBcP/xUmERT/JBohHiwGCg0TEP8ZJRIY/yMWIB0r////Iv//HCr/
|
||||
H/8pGygnLQ==
|
||||
"""
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
This directory contains meta-files related to the Lewiner marching cubes
|
||||
algorithm. These are not used by the algorithm, but can be convenient
|
||||
for development/maintenance:
|
||||
|
||||
* MarchingCubes.cpp - the original algorithm, this is ported to Cython
|
||||
* LookupTable.h - the original LUTs, these are ported to Python
|
||||
* createluts.py - scrip to generate Python luts from the .h file
|
||||
* visual_test.py - script to compare visual results of marchingcubes algorithms
|
||||
@@ -0,0 +1,173 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Create lookup tables for the marching cubes algorithm, by parsing
|
||||
the file "LookUpTable.h". This prints a text to the stdout wich
|
||||
can then be copied to luts.py.
|
||||
|
||||
The luts are tuples of shape and base64 encoded bytes.
|
||||
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import sys
|
||||
import base64
|
||||
|
||||
# Get base64 encode/decode functions
|
||||
if sys.version_info >= (3, ):
|
||||
base64encode = base64.encodebytes
|
||||
base64decode = base64.decodebytes
|
||||
else:
|
||||
base64encode = base64.encodestring
|
||||
base64decode = base64.decodestring
|
||||
|
||||
def create_luts(fname):
|
||||
|
||||
# Get the lines in the C header file
|
||||
text = open(fname,'rb').read().decode('utf-8')
|
||||
lines1 = [line.rstrip() for line in text.splitlines()]
|
||||
|
||||
# Init lines for Python
|
||||
lines2 = []
|
||||
|
||||
# Get classic table
|
||||
more_lines, ii = get_table(lines1, 'static const char casesClassic', 0)
|
||||
lines2.extend(more_lines)
|
||||
|
||||
# Get cases table
|
||||
more_lines, ii = get_table(lines1, 'static const char cases', 0)
|
||||
lines2.extend(more_lines)
|
||||
|
||||
# Get tiling tables
|
||||
ii = 0
|
||||
for casenr in range(99):
|
||||
# Get table
|
||||
more_lines, ii = get_table(lines1, 'static const char tiling', ii+1)
|
||||
if ii < 0:
|
||||
break
|
||||
else:
|
||||
lines2.extend(more_lines)
|
||||
|
||||
# Get test tables
|
||||
ii = 0
|
||||
for casenr in range(99):
|
||||
# Get table
|
||||
more_lines, ii = get_table(lines1, 'static const char test', ii+1)
|
||||
if ii < 0:
|
||||
break
|
||||
else:
|
||||
lines2.extend(more_lines)
|
||||
|
||||
# Get subconfig tables
|
||||
ii = 0
|
||||
for casenr in range(99):
|
||||
# Get table
|
||||
more_lines, ii = get_table(lines1, 'static const char subconfig', ii+1)
|
||||
if ii < 0:
|
||||
break
|
||||
else:
|
||||
lines2.extend(more_lines)
|
||||
|
||||
return '\n'.join(lines2)
|
||||
|
||||
|
||||
def get_table(lines1, needle, i):
|
||||
|
||||
# Try to find the start
|
||||
ii = search_line(lines1, needle, i)
|
||||
if ii < 0:
|
||||
return [], -1
|
||||
|
||||
# Init result
|
||||
lines2 = []
|
||||
|
||||
# Get size and name
|
||||
front, dummu, back = lines1[ii].partition('[')
|
||||
name = front.split(' ')[-1].upper()
|
||||
size = int(back.split(']',1)[0])
|
||||
cdes = lines1[ii].rstrip(' {=')
|
||||
|
||||
# Write name
|
||||
lines2.append('%s = np.array([' % name)
|
||||
|
||||
# Get elements
|
||||
for i in range(ii+1, ii+1+9999999):
|
||||
line1 = lines1[i]
|
||||
front, dummy, back = line1.partition('*/')
|
||||
if not back:
|
||||
front, back = back, front
|
||||
line2 = ' '
|
||||
line2 += back.strip().replace('{', '[').replace('}',']').replace(';','')
|
||||
line2 += front.replace('/*',' #').rstrip()
|
||||
lines2.append(line2)
|
||||
if line1.endswith('};'):
|
||||
break
|
||||
|
||||
# Close and return
|
||||
lines2.append(" , 'int8')")
|
||||
lines2.append('')
|
||||
#return lines2, ii+size
|
||||
|
||||
# Execute code and get array as base64 text
|
||||
code = '\n'.join(lines2)
|
||||
code = code.split('=',1)[1]
|
||||
array = eval(code)
|
||||
array64 = base64encode(array.tostring()).decode('utf-8')
|
||||
# Reverse: bytes = base64decode(text.encode('utf-8'))
|
||||
text = '%s = %s, """\n%s"""' % (name, str(array.shape), array64)
|
||||
|
||||
# Build actual lines
|
||||
lines2 = []
|
||||
#lines2.append( '# %s -> %s %s' % (cdes, str(array.dtype), str(array.shape)) )
|
||||
lines2.append( '#' + cdes)
|
||||
lines2.append(text)
|
||||
lines2.append('')
|
||||
return lines2, ii+size
|
||||
|
||||
|
||||
def search_line(lines, refline, start=0):
|
||||
for i, line in enumerate(lines[start:]):
|
||||
if line.startswith(refline):
|
||||
return i + start
|
||||
return -1
|
||||
|
||||
|
||||
|
||||
def getLutNames(prefix):
|
||||
aa = []
|
||||
for a in dir(luts):
|
||||
if a.startswith(prefix): aa.append(a)
|
||||
|
||||
def sortkey(x):
|
||||
fullnr = x.split(prefix)[1]
|
||||
nr, us, subnr = fullnr.partition('_')
|
||||
if len(nr) == 1:
|
||||
nr = '0'+nr
|
||||
return nr + us + subnr
|
||||
|
||||
return [a for a in sorted(aa, key=sortkey)]
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import os
|
||||
fname = os.path.join(os.getcwd(), 'LookUpTable.h')
|
||||
|
||||
if True:
|
||||
with open(os.path.join(os.getcwd(), 'mcluts.py'), 'w') as f:
|
||||
f.write('# -*- coding: utf-8 -*-\n')
|
||||
f.write('# Copyright (C) 2012, Almar Klein\n# Copyright (C) 2002, Thomas Lewiner\n\n')
|
||||
f.write('# This file was auto-generated from LookUpTable.h by createluts.py.\n\n')
|
||||
f.write(create_luts(fname))
|
||||
|
||||
else:
|
||||
for prefix in ['TILING', 'TEST']:
|
||||
tmp = ['luts.'+a for a in getLutNames(prefix)]
|
||||
print(', '.join(tmp))
|
||||
print('')
|
||||
for name in getLutNames(prefix):
|
||||
print('self.%s = Lut(%s)' % (name, name))
|
||||
print('')
|
||||
for name in getLutNames(prefix):
|
||||
print('cdef Lut %s' % name)
|
||||
print('')
|
||||
print('')
|
||||
@@ -0,0 +1,72 @@
|
||||
"""
|
||||
Script to show the results of the two marching cubes algorithms on different
|
||||
data.
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
import visvis as vv
|
||||
|
||||
from skimage.measure import marching_cubes_classic, marching_cubes_lewiner
|
||||
from skimage.draw import ellipsoid
|
||||
|
||||
|
||||
# Create test volume
|
||||
SELECT = 3
|
||||
gradient_dir = 'descent' # ascent or descent
|
||||
|
||||
if SELECT == 1:
|
||||
# Medical data
|
||||
vol = vv.volread('stent')
|
||||
isovalue = 800
|
||||
|
||||
elif SELECT == 2:
|
||||
# Blocky data
|
||||
vol = vv.aVolume(20, 128) # Different every time
|
||||
isovalue = 0.2
|
||||
|
||||
elif SELECT == 3:
|
||||
# Generate two donuts using a formula by Thomas Lewiner
|
||||
n = 48
|
||||
a, b = 2.5/n, -1.25
|
||||
isovalue = 0.0
|
||||
#
|
||||
vol = np.empty((n,n,n), 'float32')
|
||||
for iz in range(vol.shape[0]):
|
||||
for iy in range(vol.shape[1]):
|
||||
for ix in range(vol.shape[2]):
|
||||
z, y, x = float(iz)*a+b, float(iy)*a+b, float(ix)*a+b
|
||||
vol[iz,iy,ix] = ( (
|
||||
(8*x)**2 + (8*y-2)**2 + (8*z)**2 + 16 - 1.85*1.85 ) * ( (8*x)**2 +
|
||||
(8*y-2)**2 + (8*z)**2 + 16 - 1.85*1.85 ) - 64 * ( (8*x)**2 + (8*y-2)**2 )
|
||||
) * ( ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 )
|
||||
* ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 ) -
|
||||
64 * ( ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2
|
||||
) ) + 1025
|
||||
# Uncommenting the line below will yield different results for classic MC
|
||||
#vol = -vol
|
||||
|
||||
elif SELECT == 4:
|
||||
vol = ellipsoid(4, 3, 2, levelset=True)
|
||||
isovalue = 0
|
||||
|
||||
# Get surface meshes
|
||||
t0 = time.time()
|
||||
vertices1, faces1, *_ = marching_cubes_lewiner(vol, isovalue, gradient_direction=gradient_dir, use_classic=False)
|
||||
print('finding surface lewiner took %1.0f ms' % (1000*(time.time()-t0)) )
|
||||
|
||||
t0 = time.time()
|
||||
vertices2, faces2, *_ = marching_cubes_classic(vol, isovalue, gradient_direction=gradient_dir)
|
||||
print('finding surface classic took %1.0f ms' % (1000*(time.time()-t0)) )
|
||||
|
||||
# Show
|
||||
vv.figure(1); vv.clf()
|
||||
a1 = vv.subplot(121); m1 = vv.mesh(np.fliplr(vertices1), faces1)
|
||||
a2 = vv.subplot(122); m2 = vv.mesh(np.fliplr(vertices2), faces2)
|
||||
a1.camera = a2.camera
|
||||
|
||||
# visvis uses right-hand rule, gradient_direction param uses left-hand rule
|
||||
m1.cullFaces = m2.cullFaces = 'front' # None, front or back
|
||||
|
||||
vv.use().Run()
|
||||
@@ -15,7 +15,8 @@ def configuration(parent_package='', top_path=None):
|
||||
cython(['_ccomp.pyx'], working_path=base_path)
|
||||
cython(['_find_contours_cy.pyx'], working_path=base_path)
|
||||
cython(['_moments_cy.pyx'], working_path=base_path)
|
||||
cython(['_marching_cubes_cy.pyx'], working_path=base_path)
|
||||
cython(['_marching_cubes_classic_cy.pyx'], working_path=base_path)
|
||||
cython(['_marching_cubes_lewiner_cy.pyx'], working_path=base_path)
|
||||
cython(['_pnpoly.pyx'], working_path=base_path)
|
||||
|
||||
config.add_extension('_ccomp', sources=['_ccomp.c'],
|
||||
@@ -24,8 +25,11 @@ def configuration(parent_package='', top_path=None):
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
config.add_extension('_moments_cy', sources=['_moments_cy.c'],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
config.add_extension('_marching_cubes_cy',
|
||||
sources=['_marching_cubes_cy.c'],
|
||||
config.add_extension('_marching_cubes_classic_cy',
|
||||
sources=['_marching_cubes_classic_cy.c'],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
config.add_extension('_marching_cubes_lewiner_cy',
|
||||
sources=['_marching_cubes_lewiner_cy.c'],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
config.add_extension('_pnpoly', sources=['_pnpoly.c'],
|
||||
include_dirs=[get_numpy_include_dirs(), '../_shared'])
|
||||
|
||||
@@ -1,17 +1,55 @@
|
||||
import sys
|
||||
import numpy as np
|
||||
from numpy.testing import assert_raises
|
||||
|
||||
from skimage.draw import ellipsoid, ellipsoid_stats
|
||||
from skimage.measure import (marching_cubes, mesh_surface_area,
|
||||
correct_mesh_orientation)
|
||||
from skimage.measure import (marching_cubes,
|
||||
marching_cubes_classic, marching_cubes_lewiner,
|
||||
mesh_surface_area, correct_mesh_orientation)
|
||||
from skimage.measure._marching_cubes_lewiner import _expected_output_args
|
||||
|
||||
def func_that_knows_about_its_outputs(r):
|
||||
# Must be defined in global scope to avoid syntax error on Python 2 *sigh*
|
||||
nout = _expected_output_args()
|
||||
print(nout)
|
||||
r.append(nout)
|
||||
return [nout] * int(nout)
|
||||
|
||||
|
||||
def test_expected_output_args():
|
||||
|
||||
foo = func_that_knows_about_its_outputs
|
||||
|
||||
res = []
|
||||
foo(res)
|
||||
a = foo(res)
|
||||
a, b = foo(res)
|
||||
a, b, c = foo(res)
|
||||
assert res == [0, 1, 2, 3] or res == [0, 0, 2, 3]
|
||||
# ``a = foo()`` somehow yields 0 in test, which is ok for us;
|
||||
# we only want to distinguish between > 2 args or not
|
||||
|
||||
if sys.version_info >= (3, 3):
|
||||
res = []
|
||||
exec('*a, b, c = foo(res)')
|
||||
exec('a, b, c, *d = foo(res)')
|
||||
exec('a, b, *c, d, e = foo(res)')
|
||||
assert res == [2.1, 3.1, 4.1]
|
||||
|
||||
|
||||
def test_marching_cubes_isotropic():
|
||||
ellipsoid_isotropic = ellipsoid(6, 10, 16, levelset=True)
|
||||
_, surf = ellipsoid_stats(6, 10, 16)
|
||||
verts, faces = marching_cubes(ellipsoid_isotropic, 0.)
|
||||
|
||||
# Classic
|
||||
verts, faces = marching_cubes_classic(ellipsoid_isotropic, 0.)
|
||||
surf_calc = mesh_surface_area(verts, faces)
|
||||
# Test within 1% tolerance for isotropic. Will always underestimate.
|
||||
assert surf > surf_calc and surf_calc > surf * 0.99
|
||||
|
||||
# Lewiner
|
||||
verts, faces = marching_cubes_lewiner(ellipsoid_isotropic, 0.)[:2]
|
||||
surf_calc = mesh_surface_area(verts, faces)
|
||||
|
||||
# Test within 1% tolerance for isotropic. Will always underestimate.
|
||||
assert surf > surf_calc and surf_calc > surf * 0.99
|
||||
|
||||
@@ -21,20 +59,35 @@ def test_marching_cubes_anisotropic():
|
||||
ellipsoid_anisotropic = ellipsoid(6, 10, 16, spacing=spacing,
|
||||
levelset=True)
|
||||
_, surf = ellipsoid_stats(6, 10, 16)
|
||||
verts, faces = marching_cubes(ellipsoid_anisotropic, 0.,
|
||||
spacing=spacing)
|
||||
|
||||
# Classic
|
||||
verts, faces = marching_cubes_classic(ellipsoid_anisotropic, 0.,
|
||||
spacing=spacing)
|
||||
surf_calc = mesh_surface_area(verts, faces)
|
||||
# Test within 1.5% tolerance for anisotropic. Will always underestimate.
|
||||
assert surf > surf_calc and surf_calc > surf * 0.985
|
||||
|
||||
# Lewiner
|
||||
verts, faces = marching_cubes_lewiner(ellipsoid_anisotropic, 0., spacing=spacing)[:2]
|
||||
surf_calc = mesh_surface_area(verts, faces)
|
||||
|
||||
# Test within 1.5% tolerance for anisotropic. Will always underestimate.
|
||||
assert surf > surf_calc and surf_calc > surf * 0.985
|
||||
|
||||
|
||||
def test_invalid_input():
|
||||
assert_raises(ValueError, marching_cubes, np.zeros((2, 2, 1)), 0)
|
||||
assert_raises(ValueError, marching_cubes, np.zeros((2, 2, 1)), 1)
|
||||
assert_raises(ValueError, marching_cubes, np.ones((3, 3, 3)), 1,
|
||||
# Classic
|
||||
assert_raises(ValueError, marching_cubes_classic, np.zeros((2, 2, 1)), 0)
|
||||
assert_raises(ValueError, marching_cubes_classic, np.zeros((2, 2, 1)), 1)
|
||||
assert_raises(ValueError, marching_cubes_classic, np.ones((3, 3, 3)), 1,
|
||||
spacing=(1, 2))
|
||||
assert_raises(ValueError, marching_cubes, np.zeros((20, 20)), 0)
|
||||
assert_raises(ValueError, marching_cubes_classic, np.zeros((20, 20)), 0)
|
||||
|
||||
# Lewiner
|
||||
assert_raises(ValueError, marching_cubes_lewiner, np.zeros((2, 2, 1)), 0)
|
||||
assert_raises(ValueError, marching_cubes_lewiner, np.zeros((2, 2, 1)), 1)
|
||||
assert_raises(ValueError, marching_cubes_lewiner, np.ones((3, 3, 3)), 1,
|
||||
spacing=(1, 2))
|
||||
assert_raises(ValueError, marching_cubes_lewiner, np.zeros((20, 20)), 0)
|
||||
|
||||
|
||||
def test_correct_mesh_orientation():
|
||||
@@ -74,5 +127,68 @@ def test_correct_mesh_orientation():
|
||||
np.testing.assert_array_equal(expected, corrected_faces1)
|
||||
|
||||
|
||||
def test_both_algs_same_result_ellipse():
|
||||
# Performing this test on data that does not have ambiguities
|
||||
|
||||
sphere_small = ellipsoid(1, 1, 1, levelset=True)
|
||||
|
||||
vertices1, faces1 = marching_cubes_classic(sphere_small, 0)[:2]
|
||||
vertices2, faces2 = marching_cubes_lewiner(sphere_small, 0, allow_degenerate=False)[:2]
|
||||
vertices3, faces3 = marching_cubes_lewiner(sphere_small, 0, allow_degenerate=False, use_classic=True)[:2]
|
||||
|
||||
# Order is different, best we can do is test equal shape and same vertices present
|
||||
assert _same_mesh(vertices1, faces1, vertices2, faces2)
|
||||
assert _same_mesh(vertices1, faces1, vertices3, faces3)
|
||||
|
||||
|
||||
def _same_mesh(vertices1, faces1, vertices2, faces2, tol=1e-10):
|
||||
""" Compare two meshes, using a certain tolerance and invariant to
|
||||
the order of the faces.
|
||||
"""
|
||||
# Unwind vertices
|
||||
triangles1 = vertices1[np.array(faces1)]
|
||||
triangles2 = vertices2[np.array(faces2)]
|
||||
# Sort vertices within each triangle
|
||||
triang1 = [np.concatenate(sorted(t, key=lambda x:tuple(x))) for t in triangles1]
|
||||
triang2 = [np.concatenate(sorted(t, key=lambda x:tuple(x))) for t in triangles2]
|
||||
# Sort the resulting 9-element "tuples"
|
||||
triang1 = np.array(sorted([tuple(x) for x in triang1]))
|
||||
triang2 = np.array(sorted([tuple(x) for x in triang2]))
|
||||
return triang1.shape == triang2.shape and np.allclose(triang1, triang2, 0, tol)
|
||||
|
||||
|
||||
def test_both_algs_same_result_donut():
|
||||
# Performing this test on data that does not have ambiguities
|
||||
|
||||
n = 48
|
||||
a, b = 2.5/n, -1.25
|
||||
isovalue = 0.0
|
||||
|
||||
vol = np.empty((n,n,n), 'float32')
|
||||
for iz in range(vol.shape[0]):
|
||||
for iy in range(vol.shape[1]):
|
||||
for ix in range(vol.shape[2]):
|
||||
# Double-torii formula by Thomas Lewiner
|
||||
z, y, x = float(iz)*a+b, float(iy)*a+b, float(ix)*a+b
|
||||
vol[iz,iy,ix] = ( (
|
||||
(8*x)**2 + (8*y-2)**2 + (8*z)**2 + 16 - 1.85*1.85 ) * ( (8*x)**2 +
|
||||
(8*y-2)**2 + (8*z)**2 + 16 - 1.85*1.85 ) - 64 * ( (8*x)**2 + (8*y-2)**2 )
|
||||
) * ( ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 )
|
||||
* ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 ) -
|
||||
64 * ( ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2
|
||||
) ) + 1025
|
||||
|
||||
vertices1, faces1 = marching_cubes_classic(vol, 0)[:2]
|
||||
vertices2, faces2 = marching_cubes_lewiner(vol, 0)[:2]
|
||||
vertices3, faces3 = marching_cubes_lewiner(vol, 0, use_classic=True)[:2]
|
||||
|
||||
# Old and new alg are different
|
||||
assert not _same_mesh(vertices1, faces1, vertices2, faces2)
|
||||
# New classic and new Lewiner are different
|
||||
assert not _same_mesh(vertices2, faces2, vertices3, faces3)
|
||||
# Would have been nice if old and new classic would have been the same
|
||||
# assert _same_mesh(vertices1, faces1, vertices3, faces3, 5)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
np.testing.run_module_suite()
|
||||
|
||||
Reference in New Issue
Block a user