chiark / gitweb /
curveopt: fix handling of empty lines from findcurve
[moebius3.git] / genscad
diff --git a/genscad b/genscad
index 26a21e7720baf6484c2dd29f28d8f951e1fefe23..62fb2ce4758699100f514356406d9fb64fbeaf1c 100755 (executable)
--- a/genscad
+++ b/genscad
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 from __future__ import print_function
 
@@ -6,56 +6,103 @@ import signal
 signal.signal(signal.SIGINT, signal.SIG_DFL)
 
 from moebius import *
+from scad import *
 
-nomsize = 20
-thick = 2.5
+nomsize = 30;
+thick = 2.000;
 
-nv = 40
-nw = 40
+sliceat = 1.675;
+
+nv = 80
+nw = 80
 
 m = Moebius(nv, nw)
 
+relthick = thick/(nomsize*2)
 
-stl_points = []
-stl_point_indices = {}
-stl_triangles = []
-
-def stl_writeout():
-  print('module MoebiusCore(){ scale(%s) polyhedron(points=[' % nomsize)
-  for p in stl_points: print(p, ',')
-  print('],faces=[')
-  for t in stl_triangles: print(repr(t), ',')
-  print('],convexity=10); }')
-
-def stl_point(p):
-  l = list(p)
-  s = repr(l)
-  try:
-    ix = stl_point_indices[s]
-  except KeyError:
-    ix = len(stl_points)
-    stl_points.append(s)
-    stl_point_indices[s] = ix
-  return ix
-
-def stl_triangle(a,b,c):
-  ''' a b c  are clockwise from inside '''
-  stl_triangles.append([ stl_point(p) for p in (a,b,c) ])
-
-def stl_quad(cnrs):
-  ''' cnrs[0] [1] [3] [2] are clockwise from inside '''
-  stl_triangle(cnrs[0], cnrs[1], cnrs[3])
-  stl_triangle(cnrs[0], cnrs[3], cnrs[2])
+def make_moebius(objname):
+  so = ScadObject()
+  for v in range(0, nv):
+    for w in range(0, nw):
+      so.quad([ m.point_offset(v+a, w+b,  relthick)
+                for a in (0, 1)
+                for b in (0, 1) ])
+      so.rquad([ m.point_offset(v+a, w+b, -relthick)
+                 for a in (1, 0)
+                 for b in (1, 0) ])
+    for q, w in ((so.quad, 0), (so.rquad, nw)):
+      q([ m.point_offset(v+a, w,  b*relthick)
+          for a in (0, 1)
+          for b in (-1, +1) ])
+  so.writeout(objname, nomsize)
 
-relthick = thick/(nomsize*2)
+def make_pinlocations():
+  bests = [ None, None ] # bests[ y>=0 ] = (locn, normal)
+
+  def goodness(info):
+    # we find the one with biggest Z (actually, the least -ve)
+    return (
+      0 * np.linalg.norm(info[0][0:2])
+      -abs(info[1][2])
+    )
+    return abs(info[1][1])
+
+  for v in range(0, nv):
+    for w in range(0, nw):
+      core_quad = [ m.point(v+a, w+b)
+                    for a in (1, 0)
+                    for b in (1, 0) ]
+      for p,q in [ (core_quad[i], core_quad[(i+1) % 4])
+                   for i in range(0,4) ]:
+        normal = (m.point_offset(v,  w,   0.5) - core_quad[0] +
+                  m.point_offset(v+1,w+1, 0.5) - core_quad[3]);
+        if normal[2] > 0: # inwards, make outwards
+          normal = -normal
+
+        #print(repr((p,q)), file=sys.stderr)
+        if (p[2] > -sliceat) == (q[2] > -sliceat): continue
 
-for v in range(0, nv):
-  for w in range(0, nw):
-    stl_quad([ m.point_offset(v+a, w+b,  relthick)
-               for a in (0, 1)
-               for b in (0, 1) ])
-    stl_quad([ m.point_offset(v+a, w+b, -relthick)
-               for a in (1, 0)
-               for b in (1, 0) ])
+        lincomb = (-sliceat - p[2]) / (q[2] - p[2])
+        here = p * (1-lincomb) + q * lincomb;
+        best_key = here[1] >= 0
+        prospective = (here,normal)
+        if (bests[best_key] is None or
+            goodness(prospective) > goodness(bests[best_key])):
+          bests[best_key] = prospective
+  def print_best_list(name, l):
+    print('moebius_pin_%s=[' % name)
+    for i in l: print(repr(list(i)),',')
+    print('];')
+  def print_bests(name, info_index):
+    print_best_list(name, [b[info_index] for b in bests])
+  print_bests('locns', 0)
+  print_bests('normals', 1)
+  upwardses = []
+  alongs = []
+  matrices = []
+  for b in bests:
+    along = unit_v(np.cross(b[1], unit_z))
+    upwards = np.cross(b[1], along)
+    matrix = [ along,
+               -upwards,
+               -b[1] ]
+    #print('initial', matrix, file=sys.stderr)
+    matrix = np.concatenate((matrix, [[0,0,0]]))
+    #print('concatd', matrix, file=sys.stderr)
+    matrix = np.array(matrix).T
+    #print('transposed', matrix, file=sys.stderr)
+    matrix = np.concatenate((matrix, [[0,0,0,1]]))
+    #print('concat2', matrix, file=sys.stderr)
+    matrix = [ list(row) for row in matrix ]
+    #print('listed', matrix, file=sys.stderr)
+    alongs   .append(along)
+    upwardses.append(upwards)
+    matrices. append(matrix)
+  print_best_list('upwardses',upwardses)
+  print_best_list('alongs',   alongs)
+  print_best_list('matrix',   matrices)
 
-stl_writeout()
+make_moebius('MoebiusCore')
+make_pinlocations()
+print('moebiuscore_nomsize=%s;' % repr(nomsize))
+print('moebiuscore_sliceat=%s;' % repr(sliceat))