chiark / gitweb /
fix python incompatibilities
[moebius3.git] / curveopt.py
index a0e44cbf1313eac4f16dd0a3060f7253ddea6c36..234b2750417512bf3c0821b3523f2dd39d2ed5e3 100644 (file)
@@ -4,70 +4,100 @@ from __future__ import print_function
 import numpy as np
 from numpy import cos, sin
 
+import six
 import sys
 import subprocess
+import math
 
 from moedebug import *
 from moenp import *
 from moebez import *
+from schequeue import ScheduledTask
 
 from math import atan2, atan, sqrt
 
 import symbolic
 
-findcurve_subprocs = { }
-
 class OptimisedCurve():
-  def __init__(hc, cp, nt):
-    db = DiscreteBezier(cp, nt, constructor=BezierSegment)
-    fc_input = map(db.point_at_it, range(0, nt+1))
+  counter = 0
+
+  def _dbg(oc, s):
+    dbg('%s %s' % (oc._desc, s))
+
+  def __init__(oc, cp, nt):
+    oc._desc = 'OC#%04d' % OptimisedCurve.counter
+    OptimisedCurve.counter += 1
+
+    oc._dbg('cp= ' + ' '.join(map(vec2dbg, cp)))
+
+    db = DiscreteBezier(cp, nt, bezier_constructor=BezierSegment)
+
+    fc_input = [ x for x in map(db.point_at_it, range(0, nt+1)) ]
+    oc._dbg(repr(fc_input))
+
     for end in (False,True):
-      ei = end ? nt : 0
-      fi = end ? nt-1 : 1
-      cp0i = end ? 0 : 3
-      cp1i = end ? 1 : 2
-      e = cp[cp0i]
-      ef_dirn =unit_v(cp[cp1i] - cp[cp0i])
-      ef_len = np.linalg.norm(fc_input[fi] - fc_input[ei])
+      ei = nt if end else 0
+      fi = nt-1 if end else 1
+      cp0i = 3 if end else 0
+      cp1i = 2 if end else 1
+      e = np.array(cp[cp0i])
+      ef_dirn = unit_v(cp[cp1i] - cp[cp0i])
+      ef_len = np.linalg.norm(np.array(fc_input[fi]) - np.array(fc_input[ei]))
       f = e + ef_dirn * ef_len
+      oc._dbg(repr((end, e,f, ef_dirn, ef_len)))
       fc_input[ei] = e
       fc_input[fi] = f
 
-    findcurve_epsilon = dist_pq_plane * 0.01
+    oc._dbg(repr(fc_input))
+
+    findcurve_epsilon = 0.01
+
+    oc.sched = ScheduledTask(oc._await_subproc, oc._desc)
+    oc.sched.pre_spawn()
+
+    cl = ['./findcurve', '%d' % (nt+1), '%.18g' % findcurve_epsilon]
+    oc._dbg('STARTING FINDCURVE %s' % cl)
+    subproc = subprocess.Popen(
+      cl,
+      bufsize=1,
+      stdin=subprocess.PIPE,
+      stdout=subprocess.PIPE,
+      stderr=None,
+      close_fds=False,
+      # restore_signals=True, // want python2 compat, nnng
+      universal_newlines=True,
+    )
 
-    try:
-      subproc = findcurve_subprocs[nt]
-    except KeyError:
-      dbg('STARTING FINDCURVE %d' % nt)
-      subproc = subprocess.Popen(
-        ['./findcurve', '%d' % nt],
-        bufsize=1,
-        stdin=subprocess.PIPE,
-        stdout=subprocess.PIPE,
-        stderr=None,
-        close_fds=False,
-        # restore_signals=True, // want python2 compat, nnng
-        universal_newlines=True,
-      )
-      findcurve_subprocs[nt] = subproc
+    oc._dbg('RUNNING FINDCURVE')
 
-    dbg(('RUNNING FINDCURVE')
+    fc_input = np.hstack(fc_input)
+    s = ' '.join(map(str, fc_input))
 
-    findcurve_input = np.hstack(*findcurve_input)
-    s = ' '.join(map(str, findcurve_input))
+    oc._dbg(('>> %s' % s))
 
-    dbg(('>> %s' % s))
+    print(s, file=subproc.stdin)
+    subproc.stdin.flush()
 
-    print(s, file=findcurve_subproc.stdin)
-    findcurve_subproc.stdin.flush()
+    oc.subproc = subproc
+    oc.nt = nt
 
+    oc.sched.post_spawn()
+    #oc._await_subproc()
+
+  def _await_subproc(oc):
+    subproc = oc.subproc
+    if subproc is None: return
+
+    oc._dbg('(awaiting)')
     commentary = ''
 
     while True:
-      l = findcurve_subproc.stdout.readline()
+      l = subproc.stdout.readline()
+      if not l:
+        oc._dbg('findcurve EOF')
+        vdbg().crashing('findcurve EOF')
       l = l.rstrip()
-      dbg('<< ', l)
-      if not l: vdbg().crashing('findcurve EOF')
+      oc._dbg('<< ' + l)
       if not l.startswith('['):
         commentary += ' '
         commentary += l
@@ -76,24 +106,33 @@ class OptimisedCurve():
       l = eval(l)
       if not l: break
 
-      dbg('[%s] %s' % (l, commentary))
+      oc._dbg('[%s] %s' % (l, commentary))
       commentary = ''
 
-      hc.findcurve_result = l[0:6]
-      #hc.findcurve_result = findcurve_start
-      hc.threshold = l[0]**2
-      hc.total_dist = hc.threshold + l[1]**2
-      #vdbg().curve( hc.point_at_t )
-
-  def point_at_t(hc, normalised_parameter):
-    dist = normalised_parameter * hc.total_dist
-    ours = list(hc.findcurve_result)
-    if dist <= hc.threshold:
-      ours[0] = sqrt(dist)
-      ours[1] = 0
-    else:
-      ours[1] = sqrt(dist - hc.threshold)
-    asmat = hc.func(*ours)
-    p = asmat[:,0]
-    p = augmatmultiply(hc.findcurve_basis, p)
-    return p
+      findcurve_result = l
+
+    subproc.stdin.close()
+    subproc.wait()
+    assert(subproc.returncode == 0)
+    oc.subproc = None
+
+    oc.sched.post_reap()
+
+    oc._result = np.reshape(findcurve_result, (-1,3), 'C')
+    oc._dbg(repr(oc._result))
+
+    #vdbg().curve( oc.point_at_t )
+
+  def point_at_it(oc, it):
+    oc._await_subproc()
+    oc._dbg(repr((it,)))
+    return oc._result[it]
+
+  def point_at_t(oc, t):
+    itd = t * oc.nt
+    it0 = int(math.floor(itd))
+    it1 = int(math.ceil(itd))
+    p0 = oc.point_at_it(it0)
+    p1 = oc.point_at_it(it1)
+    return p0 + (p1-p0) * (itd-it0)
+