reprap = {} -- adds to each node in a line from to function reprap.drawline3d(from_position, to_position, material) --modified from https://github.com/ryanramage/bresenham3d/blob/master/index.js --lua port by jin_xi local line = {} local temp local x0 = math.floor(from_position.x) local y0 = math.floor(from_position.y) local z0 = math.floor(from_position.z) local x1 = math.floor(to_position.x) local y1 = math.floor(to_position.y) local z1 = math.floor(to_position.z) --'steep' xy Line, make longest delta x plane local swap_xy = math.abs(y1 - y0) > math.abs(x1 - x0) if swap_xy then temp = x0; x0 = y0; y0 = temp --swap(x0, y0); temp = x1; x1 = y1; y1 = temp --swap(x1, y1); end local swap_xz = math.abs(z1 - z0) > math.abs(x1 - x0) if swap_xz then temp = x0; x0 = z0; z0 = temp --swap(x0, z0); temp = x1; x1 = z1; z1 = temp --swap(x1, z1); end --delta is Length in each plane local delta_x = math.abs(x1 - x0) local delta_y = math.abs(y1 - y0) local delta_z = math.abs(z1 - z0) --drift controls when to step in 'shallow' planes --starting value keeps Line centred local drift_xy = (delta_x / 2) local drift_xz = (delta_x / 2) --direction of line local step_x = 1 if x0 > x1 then step_x = -1 end local step_y = 1 if y0 > y1 then step_y = -1 end local step_z = 1 if z0 > z1 then step_z = -1 end --starting point local y = y0 local z = z0 --step through longest delta (which we have swapped to x) local cx, cy, cz for x = x0, x1, step_x do --copy position cx = x; cy = y; cz = z --unswap (in reverse) if swap_xz then temp = cx; cx = cz; cz = temp --swap(cx, cz) end if swap_xy then temp = cx; cx = cy; cy = temp --swap(cx, cy) end print("drawing dot: "..cx..', '..cy..', '..cz) --minetest.env:add_node({ x = cx, y = cy, z = cz }, { name=material, param2=2 }) table.insert(line, { pos={ x = cx, y = cy, z = cz }, mat = material }) --update progress in other planes drift_xy = drift_xy - delta_y drift_xz = drift_xz - delta_z --step in y plane if drift_xy < 0 then y = y + step_y drift_xy = drift_xy + delta_x end --same in z if (drift_xz < 0) then z = z + step_z drift_xz = drift_xz + delta_x end end return line end -- process a gcode file placing on each point touched by the machine function reprap.process_gcode(filename, material, center) local path = minetest.get_modpath("reprap").."/"..filename local nodes = {} local min = {x=center.x, y=center.y, z=center.z} local max = {x=center.x, y=center.y, z=center.z} local mat = minetest.get_content_id(material) local f = io.open(path) local line local cmd, param = "", "" local lastx, lasty, lastz local cmdx, cmdy, cmdz lastx = 0 lasty = 0 lastz = 0 for line in f:lines() do if (line ~= "") and (line:sub(1,1) ~= ";") then if string.find(line, "G1 ") then cmdx = lastx cmdy = lasty cmdz = lastz for cmd, param in string.gmatch(line, "(%w)([0-9.-]+)") do param = tonumber(param) if cmd == "X" then cmdx = param elseif cmd == "Y" then cmdz = param elseif cmd == "Z" then cmdy = param end end local p1 = { x = center.x + lastx, y = center.y + lasty, z = center.z + lastz } local p2 = { x = center.x + cmdx, y = center.y + cmdy, z = center.z + cmdz } min, max = check_pos(min, max, p1) min, max = check_pos(min, max, p2) table.insert(nodes, reprap.drawline3d( p1, p2, mat ) ) lastx = cmdx lasty = cmdy lastz = cmdz end end end local vm = VoxelManip() --print("min: .."..dump(min).." max: "..dump(max)) min, max = vm:read_from_map(min, max) --print("min: .."..dump(min).." max: "..dump(max)) local area = VoxelArea:new{ MinEdge = min, MaxEdge = max } local data = vm:get_data() for _, lines in pairs(nodes) do for _, node in pairs(lines) do local index = area:indexp(node.pos) data[index] = node.mat end end vm:set_data(data) vm:write_to_map() vm:update_map() end minetest.register_chatcommand("reprap", { params = ",,,,", description = "start printing a gcode file", privs = {}, func = function(name, param) local paramlist print(param) paramlist = string.split(param, ",") print(paramlist[1]) print(paramlist[2]) print(paramlist[3]) print(paramlist[4]) print(paramlist[5]) filename = paramlist[1] material = paramlist[2] drawx = tonumber(paramlist[3]) drawy = tonumber(paramlist[4]) drawz = tonumber(paramlist[5]) reprap.process_gcode(filename, material, { x=drawx, y=drawy, z=drawz }) -- reprap.process_gcode("column.gcode", "default:mese", { x=-65, y=0, z=77 }) end } ) function check_pos(min, max, pos) if pos.x < min.x then min.x = pos.x end if pos.y < min.y then min.y = pos.y end if pos.z < min.z then min.z = pos.z end if pos.x > max.x then max.x = pos.x end if pos.y > max.y then max.y = pos.y end if pos.z > max.z then max.z = pos.z end return min, max end