Skip to content

Commit

Permalink
Print errors to console when hole filling fails (#55)
Browse files Browse the repository at this point in the history
* Print errors to console when hole filling fails

Fixes #39 

Signed-off-by: Christopher T. Lee <[email protected]>

* Update google-test repo

Signed-off-by: Christopher T. Lee <[email protected]>

* feat: Bump metadata to support Blender 3.3 LTS

Signed-off-by: Christopher T. Lee <[email protected]>

* refactor: Add offender info to runtime errors

Signed-off-by: Christopher T. Lee <[email protected]>

* refactor(blendgamer): Update blendgamer cmap

Aiming for blender3.3LTS and mpl 3.6.2

Signed-off-by: Christopher T. Lee <[email protected]>

* feat(blendgamer): Deviatoric curvature

Signed-off-by: Christopher T. Lee <[email protected]>

* chore: bump support blender to 3.6 LTS

Fixes #56 

Signed-off-by: Christopher T. Lee <[email protected]>

* chore: Stop support for Blender 2.79b

Signed-off-by: Christopher T. Lee <[email protected]>

---------

Signed-off-by: Christopher T. Lee <[email protected]>
  • Loading branch information
ctlee authored Nov 13, 2023
1 parent 842fce5 commit e3ccc6d
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 110 deletions.
7 changes: 5 additions & 2 deletions .github/scripts/blender_pyversion_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
import sys

bver_to_pyver = {
"2.79": '3.5',
# "2.79": '3.5',
"2.83": '3.7',
"2.93": '3.9'
"2.93": '3.9',
"3.3": "3.10",
"3.6": "3.10",

}

if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
blender: [2.79, 2.83, 2.93]
blender: [2.83, 2.93, 3.3, 3.6]
runs-on: ${{ matrix.os }}
defaults:
run:
Expand Down
4 changes: 2 additions & 2 deletions cmake/blenderexec.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ f = open('@CMAKE_CURRENT_BINARY_DIR@/found_blender_info', 'w')
f.write('{}\n'.format(str(bpy.app.version[0]) + '.' + str(bpy.app.version[1]) + '.' + str(bpy.app.version[2])))
f.write('{}\n'.format(bpy.utils.script_path_user()))
f.write('{}\n'.format('.'.join(str(v) for v in sys.version_info[0:3])));
f.write('{}\n'.format(bpy.app.binary_path_python))
f.write('{}\n'.format(sys.executable))
f.write('{}\n'.format(struct.calcsize('@P')))
f.close()
f.close()
3 changes: 2 additions & 1 deletion include/gamer/gamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ void throw_runtime_error(const char *function, const char *file, const int line,
T &&...ts) {
std::stringstream ss;
ss << "Error: ";
int dummy[] = {0, ((ss << std::forward<T>(ts)), 0)...};
// https://stackoverflow.com/questions/25680461/variadic-template-pack-expansion/25683817#25683817
int dummy[] = {0, ((ss << std::forward<T>(ts) << " "), 0)...};
static_cast<void>(dummy); // Avoid warning for unused variable
ss << " in function " << function << " at " << file << ":" << line;
throw std::runtime_error(ss.str());
Expand Down
48 changes: 34 additions & 14 deletions src/SurfaceMeshDetail.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,14 @@ void decimateVertex(SurfaceMesh &mesh, SurfaceMesh::SimplexID<1> vertexID,
}
// The ring isn't really a ring
if (!success) {
gamer_runtime_error(
"ERROR(coarse): Hole ring is not closed. "
"Please contact the developers with this error.");
std::stringstream ss;
ss << "Offending vertices:";
for (auto item : boundary) {
ss << item << ", ";
}
gamer_runtime_error("ERROR(coarse): Hole ring is not closed. "
"Please contact the developers with this error.",
ss.str());
}
}

Expand Down Expand Up @@ -237,8 +242,14 @@ void triangulateHole(SurfaceMesh &mesh,
mesh, std::move(keys), backupVerts.begin(), backupVerts.end());

if (!computeLocalOrientation(mesh, holeEdges)) {
gamer_runtime_error(
"ERROR(triangulateHole): Mesh became non-orientable");

std::stringstream ss;
ss << "Offending edges:";
for (auto item : holeEdges) {
ss << item << ", ";
}
gamer_runtime_error("ERROR(triangulateHole): Mesh became non-orientable.",
ss.str());
}
}

Expand Down Expand Up @@ -354,9 +365,11 @@ void weightedVertexSmooth(SurfaceMesh &mesh, SurfaceMesh::SimplexID<1> vertexID,
nS = next - shared;
normalize(nS);
} catch (std::exception &e) {
gamer_runtime_error(
"ERROR: Zero length edge found. "
"weightedVertexSmooth expects no zero length edges.");
std::stringstream ss;
ss << "Offending edge: " << edge;
gamer_runtime_error("ERROR: Zero length edge found. "
"weightedVertexSmooth expects no zero length edges.",
ss.str());
}

