Skip to content

Commit

Permalink
debug exception checks for degenerate outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
Floppy committed Dec 6, 2024
1 parent 3f0afb5 commit 216914e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
7 changes: 7 additions & 0 deletions lib/mittsu/mesh_analysis/winged_edge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ def other_vertex(index)
end

def reattach_vertex!(from:, to:)
was = self.clone
if @start == from
@start = to
elsif @finish == from
@finish = to
end
raise ArgumentError.new("was #{was.inspect}, now: #{inspect}") if degenerate?
end

def reattach_edge!(from:, to:)
Expand All @@ -49,6 +51,7 @@ def reattach_edge!(from:, to:)
elsif @ccw_right == from
@ccw_right = to
end
raise ArgumentError.new(self.inspect) if degenerate?
end

def coincident_at(edge)
Expand Down Expand Up @@ -107,16 +110,20 @@ def stitch!(edge)
return nil unless face && edge.coincident_at(edge)
# Flip incoming edge if it's not pointing the same way
edge = edge.flip unless same_direction?(edge)
raise ArgumentError if edge.degenerate? || degenerate? || !same_direction?(edge)
# Stitch left side of other edge if our left face is the shared one, or vice versa
puts face
if face == @left
@cw_left = edge.cw_left
@ccw_left = edge.ccw_left
@left = edge.left
raise ArgumentError.new(self.inspect) if degenerate?
return @left
else
@cw_right = edge.cw_right
@ccw_right = edge.ccw_right
@right = edge.right
raise ArgumentError.new(self.inspect) if degenerate?
return @right
end
end
Expand Down
25 changes: 24 additions & 1 deletion lib/mittsu/mesh_analysis/winged_edge_geometry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def flatten!
next if face.nil?
e0 = edge(face[:edge])
next if e0.nil?
puts "error accessing edge #{face[:edge]} for face #{face[:face]}" if e0.nil?
if e0.left == face[:face]
Mittsu::Face3.new(e0.start, e0.finish, edge(e0.ccw_left)&.other_vertex(e0.finish)) if e0.start && e0.finish && edge(e0.ccw_left)&.other_vertex(e0.finish)
elsif e0.right == face[:face]
Expand All @@ -76,6 +77,7 @@ def between(v1, v2)
end

def indexes_between(v1, v2)
puts "between #{v1} and #{v2}"
find_edge_indexes(from: v1, to: v2) + find_edge_indexes(from: v2, to: v1)
end

Expand All @@ -86,7 +88,18 @@ def edge(index)
def manifold?
@edges.all? do |e|
return true if e.nil?
e.complete? &&
raise "edge #{e.index} is incomplete" unless e.complete?
raise "edge #{e.index} is degenerate" if e.degenerate?
raise "edge #{e.index} is duplicated" if indexes_between(e.start, e.finish).count > 1
raise "edge #{e.index} references missing start vertex #{e.start}" if @vertices[e.start].nil?
raise "edge #{e.index} references missing finish vertex #{e.finish}" if @vertices[e.finish].nil?
raise "edge #{e.index} references missing left face #{e.left}" if @face_indices[e.left].nil?
raise "edge #{e.index} references missing right face #{e.right}" if @face_indices[e.right].nil?
raise "edge #{e.index} references missing cw left edge #{e.cw_left}" if @edges[e.cw_left].nil?
raise "edge #{e.index} references missing ccw left edge #{e.ccw_left}" if @edges[e.ccw_left].nil?
raise "edge #{e.index} references missing cw right edge #{e.cw_right}" if @edges[e.cw_right].nil?
raise "edge #{e.index} references missing ccw right edge #{e.ccw_right}" if @edges[e.ccw_right].nil?
ok = e.complete? &&
!e.degenerate? &&
indexes_between(e.start, e.finish).count <= 1 &&
!@vertices[e.start].nil? &&
Expand All @@ -97,6 +110,8 @@ def manifold?
!@edges[e.ccw_left].nil? &&
!@edges[e.cw_right].nil? &&
!@edges[e.ccw_right].nil?
puts " -- #{e.inspect}" unless ok
ok
end
end

Expand All @@ -116,8 +131,10 @@ def split(vertex:, left:, right:, displacement:, flatten: true)
# and merging everything onto the start vertex instead.
# If the result would be degenerate in some way, the mesh is unchanged
def collapse(index, flatten: true)
puts "collapsing edge #{index}"
# find the edge
e0 = edge(index)
puts e0.inspect
return if e0.nil?

# Move vertices to new position
Expand All @@ -135,6 +152,7 @@ def collapse(index, flatten: true)
ccw_left = @edges[e0.ccw_left]
if cw_left && ccw_left
face = cw_left.stitch!(ccw_left)
raise ArgumentError.new("tried to stitch #{ccw_left.inspect} into #{cwl.inspect} and got #{cw_left.inspect}") if cw_left.degenerate?
@edges[cw_left.index] = cw_left
@face_indices[face] = {face: face, edge: cw_left.index} if face
end
Expand All @@ -144,6 +162,7 @@ def collapse(index, flatten: true)
ccw_right = ccwr = @edges[e0.ccw_right]
if cw_right && ccw_right
face = ccw_right.stitch!(cw_right)
raise ArgumentError.new("tried to stitch #{cw_right.inspect} into #{ccwr.inspect} and got #{ccw_right.inspect}") if ccw_right.degenerate?
@edges[ccw_right.index] = ccw_right
@face_indices[face] = {face: face, edge: ccw_right.index} if face
end
Expand All @@ -158,6 +177,9 @@ def collapse(index, flatten: true)

# Reattach edges to remove old indexes
# This could be much more efficient by walking round the wings
puts "reattaching: left #{ccw_left&.index} -> #{cw_left&.index}"
puts "reattaching: right #{cw_right&.index} -> #{ccw_right&.index}"
puts "reattaching: finish #{e0.finish} -> #{e0.start}"
@face_indices.each do |f|
next if f.nil?
f[:edge] = cw_left&.index if f[:edge] == ccw_left&.index
Expand All @@ -171,6 +193,7 @@ def collapse(index, flatten: true)
end

# Prepare for rendering
raise "SHIT" unless manifold?
flatten! if flatten
# Return split parameters required to invert operation
# [vertex, left_vertex, right_vertex, displacement]
Expand Down

0 comments on commit 216914e

Please sign in to comment.