<commit_before>/** Copyright 2014-2017 <NAME> -- All Rights Reserved */

"use strict";

var gs_kiri_laser = exports;

(function() {

    if (!self.kiri) self.kiri = { };
    if (!self.kiri.driver) self.kiri.driver = { };
    if (self.kiri.driver.LASER) return;

    var KIRI = self.kiri,
        BASE = self.base,
        UTIL = BASE.util,
        DBUG = BASE.debug,
        LASER = KIRI.driver.LASER = { },
        SLICER = KIRI.slicer,
        newPoint = BASE.newPoint;

    /**
     * DRIVER SLICE CONTRACT
     *
     * @param {Object} settings
     * @param {Widget} Widget
     * @param {Function} onupdate (called with % complete and optional message)
     * @param {Function} ondone (called when complete with an array of Slice objects)
     */
    LASER.slice = function(settings, widget, onupdate, ondone) {
        var proc = settings.process;

        if (proc.laserSliceHeight < 0) {
            DBUG.log("invalid slice height");
            return ondone(false);
        }

        SLICER.sliceWidget(widget, {height: proc.laserSliceHeight}, function(slices) {
            widget.slices = slices;
            slices.forEach(function(slice, index) {
                slice.doShells(1, -proc.laserOffset);
                onupdate(0.80 + (index/slices.length) * 0.20);
            });
            ondone(true);
        }, function(update) {
            onupdate(0.0 + update * 0.80)
        });
    };

    function sliceEmitObjects(print, slice, objects) {
        var start = newPoint(0,0,0);

        function laserOut(poly, object) {
            if (!poly) return;
            if (Array.isArray(poly)) {
                poly.forEach(function(pi) {
                    laserOut(pi, object);
                });
            } else {
                print.polyPrintPath(poly, start, object, 1);
            }
        }

        slice.tops.forEach(function(top) {
            var object = [];
            laserOut(top.traces, object);
            laserOut(top.innerTraces(), object);
            objects.push(object);
        });
    };

    /**
     * DRIVER PRINT CONTRACT
     *
     * @param {Object} print state object
     * @param {Function} update incremental callback
     */
    LASER.printSetup = function(print, update) {
        var widgets = print.widgets,
            settings = print.settings,
            device = settings.device,
            process = settings.process,
            mode = settings.mode,
            output = print.output,
            totalSlices = 0,
            slices = 0;

        // find max layers (for updates)
        widgets.forEach(function(widget) {
            totalSlices += widget.slices.length;
        });

        // emit objects from each slice into output array
        widgets.forEach(function(widget) {
            widget.slices.forEach(function(slice) {
                sliceEmitObjects(print, slice, output);
                update(slices++ / totalSlices);
            });
        });

        // compute tile width / height
        output.forEach(function(layerout) {
            var min = {w:Infinity, h:Infinity}, max = {w:-Infinity, h:-Infinity}, p;
            layerout.forEach(function(out) {
                p = out.point;
                min.w = Math.min(min.w, p.x);
                max.w = Math.max(max.w, p.x);
                min.h = Math.min(min.h, p.y);
                max.h = Math.max(max.h, p.y);
            });
            layerout.w = max.w - min.w;
            layerout.h = max.h - min.h;
        });

        // do object layout packing
        var i, m, e,
            MOTO = self.moto,
            device = settings.device,
            process = settings.process,
            mp = [device.bedWidth, device.bedDepth],
            ms = [mp[0] / 2, mp[1] / 2],
            mi = mp[0] > mp[1] ? [(mp[0] / mp[1]) * 10, 10] : [10, (mp[1] / mp[1]) * 10],
            // sort objects by size
            c = output.sort(function (a, b) { return (b.w * b.h) - (a.w * a.h) }),
            p = new MOTO.Pack(ms[0], ms[1], process.outputTileSpacing).fit(c);

        while (!p.packed) {
            ms[0] += mi[0];
            ms[1] += mi[1];
            p = new MOTO.Pack(ms[0], ms[1], process.outputTileSpacing).fit(c);
        }

        for (i = 0; i < c.length; i++) {
            m = c[i];
            m.fit.x += m.w / 2 + p.pad;
            m.fit.y += m.h / 2 + p.pad;
            m.forEach(function(o, i) {
                // because first point emitted twice (begin/end)
                e = o.point = o.point.clone();
                e.x += p.max.w / 2 - m.fit.x;
                e.y += p.max.h / 2 - m.fit.y;
                e.z = 0;<commit_msg>fix laser packing for offset polys<commit_after>/** Copyright 2014-2017 <NAME> -- All Rights Reserved */

"use strict";

var gs_kiri_laser = exports;

(function() {

    if (!self.kiri) self.kiri = { };
    if (!self.kiri.driver) self.kiri.driver = { };
    if (self.kiri.driver.LASER) return;

    var KIRI = self.kiri,
        BASE = self.base,
        UTIL = BASE.util,
        DBUG = BASE.debug,
        LASER = KIRI.driver.LASER = { },
        SLICER = KIRI.slicer,
        newPoint = BASE.newPoint;

    /**
     * DRIVER SLICE CONTRACT
     *
     * @param {Object} settings
     * @param {Widget} Widget
     * @param {Function} onupdate (called with % complete and optional message)
     * @param {Function} ondone (called when complete with an array of Slice objects)
     */
    LASER.slice = function(settings, widget, onupdate, ondone) {
        var proc = settings.process;

        if (proc.laserSliceHeight < 0) {
            DBUG.log("invalid slice height");
            return ondone(false);
        }

        SLICER.sliceWidget(widget, {height: proc.laserSliceHeight}, function(slices) {
            widget.slices = slices;
            slices.forEach(function(slice, index) {
                slice.doShells(1, -proc.laserOffset);
                onupdate(0.80 + (index/slices.length) * 0.20);
            });
            ondone(true);
        }, function(update) {
            onupdate(0.0 + update * 0.80)
        });
    };

    function sliceEmitObjects(print, slice, objects) {
        var start = newPoint(0,0,0);

        function laserOut(poly, object) {
            if (!poly) return;
            if (Array.isArray(poly)) {
                poly.forEach(function(pi) {
                    laserOut(pi, object);
                });
            } else {
                print.polyPrintPath(poly, start, object, 1);
            }
        }

        slice.tops.forEach(function(top) {
            var object = [];
            laserOut(top.traces, object);
            laserOut(top.innerTraces(), object);
            objects.push(object);
        });
    };

    /**
     * DRIVER PRINT CONTRACT
     *
     * @param {Object} print state object
     * @param {Function} update incremental callback
     */
    LASER.printSetup = function(print, update) {
        var widgets = print.widgets,
            settings = print.settings,
            device = settings.device,
            process = settings.process,
            mode = settings.mode,
            output = print.output,
            totalSlices = 0,
            slices = 0;

        // find max layers (for updates)
        widgets.forEach(function(widget) {
            totalSlices += widget.slices.length;
        });

        // emit objects from each slice into output array
        widgets.forEach(function(widget) {
            widget.slices.forEach(function(slice) {
                sliceEmitObjects(print, slice, output);
                update(slices++ / totalSlices);
            });
        });

        // compute tile width / height
        output.forEach(function(layerout) {
            var min = {w:Infinity, h:Infinity}, max = {w:-Infinity, h:-Infinity}, p;
            layerout.forEach(function(out) {
                p = out.point;
                out.point = p.clone(); // b/c first/last point are often shared
                min.w = Math.min(min.w, p.x);
                max.w = Math.max(max.w, p.x);
                min.h = Math.min(min.h, p.y);
                max.h = Math.max(max.h, p.y);
            });
            layerout.w = max.w - min.w;
            layerout.h = max.h - min.h;
            // shift objects to top/left of w/h bounds
            layerout.forEach(function(out) {
                p = out.point;
                p.x -= min.w;
                p.y -= min.h;
            });
        });

        // do object layout packing
        var i, m, e,
            MOTO = self.moto,
            device = settings.device,
            process = settings.process,
            mp = [device.bedWidth, device.bedDepth],
            ms = [mp[0] / 2, mp[1] / 2],
            mi = mp[0] > mp[1] ? [(mp[0] / mp[1]) * 10, 10] : [10, (mp[1] / mp[1]) * 10],
            // sort objects by size
            c = output.sort(function (a, b) { return (b.w * b.h) - (a.w * a.h) }),
            p = new MOTO.Pack(ms[0], ms[1], process.outputTileSpacing).fit(c);

        // test different ratios until packed
        while (!p.packed) {
            ms[0] += mi[0];
            ms[1] += mi[1];
            p = new MOTO.Pack(ms[0], ms[1], process.outputTileSpacing).fit(c);
        }

        for (i = 0; i < c.length; i++) {
            m = c[i];
            m.fit.x += m.w / 2 + p.pad;
            m.fit.y += m.h / 2 + p.pad;
            m.forEach(function(o, i) {
                // because first point emitted twice (begin/end)
                e = o.point;
                e.x += p.max.w / 2 - m.fit.x;
                e.y += p.max.h / 2 - m.fit.y;
                e.z = 0;
{'fraction_non_alphanumeric': 0.13928794503435352, 'fraction_numerical': 0.012283989173433272, 'mean_word_length': 1.4760309278350516, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4084875', 'n_tokens_mistral': 3122, 'n_tokens_neox': 2968, 'n_words': 672}