// Bisector of the 'rhombus'
Expand Down Expand Up @@ -472,9 +485,11 @@ Vector weightedVertexSmoothCache(SurfaceMesh &mesh,
nS = next - shared;
normalize(nS);
} catch (std::exception &e) {
gamer_runtime_error(
"ERROR: Zero length edge found. "
"weightedVertexSmooth expects no zero length edges.");
std::stringstream ss;
ss << "Offending edge: " << edge;
gamer_runtime_error("ERROR: Zero length edge found."
"weightedVertexSmooth expects no zero length edges.",
ss.str());
}

// Bisector of the 'rhombus'
Expand Down Expand Up @@ -558,7 +573,7 @@ void normalSmoothH(SurfaceMesh &mesh, SurfaceMesh::SimplexID<1> vertexID,

auto p = (*vertexID).position;
Eigen::Vector4d pos_e{p[0], p[1], p[2], 1}; // 4D for affine3D
Eigen::Vector4d newPos_e{0,0,0,0};
Eigen::Vector4d newPos_e{0, 0, 0, 0};

// For each incident face get the average normal
auto incidentFaces = mesh.up(mesh.up(vertexID));
Expand Down Expand Up @@ -892,7 +907,12 @@ void findHoles(const SurfaceMesh &mesh,
// mesh.down(firstEdge, std::back_inserter(visitedVerts));
// Try to complete the ring
if (!orderBoundaryEdgeRing(mesh, bdryEdges, visitedVerts, bdryRing)) {
gamer_runtime_error("Couldn't connect ring");
std::stringstream ss;
ss << "Participating edges: ";
for (auto item : bdryEdges) {
ss << item << ", ";
}
gamer_runtime_error("Couldn't connect ring", ss.str());
}
holeList.push_back(bdryRing);
}
Expand Down Expand Up @@ -1023,7 +1043,7 @@ bool checkEdgeFlip(
// faces. "
// << "Returning..." << std::endl;
gamer_runtime_error("SurfaceMesh is not pseudomanifold. Found an edge "
"connected to more than 2 faces.");
"connected to more than 2 faces.");
} else if (up.size() < 2) // Edge is a boundary
{
// std::cerr << "This edge participates in fewer than 2
Expand Down
11 changes: 6 additions & 5 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ else()
endif()

FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG origin/master
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG origin/main
GIT_SHALLOW TRUE
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
)

# Prevent overriding the parent project's compiler/linker
Expand Down
2 changes: 1 addition & 1 deletion tools/blendgamer/__init__.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ bl_info = {
"description": "Utilities for generating finite elements simulation compatible meshes",
"author": "Christopher T. Lee, Justin Laughlin, John B. Moody, Zeyun Yu, Tom Bartol, Johan Hake, and Michael Holst",
"version": (@PROJECT_VERSION_MAJOR@, @PROJECT_VERSION_MINOR@, @PROJECT_VERSION_PATCH@),
"blender": (2, 93, 0),
"blender": (3, 6, 0),
"location": "3D View > Tool Shelf",
"wiki_url": "https://github.com/ctlee/gamer",
"tracker_url": "https://github.com/ctlee/gamer/issues",
Expand Down
98 changes: 15 additions & 83 deletions tools/blendgamer/src/colormap.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,76 +39,6 @@
}


class DivergingNorm(mpl.colors.Normalize):
def __init__(self, vcenter, vmin=None, vmax=None):
"""
Normalize data with a set center.
Useful when mapping data with an unequal rates of change around a
conceptual center, e.g., data that range from -2 to 4, with 0 as
the midpoint.
Parameters
----------
vcenter : float
The data value that defines ``0.5`` in the normalization.
vmin : float, optional
The data value that defines ``0.0`` in the normalization.
Defaults to the min value of the dataset.
vmax : float, optional
The data value that defines ``1.0`` in the normalization.
Defaults to the the max value of the dataset.
Examples
--------
This maps data value -4000 to 0., 0 to 0.5, and +10000 to 1.0; data
between is linearly interpolated::
>>> import matplotlib.colors as mcolors
>>> offset = mcolors.DivergingNorm(vmin=-4000.,
vcenter=0., vmax=10000)
>>> data = [-4000., -2000., 0., 2500., 5000., 7500., 10000.]
>>> offset(data)
array([0., 0.25, 0.5, 0.625, 0.75, 0.875, 1.0])
"""

self.vcenter = vcenter
self.vmin = vmin
self.vmax = vmax
if not (vcenter and vmin and vmax) and (vcenter >= vmax or vcenter <= vmin):
raise ValueError(
"vmin(%f), vcenter(%f), and vmax(%f) must be in "
"ascending order" % (vmin, vcenter, vmax)
)

def autoscale_None(self, A):
"""
Get vmin and vmax, and then clip at vcenter
"""
super().autoscale_None(A)
if self.vmin > self.vcenter:
self.vmin = self.vcenter
if self.vmax < self.vcenter:
self.vmax = self.vcenter

