Skip to content

Commit

Permalink
Merge pull request #11 from flux3dp/dev
Browse files Browse the repository at this point in the history
Release 0.7a5
  • Loading branch information
yen-von committed Dec 24, 2015
2 parents c68e92f + a779b4b commit 1504111
Show file tree
Hide file tree
Showing 19 changed files with 418 additions and 264 deletions.
2 changes: 1 addition & 1 deletion fluxclient/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ def check_pcl():
return False


__version__ = "0.7a4"
__version__ = "0.7a5"
SUPPORT_PCL = check_pcl()
174 changes: 33 additions & 141 deletions fluxclient/commands/experiment_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,10 @@
from fluxclient.scanner.pc_process import PcProcess


logger = logging.Logger(__name__)
logger.setLevel(level=logging.DEBUG)


def show_pc(name, pc_in):
return '{} size:{}'.format(name, len(pc_in[0]))


def cross(p0, p1, p2):
return ((p1[0] - p0[0]) * (p2[1] - p0[1])) - ((p1[1] - p0[1]) * (p2[0] - p0[0]))


def main(in_file, out_file, command=''):
_PcProcess = PcProcess()
tmp = out_file.rfind('.')
Expand All @@ -44,153 +36,53 @@ def main(in_file, out_file, command=''):
suffix = 'stl'
print('done')
elif i.startswith('A'):
if i[1] == 'f':
import bisect
import copy
from math import sqrt, asin, pi, radians, cos, sin

floor = -10
steps = 400
print('adding floor')
a = []
# print(len(_PcProcess.clouds['in'][0]))
_PcProcess.cut('in', 'in', 'z', True, floor)
print(len(_PcProcess.clouds['in'][0]))
# for z in range(len(_PcProcess.clouds['in'][0]) - 1):
for z in range(len(_PcProcess.clouds['in'][0])):
# if _PcProcess.clouds['in'][0][z][2] < _PcProcess.clouds['in'][0][z + 1][2]: # detect for tail
a.append(_PcProcess.clouds['in'][0][z])

# get near floor and a ring point set
d = [[p, asin(p[1] / sqrt(p[0] ** 2 + p[1] ** 2)) if p[0] > 0 else pi - asin(p[1] / sqrt(p[0] ** 2 + p[1] ** 2))] for p in a] # add theta data
d = sorted(d, key=lambda x: abs(x[0][2] - floor))

rec = [float('-inf'), float('inf')]
interval = 2 * pi / 400 * 0.9
after = []
for p in d:
tmp_index = bisect.bisect(rec, p[1])
if p[1] - rec[tmp_index - 1] > interval and rec[tmp_index] - p[1] > interval:
rec.insert(tmp_index, p[1])
after.append(p)
if len(rec) > 400 + 2:
break

# print('rec l:', len(rec))
# for p in after:
# p[0][3] = 255
# _PcProcess.clouds['in'][0].push_backPoint(*p[0])
# continue

# compute for center (no need?)
after = sorted(after, key=lambda x: x[1])
after = [p[0] for p in after]
# c = [0.0 for _ in range(6)]
# for p in after:
# for _ in range(6):
# c[_] += p[_]
# for _ in range(6):
# c[_] /= len(after)

plane = copy.deepcopy(after)
for p in plane:
pass
# print(p[2])
# p[2] = floor

# for p in plane:
# p[3] = 255
# _PcProcess.clouds['in'][0].push_backPoint(*p)
# continue

index = list(range(len(plane)))
index = sorted(index, key=lambda x: [after[x][0], after[x][1]])
output = []
for j in index: # upper
while len(output) >= 2 and cross(after[output[-2]], after[output[-1]], after[j]) <= 0:
output.pop()
output.append(j)

t = len(output) + 1
for j in index[-2::-1]: # lower
while len(output) > t and cross(after[output[-2]], after[output[-1]], after[j]) <= 0:
output.pop()
output.append(j)
output.pop()

boarder = [after[x] for x in sorted(output)]
# for p in plane:
# p[3] = 255
# _PcProcess.clouds['in'][0].push_backPoint(*p)
# continue
# plane = after

from scipy.interpolate import Rbf
tmp = []
grid_leaf = 100
X = np.linspace(min(p[0] for p in plane), max(p[0] for p in plane), grid_leaf)
Y = np.linspace(min(p[1] for p in plane), max(p[1] for p in plane), grid_leaf)
XI, YI = np.meshgrid(X, Y)

x = [p[0] for p in plane]
y = [p[1] for p in plane]
z = [p[2] for p in plane]
print(len(z))

rbf = Rbf(x, y, z, function='linear')
ZI = rbf(XI, YI)
print(ZI.dtype)
for xx in range(grid_leaf):
for yy in range(grid_leaf):
# print([XI[xx][yy], YI[xx][yy], ZI[xx][yy], 255, 0, 0])
p = [XI[xx][yy], YI[xx][yy], ZI[xx][yy], 255, 0, 0]
flag = True
for b in range(len(boarder)):
if (cross(boarder[b], boarder[(b + 1) % len(boarder)], p)) < 0:
flag = False
break
if flag:
tmp.append(p)
# print(p[2])

# for d in range(360):
# for r in range(100):
# p = [r * cos(radians(d)), r * sin(radians(d)), floor, 0, 0, 0]
# flag = True
# for b in range(len(plane)):
# if (cross(plane[b], plane[(b + 1) % len(plane)], p)) < 0:
# flag = False
# break
# if flag:
# tmp.append(p)

