mirror of https://github.com/vitalif/openscad
#1215 Added tests, check for weak manifoldness when running tests
parent
8dd0102d4e
commit
09b3ab45d4
|
@ -0,0 +1,10 @@
|
|||
difference() {
|
||||
rotate([90,0,90])
|
||||
linear_extrude(height=10)
|
||||
polygon(points=[[-4,0],[0,0],[0,3],[-3.5,3],[-4,2]]);
|
||||
|
||||
rotate([90,0,0])
|
||||
linear_extrude(height=4)
|
||||
polygon(points=[[0,3],[0.5,3],[0,2]]);
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
module dieShape(out) {
|
||||
rotate([-90,90,0]) cylinder(r=10,h=15+out, $fn=4);
|
||||
rotate([0,-90,0]) cylinder(r=10,h=15+out, $fn=4);
|
||||
rotate([0,0,0]) cylinder(r=10,h=15+out, $fn=4);
|
||||
}
|
||||
|
||||
hull() dieShape(0);
|
||||
dieShape(.5);
|
|
@ -1239,7 +1239,9 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue13.scad
|
|||
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1105.scad
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1105b.scad
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1105c.scad
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1105d.scad)
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1105d.scad
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1215.scad
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1215b.scad)
|
||||
list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES})
|
||||
list(REMOVE_ITEM EXPORT3D_TEST_FILES
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
# Authors: Torsten Paul, Don Bright, Marius Kintel
|
||||
|
||||
import sys, os, re, subprocess, argparse
|
||||
from validatestl import validateSTL
|
||||
|
||||
def failquit(*args):
|
||||
if len(args)!=0: print(args)
|
||||
|
@ -90,6 +91,10 @@ result = subprocess.call(export_cmd)
|
|||
if result != 0:
|
||||
failquit('OpenSCAD #1 failed with return code ' + str(result))
|
||||
|
||||
if args.format == 'stl':
|
||||
if not validateSTL(exportfile):
|
||||
failquit("Error: Non-manifold STL file exported from OpenSCAD")
|
||||
|
||||
|
||||
#
|
||||
# Second run: Import the exported file and render as png
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.8 KiB |
|
@ -0,0 +1,96 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# Simple tool to validate if an STL has non-manifold (dangling) edges.
|
||||
#
|
||||
# Usage: validatestl.py <file.stl>
|
||||
#
|
||||
# Based on code by Jan Squirrel Koniarik from:
|
||||
# https://github.com/SquirrelCZE/pycad/
|
||||
#
|
||||
# Author: Marius Kintel <marius@kintel.net>
|
||||
# Licence: GPL V2
|
||||
#
|
||||
|
||||
import sys
|
||||
import io
|
||||
import hashlib
|
||||
import os
|
||||
import subprocess
|
||||
from collections import Counter
|
||||
|
||||
def read_stl(filename):
|
||||
triangles = list()
|
||||
with open(filename, "r") as fd:
|
||||
triangle = {
|
||||
"facet": [0, 0, 0],
|
||||
"points": list()
|
||||
}
|
||||
for line in fd:
|
||||
line = line.strip()
|
||||
if line.startswith('solid'):
|
||||
continue
|
||||
elif line.startswith('endsolid'):
|
||||
continue
|
||||
elif line.startswith('outer'):
|
||||
continue
|
||||
elif line.startswith('facet'):
|
||||
parts = line.split(' ')
|
||||
for i in range(2, 5):
|
||||
triangle['facet'][i-2] = float(parts[i])
|
||||
continue
|
||||
elif line.startswith('vertex'):
|
||||
parts = line.split(' ')
|
||||
point = [0, 0, 0]
|
||||
for i in range(1, 4):
|
||||
point[i-1] = float(parts[i])
|
||||
triangle['points'].append(point)
|
||||
continue
|
||||
elif line.startswith('endloop'):
|
||||
continue
|
||||
elif line.startswith('endfacet'):
|
||||
triangles.append(triangle)
|
||||
triangle = {
|
||||
"facet": [0, 0, 0],
|
||||
"points": list()
|
||||
}
|
||||
continue
|
||||
|
||||
return Mesh(
|
||||
triangles=triangles
|
||||
)
|
||||
|
||||
class Mesh():
|
||||
def __init__(self, triangles):
|
||||
points = list()
|
||||
p_triangles = list()
|
||||
for triangle in triangles:
|
||||
p_triangle = list()
|
||||
for point in triangle['points']:
|
||||
if point not in points:
|
||||
points.append(point)
|
||||
p_triangle.append(
|
||||
points.index(point)
|
||||
)
|
||||
p_triangles.append(p_triangle)
|
||||
self.points = points
|
||||
self.triangles = p_triangles
|
||||
|
||||
|
||||
def validateSTL(filename):
|
||||
mesh = read_stl(filename);
|
||||
edges = Counter((t[i], t[(i+1)%3]) for i in range(0,3) for t in mesh.triangles)
|
||||
reverse_edges = Counter((t[(i+1)%3], t[i]) for i in range(0,3) for t in mesh.triangles)
|
||||
edges.subtract(reverse_edges)
|
||||
edges += Counter() # remove zero and negative counts
|
||||
if len(edges) > 0:
|
||||
print "Non-manifold STL: " + str(edges)
|
||||
return False
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
retval = validateSTL(sys.argv[1])
|
||||
if retval:
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(1)
|
Loading…
Reference in New Issue