---- luapstricks-plugin-pstsolides3d.lua
-- Copyright 2021--2023 Marcel Krüger <
[email protected]>
-- Converted from PostScript in pst-solides3d.pro
--
-- This work may be distributed and/or modified under the
-- conditions of the LaTeX Project Public License, either version 1.3
-- of this license or (at your option) any later version.
-- The latest version of this license is in
--
http://www.latex-project.org/lppl.txt
-- and version 1.3 or later is part of all distributions of LaTeX
-- version 2005/12/01 or later.
--
-- This work has the LPPL maintenance status `maintained'.
--
-- The Current Maintainer of this work is M. Krüger
--
-- This work consists of the files luapstricks.lua and luapstricks-plugin-pstmarble.lua
local loader, version, plugininterface = ...
assert(loader == 'luapstricks' and version == 0)
local push = plugininterface.push
local pop = plugininterface.pop
local pop_array = plugininterface.pop_array
local pop_num = plugininterface.pop_num
local pop_proc = plugininterface.pop_proc
local pop_string = pop
local exec = plugininterface.exec
local newtable = lua.newtable
local abs = math.abs
local exp = math.exp
local cos = math.cos
local sin = math.sin
local rad = math.rad
local max = math.max
local deg = math.deg
local atan = math.atan
--[[
-- Solides are represented as four element arrays containing:
-- {
-- Sommets, Faces, Colors_Faces, InOut_Table
-- }
--]]
local function issolid(candidate)
if type(candidate) ~= 'table' then return false end
local kind = candidate.kind
if kind == 'executable' then return issolid(candidate.value) end
if kind ~= 'array' then return false end
candidate = candidate.value
if #candidate ~= 4 then return false end
local sommets = candidate[1]
if type(sommets) ~= 'table' then return false end
if sommets.kind == 'executable' then
sommets = sommets.value
if type(sommets) ~= 'table' then return false end
end
if sommets.kind ~= 'array' then return false end
local faces = candidate[2]
if type(faces) ~= 'table' then return false end
if faces.kind == 'executable' then
faces = faces.value
if type(faces) ~= 'table' then return false end
end
if faces.kind ~= 'array' then return false end
local faceColors = candidate[3]
if type(faceColors) ~= 'table' then return false end
if faceColors.kind == 'executable' then
faceColors = faceColors.value
if type(faceColors) ~= 'table' then return false end
end
if faceColors.kind ~= 'array' then return false end
local IO = candidate[4]
if type(IO) ~= 'table' then return false end
if IO.kind == 'executable' then
IO = IO.value
if type(IO) ~= 'table' then return false end
end
if IO.kind ~= 'array' then return false end
IO = IO.value
if #IO ~= 4 then return false end
return type(IO[1]) == 'number' and type(IO[2]) == 'number' and type(IO[3]) == 'number' and type(IO[4]) == 'number'
end
local function nullsolid(candidate)
assert(issolid(candidate), 'Error type argument dans "nullsolid"')
return #candidate[1].value == 0
end
local function getp3d(sommets, indices)
-- TODO
error'TODO'
end
local function solidgetsommetsface(solid, i)
assert(issolid(solid), 'Error : mauvais type d argument dans solidgetsommetsface')
local table_sommets = solid.value[1].value
local table_faces = solid.value[2].value
local table_indices = table_faces[i + 1]
local result = {}
for j=1, #table_indices do
result[j] = getp3d(table_sommets, table_indices[j])
end
return result
end
local function isobarycentre3d(face)
-- TODO
error'TODO'
end
local function solidcentreface(solid, i)
return isobarycentre3d(solidgetsommetsface(solid, i))
end
local function drawsolid(solid, order, peintrealgorithme)
if nullsolid(solid) then return end
local sommets = solid[1].value
local n = #sommets // 3
local faces = solid[2].value
if not order then
order = {}
if peintrealgorithme then
for i = 1, #faces do
local face = solidcentreface(solid, i-1)
order[i] = face GetCamPos distance3d
end
order = order doublequicksort pop reverse
else
for i = 1, #faces do
order[i] = i - 1
end
order = {kind = 'array', value = order}
end
end
0 1 faces length 1 sub {
/k exch def
/i order k get def
gsave
solid i solidfacevisible? {
solid i dessinefacevisible
} if
grestore
} for
aretescachees {
0 1 F length 1 sub {
/k exch def
/i order k get def
gsave
solid i solidfacevisible? not {
solid i dessinefacecachee
} if
grestore
} for
} if
end
return {
drawsolid = function()
local order
local solid = pop()
if not issolid(solid) then
solid, order = pop(), solid
assert(issolid(solid), 'Error : mauvais type d argument dans drawsolid')
end
return drawsolid(solid, order)
end,
issolid = function()
push(issolid(pop()))
end,
}, 0