spin wrote:Some initial money for devs and/or the whole Minetest project. Though I need a cost estimate so I can discuss this project with my employer.
default_privs = interact, shout, flydefault_privs = interact, shout, fly
free_move = true
Krock wrote:Oh cool! Some money in a FOSS project!
Krock wrote:For the modelling I would suggest Blender.
Krock wrote:For the "fly" priv as default:
https://github.com/minetest/minetest/bl ... ample#L290
MeansYour phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
default_privs = interact, shout, fly
in your minetest.conf.
Krock wrote:There aren't any world which would contain a 4x4x4 block only. Flat maps should work too.
rubenwardy wrote:To put them in fly mode to start with, add this to minetest.confYour phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
default_privs = interact, shout, fly
free_move = true
Evergreen wrote:In the main directory of minetest, there is a file called minetest.conf.example. It contains all the possible settings that can exist in minetest.conf.
reprap = {}
-- adds <material> to each node in a line from <from_position> to <to_position>
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 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 })
--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
end
-- process a gcode file <filename> placing <material> on each point touched by the machine
function reprap.process_gcode(filename, material, center)
local path = minetest.get_modpath("reprap").."/"..filename
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
reprap.drawline3d(
{ x = center.x + lastx, y = center.y + lasty, z = center.z + lastz },
{ x = center.x + cmdx, y = center.y + cmdy, z = center.z + cmdz },
material
)
lastx = cmdx
lasty = cmdy
lastz = cmdz
end
end
end
end
minetest.register_chatcommand("reprap", {
params = "<gcodefilename>,<material>,<x>,<y>,<z>",
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
}
)
aldobr wrote:I've already developed a solution that works backwards from what you want. Here : https://forum.minetest.net/viewtopic.php?f=9&t=7101 (Unfortunately this mod is lost).
Its my minetest g-code interpreter. You can model objects in FreeCAD, slice them using Slicer and then import the object back into minetest world. I can develop something that works by exporting G-Code compatible with reprap from the game. Blender is not in my expertise area.
srifqi wrote:How about .we file? We just need a converter from .we to single mesh file
aldobr wrote:I dont need a slicer. I can write g-code right from minetest.
Evergreen wrote:That mesh exporter is going to be useful for more than just 3d printing. :3
spin wrote:2-3 kinds of monochromatic cubes in infinite amounts available for player
spin wrote:2-3 kinds of monochromatic cubes in infinite amounts available for player
spin wrote:- srifqi's Superflat MapGen: viewtopic.php?f=9&t=9772
aldobr wrote:"Far more powerfull".
Can you quantify that or is just something that you made up from your own prejudices ? By knowing the theory behind compilers and programming languages, i call that bullshit.
All that you can say is that both python and lua are turing complete, imperative - with multi-paradigmatic elements, object oriented high level languages. While python uses a object oriented model that ressembles Smalltalk (Class based), Lua has a object model that is similar to Self language (Prototype based). Thats all you can say, the rest is bullshit, because it cant be quantified.
-- Block Export [blockexport] mod. All code is WTFPL.
-- Author: prestidigitator (as registered on forum.minetest.net)
--
-- This mod defines a new chat command "/exportblock" which writes 3D node data
-- of the player's current 80x80x80 node block to a file. This chat command
-- requires the (new) "export" privilege.
--
-- The export file format is as follows:
-- xMin,yMin,zMin
-- rowData1
-- rowData2
-- ...
--
-- where rowDataN is a sequence of double hex digits (e.g. 00, fd, 12), each
-- representing a single material index. Each material index indentifies the
-- material at the corresponding position in the EXPORT_NODES array, with "00"
-- representing no material. The row data is indexed by x coordinate (with
-- 80 entries). The first row is at y = yMin and z = zMin, and they
-- are ordered with y incrementing most often (so the second row is at
-- y = yMin+1, z = zMin). There will be exactly 80*80 = 6400 lines with row
-- data.
--
-- The file exported is in the world directory, named
-- "<prefix><bx>-<by>-<bz><suffix>", where <prefix> is FILE_PREFIX, <suffix>
-- is FILE_SUFFIX, and <bx>, <by>, and <bz> are the (minimum) x, y, and z
-- coordinates of the exported block, with negative values prefixed by a "m"
-- character rather than a minus sign. For example, with the default prefix of
-- "block_" and default suffix of ".mtb", exporting the block just
-- north/east/above the origin would write "block_0-0-0.mtb" and exporting the
-- one just south/west/below would write "block_m1-m1-m1.mtb". Each exported
-- block file is very close to 1 MB in size.
---- Configuration Data: Modify to customize behavior
local FILE_PREFIX = "block_";
local FILE_SUFFIX = ".mtb";
local EXPORT_NODES = { "wool:white", "wool:red", "wool:green", "wool:blue" };
---- End Configuration Data
local MOD_NAME = minetest.get_current_modname();
if #EXPORT_NODES > 255 then
error(MOD_NAME .. ": too many export node names");
end
local contentIdToMaterialIndex;
do
local EXPORT_MAP = nil;
contentIdToMaterialIndex = function(cid)
if not EXPORT_MAP then
EXPORT_MAP = {};
for index, name in ipairs(EXPORT_NODES) do
local cid = minetest.get_content_id(name);
EXPORT_MAP[cid] = index;
end
end
return EXPORT_MAP[cid] or 0;
end;
end
local function fileName(pos)
local xs = math.floor(pos.x);
local ys = math.floor(pos.y);
local zs = math.floor(pos.z);
if xs >= 0 then xs = tostring(xs); else xs = "m" .. tostring(-xs); end
if ys >= 0 then ys = tostring(ys); else ys = "m" .. tostring(-ys); end
if zs >= 0 then zs = tostring(zs); else zs = "m" .. tostring(-zs); end
return FILE_PREFIX .. xs .. "-" .. ys .. "-" .. zs .. FILE_SUFFIX;
end
local function toHex(index)
index = math.floor(index) % 256;
return string.format("%02x", index);
end
local function exportBlock(pos)
local bx = 80 * math.floor(pos.x / 80);
local by = 80 * math.floor(pos.y / 80);
local bz = 80 * math.floor(pos.z / 80);
local bmin = { x = bx, y = by, z = bz };
local bmax = { x = bx + 79, y = by + 79, z = bz + 79 };
local vm = minetest.get_voxel_manip();
bmin, bmax = vm:read_from_map(bmin, bmax);
local data = vm:get_data();
local va = VoxelArea:new({ MinEdge = bmin, MaxEdge = bmax });
local fname = fileName(bmin);
local fpath = minetest.get_worldpath() .. "/" .. fname;
local file, emsg = io.open(fpath, "w");
if not file then error(emsg); end
file:write(bx .. "," .. by .. "," .. bz .. "\n");
for zi = 0, 79 do
for yi = 0, 79 do
for xi = 0, 79 do
local pos = { x = bx + xi, y = by + yi, z = bz + zi };
local materialIndex = 0;
if va:containsp(pos) then
local cid = data[va:indexp(pos)];
materialIndex = contentIdToMaterialIndex(cid);
end
file:write(toHex(materialIndex));
end
file:write("\n");
end
end
file:flush();
file:close();
return fname;
end
minetest.register_privilege(
"export",
{
description = "Allows exporting of data to files",
give_to_singleplayer = true
});
minetest.register_chatcommand(
"exportblock",
{
params = "",
description = "Exports your current 80x80x80 node block to a file",
privs = { export = true },
func =
function(name, paramStr)
local player = minetest.get_player_by_name(name);
local fname = exportBlock(player:getpos());
return true, "current block exported to " .. fname;
end
});
prestidigitator wrote:aldobr wrote:"Far more powerfull".
Can you quantify that or is just something that you made up from your own prejudices ? By knowing the theory behind compilers and programming languages, i call that bullshit.
All that you can say is that both python and lua are turing complete, imperative - with multi-paradigmatic elements, object oriented high level languages. While python uses a object oriented model that ressembles Smalltalk (Class based), Lua has a object model that is similar to Self language (Prototype based). Thats all you can say, the rest is bullshit, because it cant be quantified.
By referring to "Minetest+Lua" and "Blender+Python" I was speaking of the entire platforms, not just the programming languages. Blender's API plus Python's standard library offers far, far, FAR more functionality than Minetest's API plus Lua's standard library, and you would have to link lots and LOTS of Lua extensions to even begin to close the gap. Blender's API is also much more useful for 3D mesh data manipulation. Of course, if we wanted to speak about the programming languages alone, Python allows you to do "more with less" in terms of verbosity, so it does offer an advantage in terms of development at the cost of being rather inappropriate for an embedded (game-oriented) scripting language.
I have nothing against Minetest or Lua. They are good tools for their intended purposes. This project would just be far better served by a combination of the platforms. No need to get defensive about it.
aldobr wrote:Subjective bullshit....
spin wrote:We have 3 solutions emerging, all of which are perfect for different tasks, and allow huge versatility. I don't see overlap here.
prestidigitator wrote: The part I was thinking would be easiest to do from a Blender plugin would be to create face data while eliminating unnecessary and unwanted internal geometry. Blender now even has "FGONs" (N-gon faces) which would probably allow a smooth workflow without the need for mod/plugin code to try to break faces into quads or triangles.
spin wrote:Yes, Blender supports n-gons, and recently they gave a huge boost to Boolean operations since the modifier was rewritten to use them.
I have no idea how to make a surface-only mesh from Minetest. For my purpose I care only about geometry, not textures, since FFF printers are rather monochromatic.
The approaches to building a single geometry can be different. Either:
- we try to merge the cubes using boolean operations as they are imported.
- we detect outermost faces by, idk, calculating mesh proximity or overlaps, and then remove doubles inside Blender to have them merged.
- we detect outermost vertices of cubes, and build a smooth mesh by connecting them together (in which case the result is smooth, and we treat Minetest's cubes kind of like metaballs)
-we spawn metaballs instead of cubes and let Blender do the processing :P
- something completely different. Meshlab + point cloud, idk.
-- Block Export [blockexport] mod. All code is WTFPL.
-- Author: prestidigitator (as registered on forum.minetest.net)
--
-- This mod defines a new chat command "/exportblock" which writes 3D node data
-- of the player's current 80x80x80 node block to a file. This chat command
-- requires the (new) "export" privilege.
--
-- The export file format is as follows:
-- xMin,yMin,zMin
-- rowData1
-- rowData2
-- ...
--
-- where rowData is a sequence of hex digits, each representing a bitmask of
-- booleans for block presence. Each bit corresponds with a node having one of
-- the blocks identified in the EXPORT_NODES array. The row data is indexed by
-- x coordinate (with 80/4 = 20 entries), with the most significant bit of each
-- hex digit representing the first node. The first row is at y = yMin and
-- z = zMin, and they are ordered with y incrementing most often (so the second
-- row is at y = yMin+1, z = zMin). There will be exactly 80*80 = 6400 lines
-- with row data.
--
-- The file exported is in the world directory, named
-- "<prefix><bx>-<by>-<bz><suffix>", where <prefix> is FILE_PREFIX, <suffix>
-- is FILE_SUFFIX, and <bx>, <by>, and <bz> are the (minimum) x, y, and z
-- coordinates of the exported block, with negative values prefixed by a "m"
-- character rather than a minus sign. For example, with the default prefix of
-- "block_" and default suffix of ".mtb", exporting the block just
-- north/east/above the origin would write "block_0-0-0.mtb" and exporting the
-- one just south/west/below would write "block_m1-m1-m1.mtb". Each exported
-- block file is very close to 1 MB in size.
---- Configuration Data: Modify to customize behavior
local FILE_PREFIX = "block_";
local FILE_SUFFIX = ".mtb";
local EXPORT_NODES = { "wool:white", "wool:red", "wool:green", "wool:blue" };
---- End Configuration Data
local MOD_NAME = minetest.get_current_modname();
if #EXPORT_NODES > 255 then
error(MOD_NAME .. ": too many export node names");
end
local contentIdExported;
do
local EXPORT_MAP = nil;
contentIdExported = function(cid)
if not EXPORT_MAP then
EXPORT_MAP = {};
for _, name in ipairs(EXPORT_NODES) do
local cid = minetest.get_content_id(name);
EXPORT_MAP[cid] = true;
end
end
return EXPORT_MAP[cid] or false;
end;
end
local function fileName(pos)
local xs = math.floor(pos.x);
local ys = math.floor(pos.y);
local zs = math.floor(pos.z);
if xs >= 0 then xs = tostring(xs); else xs = "m" .. tostring(-xs); end
if ys >= 0 then ys = tostring(ys); else ys = "m" .. tostring(-ys); end
if zs >= 0 then zs = tostring(zs); else zs = "m" .. tostring(-zs); end
return FILE_PREFIX .. xs .. "-" .. ys .. "-" .. zs .. FILE_SUFFIX;
end
local function toHexDigit(value)
value = math.floor(value) % 16;
return string.format("%x", value);
end
local function exportBlock(pos)
local bx = 80 * math.floor(pos.x / 80);
local by = 80 * math.floor(pos.y / 80);
local bz = 80 * math.floor(pos.z / 80);
local bmin = { x = bx, y = by, z = bz };
local bmax = { x = bx + 79, y = by + 79, z = bz + 79 };
local vm = minetest.get_voxel_manip();
bmin, bmax = vm:read_from_map(bmin, bmax);
local data = vm:get_data();
local va = VoxelArea:new({ MinEdge = bmin, MaxEdge = bmax });
local fname = fileName(bmin);
local fpath = minetest.get_worldpath() .. "/" .. fname;
local file, emsg = io.open(fpath, "w");
if not file then error(emsg); end
file:write(bx .. "," .. by .. "," .. bz .. "\n");
for zi = 0, 79 do
for yi = 0, 79 do
for xdi = 0, 79, 4 do
local bitMap = 0;
for xi = 0, 3 do
local pos = { x = bx + xdi + xi, y = by + yi, z = bz + zi };
bitMap = 2*bitMap;
if va:containsp(pos) then
local cid = data[va:indexp(pos)];
if contentIdExported(cid) then
bitMap = bitMap + 1;
end
end
end
file:write(toHexDigit(bitMap));
end
file:write("\n");
end
end
file:flush();
file:close();
return fname;
end
minetest.register_privilege(
"export",
{
description = "Allows exporting of data to files",
give_to_singleplayer = true
});
minetest.register_chatcommand(
"exportblock",
{
params = "",
description = "Exports your current 80x80x80 node block to a file",
privs = { export = true },
func =
function(name, paramStr)
local player = minetest.get_player_by_name(name);
local fname = exportBlock(player:getpos());
return true, "current block exported to " .. fname;
end
});
-- Block Export [blockexport] mod. All code is WTFPL.
-- Author: prestidigitator (as registered on forum.minetest.net)
--
-- This mod defines a new chat command "/exportblock" which writes 3D node data
-- of the player's current 80x80x80 node block to a file. This chat command
-- requires the (new) "export" privilege.
--
-- The data is expoted in Wavefront OBJ format
--
-- The file exported is in the world directory, named
-- "<prefix><bx>-<by>-<bz><suffix>", where <prefix> is FILE_PREFIX, <suffix>
-- is FILE_SUFFIX, and <bx>, <by>, and <bz> are the (minimum) x, y, and z
-- coordinates of the exported block, with negative values prefixed by a "m"
-- character rather than a minus sign. For example, with the default prefix of
-- "block_" and default suffix of ".obj", exporting the block just
-- north/east/above the origin would write "block_0-0-0.obj" and exporting the
-- one just south/west/below would write "block_m1-m1-m1.obj".
---- Configuration Data: Modify to customize behavior
local FILE_PREFIX = "block_";
local FILE_SUFFIX = ".obj";
local EXPORT_NODES = { "wool:white", "wool:red", "wool:green", "wool:blue" };
---- End Configuration Data
Basis =
{
localToGlobal = function(self, pos)
return { [self.e] = pos.x, [self.n] = pos.y, [self.u] = pos.z };
end,
globalToLocal = function(self, pos)
return { x = pos[self.e], y = pos[self.n], z = pos[self.u] };
end
};
setmetatable(
Basis,
{
__call = function(class, up)
local e, n;
if up == "x" then
e, n = "y", "z";
elseif up == "y" then
e, n = "z", "x";
elseif up == "z" then
e, n = "x", "y";
else
error("illegal basis direction");
end
return setmetatable({ e = e, n = n, u = up }, { __index = class });
end
});
local function fileName(x, y, z)
local xs = math.floor(x);
local ys = math.floor(y);
local zs = math.floor(z);
if xs >= 0 then xs = tostring(xs); else xs = "m" .. tostring(-xs); end
if ys >= 0 then ys = tostring(ys); else ys = "m" .. tostring(-ys); end
if zs >= 0 then zs = tostring(zs); else zs = "m" .. tostring(-zs); end
return FILE_PREFIX .. xs .. "-" .. ys .. "-" .. zs .. FILE_SUFFIX;
end
local isCidExported;
do
local exportMap = nil;
isCidExported = function(cid)
if not exportMap then
exportMap = {};
for _, name in ipairs(EXPORT_NODES) do
local cid = minetest.get_content_id(name);
exportMap[cid] = true;
end
end
return exportMap[cid] or false;
end;
end
local function hashVert(pos)
return (pos.x or 0) + 80*(pos.y or 0) + 6400*(pos.z or 0);
end
local function getObjData(xMin, yMin, zMin, xMax, yMax, zMax)
local verts = {};
local quads = {};
local vertMap = {};
local function getRowData(basis, xMin, xMax, y, z)
local vm = minetest.get_voxel_manip();
local pMin = basis:localToGlobal({ x = xMin, y = y, z = z - 0.5 });
local pMax = basis:localToGlobal({ x = xMax, y = y, z = z + 0.5 });
pMin, pMax = vm:read_from_map(pMin, pMax);
local data = vm:get_data();
local va = VoxelArea:new({ MinEdge = pMin, MaxEdge = pMax });
local segs = {};
local start, wasUp = nil, false;
for x = xMin, xMax do
local pL = basis:localToGlobal({ x = x, y = y, z = z - 0.5 });
local pH = basis:localToGlobal({ x = x, y = y, z = z + 0.5 });
local haveL = va:containsp(pL) and isCidExported(data[va:indexp(pL)]);
local haveH = va:containsp(pH) and isCidExported(data[va:indexp(pH)]);
local on, up = (haveL ~= haveH), haveH;
if on then
if not start then
start, wasUp = x, up;
elseif up ~= wasUp then
segs[#segs + 1] = { xs = start, xe = x-1, ys = y, up = wasUp };
start, wasUp = x, up;
end
elseif start then
segs[#segs + 1] = { xs = start, xe = x-1, ys = y, up = wasUp };
start = nil;
end
end
if start then segs[#segs + 1] = { xs = start, xe = xMax, ys = y }; end
return segs;
end
local function vertexIndex(basis, pos)
local vv = basis:localToGlobal(pos);
local vh = hashVert(vv);
local vlist = vertMap[vh];
if vlist then
for v, vi in pairs(vlist) do
if v.x == vv.x and v.y == vv.y and v.z == vv.z then
return vi;
end
end
else
vlist = {};
vertMap[vh] = vlist;
end
local vi = #verts + 1;
verts[vi] = vv;
vlist[vv] = vi;
return vi;
end
local function drawRect(basis, xs, ys, xe, ye, z)
local vi1 = vertexIndex(basis, { x = xs - 0.5, y = ys - 0.5, z = z });
local vi2 = vertexIndex(basis, { x = xe + 0.5, y = ys - 0.5, z = z });
local vi3 = vertexIndex(basis, { x = xe + 0.5, y = ye + 0.5, z = z });
local vi4 = vertexIndex(basis, { x = xs - 0.5, y = ye + 0.5, z = z });
quads[#quads + 1] = { vi1, vi2, vi3, vi4 };
end
local function drawRects(basis, prevRow, nextRow, y, z)
local nri = 1;
local nrSeg = nextRow[nri];
for _, prSeg in ipairs(prevRow) do
while nrSeg and nrSeg.xe < prSeg.xs do
nri = nri + 1;
nrSeg = nextRow[nri];
end
if nrSeg and
(nrSeg.xs == prSeg.xs) and
(nrSeg.xe == prSeg.xe) and
(nrSeg.up == prSeg.up) then
nrSeg.ys = prSeg.ys;
else
drawRect(basis, prSeg.xs, prSeg.ys, prSeg.xe, y, z);
end
end
end
local function drawSlice(basis, xMin, yMin, xMax, yMax, z)
local nextRow = getRowData(basis, xMin, xMax, yMin, z);
for y = yMin+1, yMax do
local prevRow = nextRow;
nextRow = getRowData(basis, xMin, xMax, y, z);
drawRects(basis, prevRow, nextRow, y-1, z);
end
drawRects(basis, nextRow, {}, yMax, z);
end
local function drawSlices(basis, xMin, yMin, zMin, xMax, yMax, zMax)
for z = zMin - 0.5, zMax + 0.5 do
drawSlice(basis, xMin, yMin, xMax, yMax, z);
end
end
for _, up in ipairs({ "x", "y", "z" }) do
local basis = Basis(up);
local pMin = basis:globalToLocal({ x = xMin, y = yMin, z = zMin });
local pMax = basis:globalToLocal({ x = xMax, y = yMax, z = zMax });
drawSlices(basis, pMin.x, pMin.y, pMin.z, pMax.x, pMax.y, pMax.z);
end
return verts, quads;
end
local function exportBlock(pos)
local xMin = 80 * math.floor(pos.x / 80);
local yMin = 80 * math.floor(pos.y / 80);
local zMin = 80 * math.floor(pos.z / 80);
local xMax = xMin + 79;
local yMax = yMin + 79;
local zMax = zMin + 79;
local fname = fileName(xMin, yMin, zMin);
local fpath = minetest.get_worldpath() .. "/" .. fname;
local file, emsg = io.open(fpath, "w");
if not file then error(emsg); end
local verts, quads = getObjData(xMin, yMin, zMin, xMax, yMax, zMax);
for _, v in ipairs(verts) do
file:write("v "..(v.x-xMin).." "..(v.y-yMin).." "..(v.z-zMin).."\n");
end
for _, f in ipairs(quads) do
file:write("f "..f[1].." "..f[2].." "..f[3].." "..f[4].."\n");
end
file:flush();
file:close();
return fname;
end
minetest.register_privilege(
"export",
{
description = "Allows exporting of data to files",
give_to_singleplayer = true
});
minetest.register_chatcommand(
"exportblock",
{
params = "",
description = "Exports your current 80x80x80 node block to a file",
privs = { export = true },
func =
function(name, paramStr)
local player = minetest.get_player_by_name(name);
local fname = exportBlock(player:getpos());
return true, "current block exported to " .. fname;
end
});
Users browsing this forum: No registered users and 28 guests