--[[ ngPlant-plugin : model-export menu-name : Export and launch Povray for Mac --]] --[[ Pov-ray file exporter & renderer for ngplant by Yorik van Havre - http://yorik.uncreated.net/ -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- Change et adapted for Apple Macintosh by louis bellotto - November 2016 - Remove options dialog. - Check for file extension .pov - Correct bug if images files are jpeg/jpg with correct syntax in PovRay. - Add cosmetics format en pobray sdl. - Launch Povray with exported file at the end of process -------------------------------------------------------------------------------- Feel free to contact me for any bugs or proposals : louisbel@free.fr -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ========== USAGE ============== This file must be placed in the ngPlant plugins directory. Then, an entry will appear in ngPlant File -> Export menu. For the plugin to work, povray must be installed on your system, and be available from the command line: typing: povray in terminal must work (it shows a list of povray options). On Debian/Ubuntu systems, installing the povray package is enough, on windows, you must maybe add the povray path to your search path. Another important thing, by default, povray is not allowed to access all your directory structure. If you want to use textures, you'll probably need to grant povray normal access to your files. For that, you must edit your povray.conf file and change File I/O Security to none or read-only. ====== BEGIN GPL LICENSE BLOCK ===== This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ===== END GPL LICENSE BLOCK ===== --]] function VisibleGroupsIter(Model) local IntGroupIndex = 0 local VisGroupIndex = 0 local GroupCount = Model:GetGroupCount() return function () local LODLevel = GetCurrentLOD() IntGroupIndex = IntGroupIndex + 1 while IntGroupIndex <= GroupCount do local Group = Model:GetGroup(IntGroupIndex) local MinLOD,MaxLOD MinLOD,MaxLOD = Group:GetLODVisRange() if (ExportHiddenGroups or (not Group:IsHidden())) and (ExportOutVisRangeGroups or ((LODLevel >= MinLOD) and (LODLevel <= MaxLOD))) then VisGroupIndex = VisGroupIndex + 1 return VisGroupIndex,Group else IntGroupIndex = IntGroupIndex + 1 end end return nil end end function ExportPovFile(PovFileName,lightInt) PovFile = io.open(PovFileName,"w") PovFile:write("// ----------------------------------------------------------------------------------------------------\n") PovFile:write("//\tPovray's file exported from NGPlant\n") PovFile:write("//\tYorik van Havre - http://yorik.orgfree.com\n") PovFile:write("//\n//\tModified version by louis bellotto - louisbel@free.fr\n") PovFile:write("// ----------------------------------------------------------------------------------------------------\n") PovFile:write("\n\n\n") -- global settings --------------------------------------------------------- PovFile:write(string.format("global_settings {\n\tambient_light rgb <%f,%f,%f>\n\tassumed_gamma %f\n\t}\n",0.86,1.00,1.10,1.00)) -- camera setup ------------------------------------------------------------ MinX,MinY,MinZ,MaxX,MaxY,MaxZ = PlantModel:GetBoundingBox() PlantLength = (MaxX-MinX) PlantHeight = (MaxY-MinY) if PlantHeight >= PlantLength then PovFile:write("\n\n// --- High plant\n") camAxis = PlantHeight/2+2.5 camY = PlantHeight/2 else camAxis = PlantLength/2+2.5 camY = MinY+PlantLength/2 end PovFile:write(string.format("// --- bounding box : from <%f, %f, %f> to <%f, %f, %f>\n\n\n",MinX,MinY,MinZ,MaxX,MaxY,MaxZ)) PovFile:write(string.format("#declare objectMin = <%f, %f, %f>;\n",MinX,MinY,MinZ)) PovFile:write(string.format("#declare objectMax = <%f, %f, %f>;\n",MaxX,MaxY,MaxZ)) PovFile:write(string.format("#declare LookAtCenter = objectMin + (objectMax - objectMin)*0.50;\n\n\n")) camX = MaxX-PlantLength/2 PovFile:write(string.format("camera {\n\torthographic\n\tright %f\n\tup %f\n\tlocation <%f , %f ,-10>\n\tlook_at <%f , %f , 0.0>\n\t}\n\n\n",camAxis,camAxis,camX,camY,camX,camY)) -- light setup ------------------------------------------------------------- lightX = 150 -- if lightDir == "Right" then -- lightX = -150 -- end PovFile:write(string.format("light_source {\n\t<%f,250,-250>\n\tcolor rgb <%f,%f,%f>\n\t}\n\n\n",lightX,0.97,0.95,0.70)) VertexIndexOffset = 1 NormalIndexOffset = 1 TexCoordIndexOffset = 1 ObjectCount = 1 for GroupIndex,Group in VisibleGroupsIter(PlantModel) do PovFile:write("\n// ----------------------------------------------------------------------------------------------------\n") PovFile:write(string.format("// Group object %d\n",ObjectCount)) PovFile:write("// ----------------------------------------------------------------------------------------------------\n") Material = Group:GetMaterial() PovFile:write("mesh2 {\n\tvertex_vectors {\n") Buffer = Group:GetVAttrBuffer(NGP_ATTR_VERTEX) VertexIndexStep = table.getn(Buffer) PovFile:write(string.format("\t\t%s,\n",table.getn(Buffer))) for i,v in ipairs(Buffer) do PovFile:write(string.format("\t\t< %f, %f, %f>,\n",v[1],v[2],v[3])) end PovFile:write("\t\t}\n") PovFile:write("\tnormal_vectors {\n") Buffer = Group:GetVAttrBuffer(NGP_ATTR_NORMAL) NormalIndexStep = table.getn(Buffer) PovFile:write(string.format("\t\t%s,\n",table.getn(Buffer))) for i,v in ipairs(Buffer) do PovFile:write(string.format("\t\t< %f, %f, %f>,\n",v[1],v[2],v[3])) end PovFile:write("\t\t}\n") PovFile:write("\tuv_vectors {\n") Buffer = Group:GetVAttrBuffer(NGP_ATTR_TEXCOORD0) TexCoordIndexStep = table.getn(Buffer) PovFile:write(string.format("\t\t%s,\n",table.getn(Buffer))) for i,v in ipairs(Buffer) do PovFile:write(string.format("\t\t<%f,%f>,\n",v[1],v[2])) end PovFile:write("\t\t}\n") Buffer = nil VertexIndexBuffer = Group:GetVAttrIndexBuffer(NGP_ATTR_VERTEX,true,VertexIndexOffset) NormalIndexBuffer = Group:GetVAttrIndexBuffer(NGP_ATTR_NORMAL,true,NormalIndexOffset) TexCoordIndexBuffer = Group:GetVAttrIndexBuffer(NGP_ATTR_TEXCOORD0,true,TexCoordIndexOffset) PrimitiveCount = table.getn(VertexIndexBuffer) facesCount = 0 for PrimitiveIndex = 1,PrimitiveCount do facesCount = facesCount + 1 if Group:GetPrimitiveType(PrimitiveIndex) == NGP_QUAD then facesCount = facesCount + 1 end end PovFile:write("\tface_indices {\n") PovFile:write(string.format("\t\t%s,\n",facesCount)) for PrimitiveIndex = 1,PrimitiveCount do vi = VertexIndexBuffer[PrimitiveIndex] if Group:GetPrimitiveType(PrimitiveIndex) == NGP_QUAD then PovFile:write(string.format("\t\t<%u,%u,%u>,\n",vi[1]-1,vi[2]-1,vi[3]-1)) PovFile:write(string.format("\t\t<%u,%u,%u>,\n",vi[1]-1,vi[3]-1,vi[4]-1)) else PovFile:write(string.format("\t\t<%u,%u,%u>,\n",vi[1]-1,vi[2]-1,vi[3]-1)) end end PovFile:write("\t\t}\n") PovFile:write("\tnormal_indices {\n") PovFile:write(string.format("\t\t%s,\n",facesCount)) for PrimitiveIndex = 1,PrimitiveCount do ni = NormalIndexBuffer[PrimitiveIndex] if Group:GetPrimitiveType(PrimitiveIndex) == NGP_QUAD then PovFile:write(string.format("\t\t<%u,%u,%u>,\n",ni[1]-1,ni[2]-1,ni[3]-1)) PovFile:write(string.format("\t\t<%u,%u,%u>,\n",ni[1]-1,ni[3]-1,ni[4]-1)) else PovFile:write(string.format("\t\t<%u,%u,%u>,\n",ni[1]-1,ni[2]-1,ni[3]-1)) end end PovFile:write("\t\t}\n") PovFile:write("\tuv_indices {\n") PovFile:write(string.format("\t\t%s,\n",facesCount)) for PrimitiveIndex = 1,PrimitiveCount do ti = TexCoordIndexBuffer[PrimitiveIndex] if Group:GetPrimitiveType(PrimitiveIndex) == NGP_QUAD then PovFile:write(string.format("\t\t<%u,%u,%u>,\n",ti[1]-1,ti[2]-1,ti[3]-1)) PovFile:write(string.format("\t\t<%u,%u,%u>,\n",ti[1]-1,ti[3]-1,ti[4]-1)) else PovFile:write(string.format("\t\t<%u,%u,%u>,\n",ti[1]-1,ti[2]-1,ti[3]-1)) end end PovFile:write("\t\t}\n") if Material.TexNames[NGP_TEX_DIFFUSE] then PovFile:write("\tuv_mapping\n") end PovFile:write("\ttexture {\n") PovFile:write(string.format("\t\tpigment {\n\t\t\trgb <%f,%f,%f>\n\t\t\t}\n",Material.Color.R,Material.Color.G,Material.Color.B)) if Material.TexNames[NGP_TEX_DIFFUSE] then TextureFileName = GetTextureFileName(Material.TexNames[NGP_TEX_DIFFUSE]) TextureFileExt = string.sub(TextureFileName,-3) if (TextureFileExt == "jpg") then TextureFileExt="jpeg" end PovFile:write(string.format("\t\tpigment {\n\t\t\timage_map {\n\t\t\t\t%s \"%s\"\n\t\t\t\t}\n\t\t\t}\n",TextureFileExt,GetTextureFileName(Material.TexNames[NGP_TEX_DIFFUSE]))) PovFile:write(string.format("\t\tnormal {\n\t\t\tbump_map {\n\t\t\t\t%s \"%s\"\n\t\t\t\t}\n\t\t\t}\n",TextureFileExt,GetTextureFileName(Material.TexNames[NGP_TEX_DIFFUSE]))) end PovFile:write("\t\t}\n") PovFile:write("\t}\n") ObjectCount = ObjectCount +1 end PovFile:write("\n// --- EOF --------------------------------------------------------------------------------------------\n") PovFile:close() end PovFileName = ShowFileSaveDialog("PovRAY scene file name :") if PovFileName then ExportHiddenGroups = true ExportOutVisRangeGroups = true if (string.sub(PovFileName,-3) ~= "pov") then PovFileName = PovFileName..(".pov") end ExportPovFile(PovFileName) execString="open "..PovFileName os.execute (execString) end