Cleanup to OpenSCAD code. Add sorting to makefile. Use new linter for Openscad to clean up a lot of magic numbers.

This commit is contained in:
Matt McWilliams 2024-11-11 22:43:45 -05:00
parent f061e0d180
commit 5727d171a6
29 changed files with 590346 additions and 519507 deletions

View File

@ -2,9 +2,10 @@
PREFIX=intval2
OPENSCAD=openscad
OPENSCAD_OPTIONS_STL=--enable sort-stl -D VERBOSE=false
OPENSCAD_OPTIONS_STL=--enable manifold -D VERBOSE=false
OPENSCAD_OPTIONS_DXF=-D VERBOSE=false
ORDER_STL=python3 ./c14n_stl.py
STL=../stl
DXF=../dxf
MODELS=$(shell cat models.txt | tr '\n' ' ')
@ -27,6 +28,7 @@ cleanall:
$(MODELS) : $(STL)/$(PREFIX)_%.stl : $(PREFIX).scad
$(OPENSCAD) $(OPENSCAD_OPTIONS_STL) -o $@ -D PART=\"$(subst $(PREFIX)_,,$(subst .stl,,$(@F)))\" $<
$(ORDER_STL) $@
$(LASER) : $(DXF)/$(PREFIX)_%.dxf : $(PREFIX).scad
$(OPENSCAD) $(OPENSCAD_OPTIONS_DXF) -o $@ -D PART=\"$(subst $(PREFIX)_,,$(subst .dxf,,$(@F)))\" $<

117
scad/c14n_stl.py Normal file
View File

@ -0,0 +1,117 @@
#!/usr/bin/env python
#
# NopSCADlib Copyright Chris Palmer 2018
# nop.head@gmail.com
# hydraraptor.blogspot.com
#
# This file is part of NopSCADlib.
#
# NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
# GNU General Public License as published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with NopSCADlib.
# If not, see <https://www.gnu.org/licenses/>.
#
#
#! OpenSCAD produces randomly ordered STL files. This script re-orders them consistently so that GIT can tell if they have changed or not.
#
# OpenSCAD produces randomly ordered STL files so source control like GIT can't tell if they have changed or not.
# This scrip orders each triangle to start with the lowest vertex first (comparing x, then y, then z)
# It then sorts the triangles to start with the one with the lowest vertices first (comparing first vertex, second, then third)
# This has no effect on the model but makes the STL consistent. I.e. it makes a canonical form.
#
from __future__ import print_function
import sys
def cmz(x):
''' Convert "-0" to "0". '''
return '0' if x == '-0' else x
class Vertex:
def __init__(self, x, y, z):
self.x, self.y, self.z = x, y, z
self.key = (float(x), float(y), float(z))
class Normal:
def __init__(self, dx, dy, dz):
self.dx, self.dy, self.dz = dx, dy, dz
class Facet:
def __init__(self, normal, v1, v2, v3):
self.normal = normal
if v1.key < v2.key:
if v1.key < v3.key:
self.vertices = (v1, v2, v3) #v1 is the smallest
else:
self.vertices = (v3, v1, v2) #v3 is the smallest
else:
if v2.key < v3.key:
self.vertices = (v2, v3, v1) #v2 is the smallest
else:
self.vertices = (v3, v1, v2) #v3 is the smallest
def key(self):
return (self.vertices[0].x, self.vertices[0].y, self.vertices[0].z,
self.vertices[1].x, self.vertices[1].y, self.vertices[1].z,
self.vertices[2].x, self.vertices[2].y, self.vertices[2].z)
class STL:
def __init__(self, fname):
self.facets = []
with open(fname) as f:
words = [cmz(s.strip()) for s in f.read().split()]
if words[0] == 'solid' and words[1] == 'OpenSCAD_Model':
i = 2
while words[i] == 'facet':
norm = Normal(words[i + 2], words[i + 3], words[i + 4])
v1 = Vertex(words[i + 8], words[i + 9], words[i + 10])
v2 = Vertex(words[i + 12], words[i + 13], words[i + 14])
v3 = Vertex(words[i + 16], words[i + 17], words[i + 18])
i += 21
self.facets.append(Facet(norm, v1, v2, v3))
self.facets.sort(key = Facet.key)
else:
print("Not an OpenSCAD ascii STL file")
sys.exit(1)
def write(self, fname):
mins = [float('inf'), float('inf'), float('inf')]
maxs = [float('-inf'), float('-inf'), float('-inf')]
with open(fname,"wt") as f:
print('solid OpenSCAD_Model', file=f)
for facet in self.facets:
print(' facet normal %s %s %s' % (facet.normal.dx, facet.normal.dy, facet.normal.dz), file=f)
print(' outer loop', file=f)
for vertex in facet.vertices:
print(' vertex %s %s %s' % (vertex.x, vertex.y, vertex.z), file=f)
for i in range(3):
ordinate = vertex.key[i]
if ordinate > maxs[i]: maxs[i] = ordinate
if ordinate < mins[i]: mins[i] = ordinate
print(' endloop', file=f)
print(' endfacet', file=f)
print('endsolid OpenSCAD_Model', file=f)
return mins, maxs
def canonicalise(fname):
stl = STL(fname)
return stl.write(fname)
if __name__ == '__main__':
if len(sys.argv) == 2:
canonicalise(sys.argv[1])
else:
print("\nusage:\n\t c14n_stl file - Canonicalise an STL file created by OpenSCAD.")
sys.exit(1)

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,19 @@
//!OpenSCAD
/* preprocessor */
IN = 25.4;
MM = 1;
function R (diameter) = diameter / 2.0;
function IN2MM(in) = in * IN;
function MM2IN(mm) = mm / IN;
module hex (diag = 10, h = 1) {
cylinder(r = diag / 2, h = h, center = true, $fn = 6);
}
module tube(o = 1, i = 0, h = 1, center = false, $fn = 12) {
$fn = $fn;
union () {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff