Minetest side script :
Your 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
-- FreeCAD exporting MOD - Minetest side
-- Copyright(C) 2014 - J. Aldo Gomes de Freitas Junior
-- GPLv2
-- Minetest side module
-- exporter proper
nodeexporter = {
-- Populate this array with a list of nodes that should be rendered
blockmapping = {
['default:dirt'] = 1,
['default:dirt_with_grass'] = 1
},
-- Exports a chunk of land starting at ax1, ay1, az1 and ending at ax2, ay2, az2
exportblocks = function(athis, afilename, ax1, ay1, az1, ax2, ay2, az2)
local destination = io.open(minetest.get_worldpath() .. "/" .. afilename, "w")
local x, y, z
local swapvar
-- Verify and swap inverted coordinates
if ax1 > ax2 then
swapvar = ax2
ax2 = ax1
ax1 = swapvar
end
if ay1 > ay2 then
swapvar = ay2
ay2 = ay1
ay1 = swapvar
end
if az1 > az2 then
swapvar = az2
az2 = az1
az1 = swapvar
end
-- Write map chunk size
destination:write((ax2 - ax1) .. '\n' .. (ay2 - ay1) .. '\n' .. (az2 - az1) .. '\n')
-- Write map data
for ly = ay1, ay2 do
for lx = ax1, ax2 do
for lz = az1, az2 do
local node = minetest.env:get_node({ x = lx, y = ly, z = lz })
local value = athis.blockmapping[node.name]
if value ~= nil then
destination:write(value .. '\n')
else
destination:write('0\n')
end
end
end
end
destination:close()
end
}
-- Register chat command
minetest.register_chatcommand(
"mapexport",
{
params = "filename x1 y1 z1 x2 y2 z2",
description = "Exports a piece of game map in a format that can be read by FreeCAD minetest importer plugin.",
privs = { },
func =
function(name, param)
paramlist = string.split(param, " ")
local filename = paramlist[1]
local x1 = tonumber(paramlist[2])
local y1 = tonumber(paramlist[3])
local z1 = tonumber(paramlist[4])
local x2 = tonumber(paramlist[5])
local y2 = tonumber(paramlist[6])
local z2 = tonumber(paramlist[7])
nodeexporter:exportblocks(filename, x1, y1, z1, x2, y2, z2)
return true, "Exported to " .. filename;
end
});
FreeCAD side script:
Your 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
# FreeCAD exporting MOD - Minetest side
# Copyright(C) 2014 - J. Aldo Gomes de Freitas Junior
# GPLv2
# FreeCAD side module
import Part, math
def makeCenter(x = 0, y = 0, z = 0):
return FreeCAD.Vector(x, y, z)
def makeRotation(x = 0, y = 0, z = 0):
return FreeCAD.Rotation(x, y, z)
def makePlacement(x, y, z, X, Y, Z):
return FreeCAD.Placement(makeCenter(x, y, z), makeRotation(X, Y, Z))
def importvolumefile(filename, xscale = 10, yscale = 10, zscale = 10):
cubes = []
sourcefile = open(filename)
xsize = int(float(sourcefile.readline()))
ysize = int(float(sourcefile.readline()))
zsize = int(float(sourcefile.readline()))
for yposition in range(1, ysize):
for xposition in range(1, xsize):
for zposition in range(1, zsize):
value = int(float(sourcefile.readline()))
if value > 0:
cube = Part.makeBox(zscale, xscale, yscale)
cube.Placement = makePlacement(xposition * xscale, yposition * yscale, zposition * zscale, 0, 0, 0)
cubes.append(cube)
sourcefile.close()
solid = Part.makeCompound(cubes)
return solid
# replace filename - needs a beter interface
map = importvolumefile("c:/minetest/minetest-0.4.10/worlds/aldo/teste.vol")
Part.show(map)
Already works in my computer. I can - if trully needed - use FreeCAD boolean operations to fuse all cubes into a single entity, but this is quite a costly operation.
TODO:
Minetest side - Add parameter handling and checking. Populate the mapping table. There are only two entries right now. (dirt and dirt with grass)
FreeCAD side - Add file selection interface. Change tile color by minetest mod mapping. Handle nodebox.
This is the result inside freecad:
https://www.dropbox.com/s/liznoix6ezkx9uy/freecad.png
To export a map piece from minetest :
Your 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
/minetest <filename> <x1> <y1> <z1> <x2> <y2> <z2>
To import into FreeCAD :
Edit this line:
Your 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
# replace filename - needs a beter interface
map = importvolumefile("c:/minetest/minetest-0.4.10/worlds/aldo/teste.vol")
"c:/minetest/minetest-0.4.10/worlds/aldo/teste.vol" is a fully qualified filename that points to a volume that i exported in my harddisk. Replace it with a correct fully qualified path name that points to the correct file inside your computer.
Cubes might happend to be mirrored/inverted, coords might happen to be rotated (x vs y, x vs z etc). Those small bugs need to be fixed by tests. First thing is to pupulate the "blockmapping" array in the lua source code. The blockmap has a simple structure, ["<registerednodename>"] = <value>. Any value above 0 will become a block inside minetest. The is scale is so that each block (node) inside minetest becomes a 10mm x 10mm x 10mm cube inside freecad. The scale can be changed by adding scale values to the importvolumefile call.
Your 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
p = importvolumefile(<filename>, [<xscale>, [<yscale>, [<zscale>]]])
How to use :
Export a map area from inside minetest. The file will be saved into the world directory. Open that file in FreeCAD using the macro provided. Export the file in a format that can be understood by Slic3r. Slice it, and send to printer. Later i can provide a better interface for both freecad and minetest. But now it works and thats sufficient.