Skip to content

Commit 763ec84

Browse files
committed
rewrite manyfold analysis to use assimp scene
1 parent 7b63b40 commit 763ec84

File tree

1 file changed

+13
-29
lines changed

1 file changed

+13
-29
lines changed

app/jobs/analysis/geometric_analysis_job.rb

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ class Analysis::GeometricAnalysisJob < ApplicationJob
99
def perform(file_id)
1010
# Get model
1111
file = ModelFile.find(file_id)
12-
return unless self.class.loader(file)
12+
return unless file.loadable?
1313
if SiteSettings.analyse_manifold
1414
status[:step] = "jobs.analysis.geometric_analysis.loading_mesh" # i18n-tasks-use t('jobs.analysis.geometric_analysis.loading_mesh')
1515
# Get mesh
16-
mesh = self.class.load_mesh(file)
17-
if mesh
16+
scene = file.scene
17+
if scene
1818
status[:step] = "jobs.analysis.geometric_analysis.manifold_check" # i18n-tasks-use t('jobs.analysis.geometric_analysis.manifold_check')
19-
# Check for manifold mesh
20-
manifold = manifold?(mesh)
19+
# Check that all meshes are manifold
20+
manifold = scene.meshes.map { manifold?(it) }.all?
2121
Problem.create_or_clear(
2222
file,
2323
:non_manifold,
@@ -40,46 +40,30 @@ def perform(file_id)
4040
end
4141
end
4242

43-
def self.loader(file)
44-
case file.extension.downcase
45-
when "stl"
46-
Mittsu::STLLoader
47-
when "obj"
48-
Mittsu::OBJLoader
49-
end
50-
end
51-
52-
def self.load_mesh(file)
53-
# TODO: This can be better, but needs changes upstream in Mittsu to allow loaders to parse from an IO object
54-
loader(file)&.new&.parse(file.attachment.read)
55-
end
56-
5743
private
5844

5945
def manifold?(mesh)
6046
# Shortcut if there is nothing here
61-
return true if mesh.geometry.nil? && mesh.children.empty?
62-
# Recurse children to see if they are manifold
63-
children_are_manifold = mesh.children.map { |x| manifold?(x) }.all?
47+
return true if mesh.num_faces == 0
6448
# Detect manifold geometry in this object
6549
edges = {}
6650
# For each face, record its edges in the edge hash
67-
mesh.geometry&.faces&.each do |face|
68-
update_edge_hash face.a, face.b, edges
69-
update_edge_hash face.b, face.c, edges
70-
update_edge_hash face.c, face.a, edges
51+
mesh.faces.each do |face|
52+
update_edge_hash face.indices[0], face.indices[1], edges
53+
update_edge_hash face.indices[1], face.indices[2], edges
54+
update_edge_hash face.indices[2], face.indices[0], edges
7155
end
7256
# If there's anything left in the edge hash, then either
7357
# we have holes, or we have badly oriented faces
74-
edges.empty? && children_are_manifold
58+
edges.empty?
7559
end
7660

7761
# Updates edge hash with the passed vertex indexes
7862
# First, the reverse edge is searched for in the hash
7963
# If found, it's removed as we've got a match
8064
# If not, we record this edge in the hash
8165
def update_edge_hash(v1, v2, edges)
82-
return if edges.delete "#{v2}->#{v1}"
83-
edges["#{v1}->#{v2}"] = true
66+
return if edges.delete [v2, v1].pack("QQ")
67+
edges[[v1, v2].pack("QQ")] = true
8468
end
8569
end

0 commit comments

Comments
 (0)