plane += tmp
# _PcProcess.add_floor('in', 'in')
for p in plane:
p[3] = 255
_PcProcess.clouds['in'][0].push_backPoint(*p)

# _PcProcess.clouds['in'] = _PcProcess.to_cpp([plane, []])

# _PcProcess.clouds['in'][0].to_mesh('GPT')
# suffix = 'stl'

elif i[1] == 'c':
print('adding ceiling')
print('adding at {}...'.format(float(i[2:])))
_PcProcess.closure('in', 'in', float(i[2:]), i[1] == 'f')
print('done')
elif i.startswith('E'):
print(timestamp, 'export file {}.{}'.format(prefix, suffix))
tmp = _PcProcess.export('in', suffix)
with open(prefix + '.' + suffix, 'wb') as f:
f.write(tmp)
elif i.startswith('C'):
print('Clustering')
if i[1] == 's': # show the clustering
thres = float(i[2:])
else:
thres = float(i[1:])
pc = _PcProcess.clouds['in']
# Euclidean_Cluster
output = pc[0].Euclidean_Cluster(thres)
output = sorted(output, key=lambda x: len(x))
print('finish with {} cluster'.format(len(output)))

tmp_pc = _PcProcess.to_cpp([[], []])
if i[1] == 's':
tmp_index = 0
else:
tmp_index = -1
import random
r = lambda: random.randint(0, 255)
for j in output[tmp_index:]:
c = [r(), r(), r()]
for k in j:
p = _PcProcess.clouds['in'][0][k]
if i[1] == 's':
tmp_pc[0].push_backPoint(p[0], p[1], p[2], *c)
else:
tmp_pc[0].push_backPoint(*p)
_PcProcess.clouds['in'] = tmp_pc


parser = argparse.ArgumentParser(description='An experiment tool for scanning improve', formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-i', '--input', help='input filename', required=True)
parser.add_argument('-o', '--output', help='output filename', default='output.pcd')
parser.add_argument('-c', '--command', default='', help='ex: N0.3PE\n'
'N[stddev]: noise del with dev [stddev]\n'
'P: Possion Meshing\n'
'A[fc][value]: add [floor] or [ceiling] at z = [value]'
'E: export file\n'
'C[s]?[value]: clustring points base on distance'
)
args = parser.parse_args()

Expand Down
5 changes: 5 additions & 0 deletions fluxclient/fcode/fcode_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class dealing with gcode <-> fcode... etc
"""
def __init__(self):
super(FcodeBase, self).__init__()
self.filament_this_layer = [0., 0., 0.]
self.empty_layer = []

def process_path(self, comment, moveflag, extrudeflag):
"""
Expand All @@ -25,9 +27,12 @@ def process_path(self, comment, moveflag, extrudeflag):
elif 'move' in comment:
line_type = 3
if 'to next layer' in comment:
if self.filament == self.filament_this_layer:
self.empty_layer.append(self.layer_now)
tmp = findall('[0-9]+', comment)[-1]
self.layer_now = int(tmp)
self.path.append([self.path[-1][-1][:3] + [line_type]])
self.filament_this_layer = self.filament[:]
elif 'skirt' in comment:
line_type = 4
elif 'draw' in comment:
Expand Down
13 changes: 9 additions & 4 deletions fluxclient/fcode/g_to_f.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(self, version=1, head_type="EXTRUDER", ext_metadata={}):
self.G92_delta = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # X, Y, Z, E1, E2, E3 -> recording the G92 delta for each axis
self.time_need = 0. # recording time the printing process need, in sec
self.distance = 0. # recording distance go through
self.max_range = [0., 0., 0.] # recording max coordinate
self.max_range = [0., 0., 0., 0.] # recording max coordinate, [x, y, z, r]
self.filament = [0., 0., 0.] # recording the filament needed, in mm
self.md = {'HEAD_TYPE': head_type} # basic metadata, use extruder as default
self.md.update(ext_metadata)
Expand Down Expand Up @@ -137,6 +137,8 @@ def analyze_metadata(self, input_list, comment):
if abs(self.current_pos[i - 1]) > self.max_range[i - 1]:
# self.max_range[i - 1] = abs(self.current_pos[i - 1])
self.max_range[i - 1] = self.current_pos[i - 1]
if self.current_pos[0] ** 2 + self.current_pos[1] ** 2: # computer MAX_R
self.max_range[3] = self.current_pos[0] ** 2 + self.current_pos[1] ** 2
tmp_path = sqrt(tmp_path)
self.distance += tmp_path
self.time_need += tmp_path / self.current_speed * 60 # from minute to sec
Expand Down Expand Up @@ -297,11 +299,14 @@ def process(self, input_stream, output_stream):
output_stream.seek(0, 2) # go back to file end

# warning: fileformat didn't consider multi-extruder, use first extruder instead
if self.empty_layer[0] == 0:
self.empty_layer.pop(0)
self.md['FILAMENT_USED'] = ','.join(map(str, self.filament))
self.md['TRAVEL_DIST'] = str(self.distance)
self.md['MAX_X'] = str(self.max_range[0])
self.md['MAX_Y'] = str(self.max_range[1])
self.md['MAX_Z'] = str(self.max_range[2])

for v, k in enumerate(['Z', 'Y', 'Z', 'R']):
self.md['MAX_' + k] = str(self.max_range[v])

self.md['TIME_COST'] = str(self.time_need)
self.md['CREATED_AT'] = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(time.time()))
self.md['AUTHOR'] = getuser() # TODO: use fluxstudio user name?
Expand Down
Loading

0 comments on commit 1504111

Please sign in to comment.