def __call__(self, value, clip=False):
"""
Map value to the interval [0, 1].
"""
result, is_scalar = self.process_value(value)
self.autoscale_None(result) # sets self.vmin, self.vmax if None

if not self.vmin <= self.vcenter <= self.vmax:
raise ValueError("vmin, vcenter, vmax must increase monotonically")
result = np.ma.masked_array(
np.interp(result, [self.vmin, self.vcenter, self.vmax], [0, 0.5, 1.0]),
mask=np.ma.getmask(result),
)
if is_scalar:
result = np.atleast_1d(result)[0]
return result


def curveToData(crv, context):
"""
Helper function to take a curvature object and return smoothed data.
Expand Down Expand Up @@ -241,17 +171,14 @@ def dataToVertexColor(crv, context, showplot=False, saveplot=False):

amin = np.amin(data)
amax = np.amax(data)

# if amin > tmin:
# amin = tmin
# if amax < tmax:
# amax = tmax

# Construct the norm and colorbar
if amin < 0 and amax > 0:
norm = DivergingNorm(vmin=amin, vcenter=0, vmax=amax)
# Python 3.5 matplotlib may not support?
# norm = mpl.colors.DivergingNorm(vmin=amin, vcenter=0, vmax=amax)
norm = mpl.colors.TwoSlopeNorm(0, vmin=amin, vmax=amax)
colors_neg = cmap(np.linspace(0, crv.mixpoint, 256))
colors_pos = cmap(np.linspace(crv.mixpoint, 1, 256))

Expand All @@ -271,13 +198,15 @@ def dataToVertexColor(crv, context, showplot=False, saveplot=False):
colors = colors[:, :3]

mesh = bpy.context.object.data
vlayer = "%s%s" % (crv.algorithm, crv.curvatureType)
vlayer = "%s%s_color" % (crv.algorithm, crv.curvatureType)


if vlayer not in mesh.vertex_colors:
if len(mesh.vertex_colors) == 8:
raise RuntimeError(
"Maximum of 8 vertex Layers reached cannot create a new layer. Please delete a layer to continue."
)
if bpy.app.version < (3, 3, 0):
if len(mesh.vertex_colors) == 8:
raise RuntimeError(
"Maximum of 8 vertex Layers reached cannot create a new layer. Please delete a layer to continue."
)
mesh.vertex_colors.new(name=vlayer)

color_layer = mesh.vertex_colors[vlayer]
Expand All @@ -289,13 +218,18 @@ def dataToVertexColor(crv, context, showplot=False, saveplot=False):

# Add axis for colorbar and plot it
ax = fig.add_axes([0.75, 0.05, 0.05, 0.9])
cb = mpl.colorbar.ColorbarBase(
cb = mpl.colorbar.Colorbar(
ax, cmap=curvature_map, norm=norm, orientation="vertical"
)

ticks = cb.get_ticks()
ticks.sort()

if ticks[0] < amin:
ticks = ticks[1:-1]
if ticks[-1] > amax:
ticks = ticks[0:-2]

if amin != ticks[0]:
ticks = np.insert(ticks, 0, amin)
if amax != ticks[-1]:
Expand Down Expand Up @@ -399,9 +333,7 @@ def differencePlotter(context, difftype="K1"):

# Construct the norm and colorbar
if amin < 0 and amax > 0:
norm = DivergingNorm(vmin=amin, vcenter=0, vmax=amax)
# Python 3.5 matplotlib may not support?
# norm = mpl.colors.DivergingNorm(vmin=amin, vcenter=0, vmax=amax)
norm = mpl.colors.TwoSlopeNorm(0, vmin=amin, vmax=amax)
colors_neg = cmap(np.linspace(0, 0.5, 256))
colors_pos = cmap(np.linspace(0.5, 1, 256))

Expand Down
9 changes: 8 additions & 1 deletion tools/blendgamer/src/curvatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
("K2", "k2", "Second principle curvature"),
("KG", "kg", "Gaussian curvature"),
("KH", "kh", "Mean curvature"),
("D", "d", "Deviatoric curvature")
]

curvatureCalcEnums = [
Expand Down Expand Up @@ -175,6 +176,11 @@ def execute(self, context):
ml[i].value = kh[i]
curvatures.add_curvature(context, "KH")

ml = getCurvatureLayer(obj, algorithm, "D")
for i in range(0, len(k1)):
ml[i].value = (k1[i]-k2[i]) / 2
curvatures.add_curvature(context, "D")

# Explicitly free curvature arrays
del kh
del kg
Expand Down Expand Up @@ -276,7 +282,8 @@ def remove_curvature(self, context):
with BMeshContext(obj) as bm:
name = "%s%s" % (crv.algorithm, crv.curvatureType)
layer = bm.verts.layers.float.get(name)
bm.verts.layers.float.remove(layer)
if layer:
bm.verts.layers.float.remove(layer)

self.curvature_list.remove(self.active_index)
self.active_index -= 1
Expand Down

0 comments on commit e3ccc6d

Please sign in to comment.