diff --git a/src/mode/sla/x_cxdlp.js b/src/mode/sla/x_cxdlp.js new file mode 100644 index 00000000..4659ceb7 --- /dev/null +++ b/src/mode/sla/x_cxdlp.js @@ -0,0 +1,406 @@ +(function() { + + const default_values = { + magic1: 'CXSW3DV2', + magic2: 'CXSW3DV2', + model: 'CL-89', + version: 1, + layer_count: 0, + res_x: 3840, + res_y: 2400, + height: 0, + thumb: undefined, + preview1: undefined, + preview2: undefined, + dim_x: '192.000000', + dim_y: '120.000000', + layer: '0.050000', + light_on: 6, + light_off: 2, + light_pwm: 255, + lift_dist: 6, + lift_speed: 60, + down_speed: 150, + base_layers: 8, + base_light_on: 60, + base_light_pwm: 255, + base_lift_dist: 5, + base_lift_speed: 60 + }; + const data_term = 0x0d0a; + + class CXDLP { + constructor() { + Object.assign(this, default_values); + } + + // takes a DataView Object + read(view) { + let read = new DataReader(view, 0); + + function read_string(dbl) { + let len = read.readU32(); + let str = ''; + while (--len > 0) { + if (dbl) { + read.readU8(); + len--; + } + str += String.fromCharCode(read.readU8()); + } + if (!dbl) { + read.skip(1); // null term on byte strings + } + return str; + } + + let meta = { + view, + magic1: read_string(), + version: read.readU16(), + model: read_string(), + layer_count: read.readU16(), + res_x: read.readU16(), + res_y: read.readU16(), + height: read.readU32(), + skip: read.skip(60), + thumb: read.skip(26914), + preview1: read.skip(168202), + preview2: read.skip(168202), + dim_x: read_string(true), + dim_y: read_string(true), + layer: read_string(true), + light_on: read.readU16(), + light_off: read.readU16(), + base_light_on: read.readU16(), + base_layers: read.readU16(), + base_lift_dist: read.readU16(), + base_lift_speed: read.readU16(), + lift_dist: read.readU16(), + lift_speed: read.readU16(), + down_speed: read.readU16(), + base_light_pwm: read.readU16(), + light_pwm: read.readU16() + }; + + // read layer record lengths + let layers = this.layers = []; + for (let i=0; i this.layers.length) { + throw `layer out of range 0-${this.layers.length}`; + } + let out = []; + let rec = this.layers[layer]; + let { lines, pos } = rec; + for (let j=0; j> 3; + let y_end = ((d1 & 0b111) << 10) | (d2 >> 6); + let x_end = ((d2 & 0b111111) << 8) | (d3 >> 8); + let color = d3 & 0xff; + out.push({y_start, y_end, x_end, color}); + } + return out; + } else { + throw "missing data view"; + } + } + + write() { + let output = new ArrayWriter(); + + output.write_string = function write_string(str, dbl = false) { + let len = str.length; + output.writeU32(dbl ? len * 2 : len + 1); + let pos = 0; + while (pos < len) { + if (dbl) { + output.writeU8(0); + } + output.writeU8(str.charCodeAt(pos++)); + } + if (!dbl) { + output.writeU8(0); + } + } + + let layers = this.layers; + this.layer_count = layers.length; + output.write_string(this.magic1); + output.writeU16(this.version); + output.write_string(this.model); + output.writeU16(this.layer_count); + output.writeU16(this.res_x); + output.writeU16(this.res_y); + output.writeU32(this.height); + output.skip(60); + output.skip(26912); // thumb + output.writeU16(data_term); + output.skip(168200); // preview1 + output.writeU16(data_term); + output.skip(168200); // preview1 + output.writeU16(data_term); + output.write_string(this.dim_x, true); + output.write_string(this.dim_y, true); + output.write_string(this.layer, true); + output.writeU16(this.light_on); + output.writeU16(this.light_off); + output.writeU16(this.base_light_on); + output.writeU16(this.base_layers); + output.writeU16(this.base_lift_dist); + output.writeU16(this.base_lift_speed); + output.writeU16(this.lift_dist); + output.writeU16(this.lift_speed); + output.writeU16(this.down_speed); + output.writeU16(this.base_light_pwm); + output.writeU16(this.light_pwm); + + // write placeholder layer length to capture position + for (let layer of layers) { + layer.l1 = output.pos; + output.writeU32(0); + } + output.writeU16(data_term); + + // write out encoded layers + for (let layer of layers) { + layer.l2 = output.pos; + // placeholder to be written post + output.writeU32(0); + output.writeU32(layer.lines.length); + let start = output.pos; + for (let line of layer.lines) { + let b1 = (line.y_start >> 5); + let b2 = ((line.y_start << 3) | (line.y_end >> 10)) & 0xff; + let b3 = (line.y_end >> 2) & 0xff; + let b4 = ((line.y_end << 6) | (line.x_end >> 8)) & 0xff; + let b5 = (line.x_end) & 0xff; + output.writeU8(b1); + output.writeU8(b2); + output.writeU8(b3); + output.writeU8(b4); + output.writeU8(b5); + output.writeU8(line.color); + } + layer.length = output.pos - start; + output.writeU16(data_term); + } + + output.write_string(this.magic2); + let ckpos = output.pos; + + // retrace and write layer lengths + for (let layer of layers) { + output.seek(layer.l1); + output.writeU32(layer.length); + output.seek(layer.l2); + output.writeU32(layer.length); + } + + output.seek(ckpos); + // compute xor checksum + let cksum = 0; + let array = output.array; + for (let i=0; i {return { lines: a }}); + cxdlp.res_x = device.resolutionX; + cxdlp.res_y = device.resolutionY; + cxdlp.dim_x = device.bedWidth.toFixed(5); + cxdlp.dim_y = device.bedDepth.toFixed(5); + cxdlp.layer = process.slaSlice.toFixed(5); + cxdlp.thumb = thumb; + cxdlp.preview1 = preview1; + cxdlp.preview1 = preview2; + cxdlp.light_on = process.slaLayerOn; + cxdlp.light_off = process.slaLayerOff; + // cxdlp.light_pwm = 255; + cxdlp.lift_dist = process.slaPeelDist; + cxdlp.lift_speed = process.slaPeelLiftRate * 60; + cxdlp.base_layers = process.slaBaseLayers; + cxdlp.base_light_on = process.slaBaseOn; + // cxdlp.base_light_pwm = 255; + cxdlp.base_lift_dist = process.slaBasePeelDist; + cxdlp.base_lift_speed = process.slaBasePeelLiftRate * 60; + + return cxdlp.write(); + }; + + CXDLP.render = function(params) { + let { width, height, index, widgets, scaleX, scaleY } = params; + let width2 = width / 2, height2 = height / 2; + let array = []; + let count = 0; + + function scaleMovePoly(poly) { + let points = poly.points; + poly._bounds = undefined; + for (let i=0, il=points.length; i { + let slice = widget.slices[index]; + if (slice) { + if (slice.synth) count++; + let polys = slice.unioned; + if (!polys) polys = slice.tops.map(t => t.poly); + if (slice.supports) polys.appendAll(slice.supports); + array.appendAll(polys.map(poly => { + return poly.clone(true).move(widget.track.pos); + })); + count += polys.length; + } + }); + + let wasm = kiri.driver.SLA.wasm; + let imagelen = width * height; + let writer = new self.DataWriter(new DataView(wasm.memory.buffer), imagelen); + writer.writeU16(width, true); + writer.writeU16(height, true); + writer.writeU16(array.length, true); + + // scale and move all polys to fit in rendered platform coordinates + for (let i=0, il=array.length; i