Minetest side script :
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
});
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)
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 :
Code: Select all
/minetest <filename> <x1> <y1> <z1> <x2> <y2> <z2>
Edit this line:
Code: Select all
# replace filename - needs a beter interface
map = importvolumefile("c:/minetest/minetest-0.4.10/worlds/aldo/teste.vol")
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.
Code: Select all
p = importvolumefile(<filename>, [<xscale>, [<yscale>, [<zscale>]]])
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.