This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/yafray/intern/yafray_Render.cpp
Alfredo de Greef cf8d9fbb10 Added some backward compatibility with old yafray blendershader. Because of missing
parameters the material preset menu won't be as useful. Both glass presets will look the same
because there is no 'filter' parameter in the old yafray for instance.
So using the new Blender version with an old yafray version should work a bit better,
though the other way around, using the new yafray with an old blender version, will generally
not work as well.

I added a few extra things. In 'yafray' panel re-arranged some buttons, and added a new
button 'Clamp RGB'. This button will be enabled by default and helps to improve AA on
high contrast edges in the image. When using bokeh however, it is best to switch this off,
otherwise lens shaped highlights will be quite a bit less visible.

Changed the 'extinction' parameter name to the probably more correct term 'absorption',
though mathematically it works out the same. Also changed the behaviour of this color,
it no longer specifies a color that will be removed as I wrote in the previous commit,
but instead the actual color at one (blender) unit of distance. The 'Ds' (distance scale)
button below the color sliders controls the scaling of this unit distance.
What this means is that if you take the standard blender cube, which covers two units of
distance by default, setting the distance scale button to 2.0 will make sure that the color
you specified is exactly that color at that distance (provided the base color itself is white
of course, or 'filter' is 0, otherwise it will be filtered by the base color too).
Beyond this distance the color will get darker.

The glow option for point/soft/sphere lights has a new parameter 'GloOfs', or glow offset.
Setting this to a higher value then 0 will soften the central peak of the glow.

Another unreported bug fix: For xml export, when yafray failed to render the xml file
for some unknown reason, or because of other problems, the export code would still load
the previously rendered image, this causes problems however if the image resolution is
not the same as the current Blender buffer, and so could cause memory corruption or crashes.
This is now taken into account.

World image backgrounds now use the blender mapping settings as well, but only the
'AngMap', 'Sphere' and 'Tube' settings. But in yafray those last two, unlike Blender, cover
the whole view, not just the upper half, so is not really fully compatible with yafray.
So now you have to set one of these buttons too when loading a hdr lightprobe image.
btw, something I forgot to mention in previous commits is that the exposure control using
the texture brightness slider is no longer restricted to integer values. It is now a
floating point value, so you're not restricted to the 0 1 and 2 slider positions anymore,
anything in between will work too.

And finally, display updating is now more like Blender, using the mouse cursor as frame
counter for animation, etc.
2005-05-27 17:52:53 +00:00

215 lines
6.6 KiB
C++

//----------------------------------------------------------------------------------------------------
// YafRay export
//
// For anyone else looking at this, this was designed for a tabspacing of 2 (YafRay/Jandro standard :)
//----------------------------------------------------------------------------------------------------
#include "yafray_Render.h"
#include <math.h>
using namespace std;
void yafrayRender_t::clearAll()
{
all_objects.clear();
used_materials.clear();
used_textures.clear();
dupliMtx_list.clear();
dup_srcob.clear();
objectData.clear();
imagetex.clear();
imgtex_shader.clear();
}
bool yafrayRender_t::exportScene()
{
// get camera first, no checking should be necessary, all done by Blender
maincam_obj = G.scene->camera;
// use fixed lens for objects functioning as temporary camera (ctrl-0)
mainCamLens = 35.0;
if (maincam_obj->type==OB_CAMERA) mainCamLens=((Camera*)maincam_obj->data)->lens;
// recreate the scene as object data, as well as sorting the material & textures, ignoring duplicates
if (!getAllMatTexObs())
{
// error found, clear for next call
clearAll();
return false;
}
if (!initExport())
{
G.afbreek = 1;
clearAll();
return false;
}
// start actual data export
writeTextures();
writeMaterialsAndModulators();
writeAllObjects();
writeLamps();
hasworld = writeWorld();
writeCamera();
writeRender();
// clear for next call, before render to free some memory
clearAll();
if (!finishExport())
{
G.afbreek = 1; //stop render and anim if doing so
return false;
}
else return true;
}
// gets all unique face materials & textures,
// and sorts the facelist rejecting anything that is not a quad or tri,
// as well as associating them again with the original Object.
bool yafrayRender_t::getAllMatTexObs()
{
VlakRen* vlr;
// Blender does not include object which have total 0 alpha materials,
// however, the objects might have been included in the dupliMtx list,
// so this will cause a 'Duplilist non-empty...' error after going through the renderlist.
// To solve this, keep track of all render objects included sofar,
// and remove from dupliMtx_list if object not found.
// This should also help to solve some other yet undetected 'dupli..' errors,
// but on the other hand that could also hide the real problem of course...
map<string, Object*> renderobs;
for (int i=0;i<R.totvlak;i++) {
if ((i & 255)==0) vlr=R.blovl[i>>8]; else vlr++;
// ---- The materials & textures
// in this case, probably every face has a material assigned, which can be the default material,
// so checking that this is !0 is probably not necessary, but just in case...
Material* matr = vlr->mat;
if (matr) {
// The default assigned material seems to be nameless, no MA id, an empty string.
// Since this name is needed in yafray, make it 'blender_default'
if (strlen(matr->id.name)==0)
used_materials["blender_default"] = matr;
else
used_materials[matr->id.name] = matr;
// textures, all active channels
for (int m=0;m<MAX_MTEX;m++) {
if (matr->septex & (1<<m)) continue; // only active channels
MTex* mx = matr->mtex[m];
// if no mtex, ignore
if (mx==NULL) continue;
// if no tex, ignore
Tex* tx = mx->tex;
if (tx==NULL) continue;
short txtp = tx->type;
// if texture type not available in yafray, ignore
if ((txtp==0) ||
(txtp==TEX_MAGIC) ||
(txtp==TEX_PLUGIN) ||
(txtp==TEX_ENVMAP)) continue;
// if texture is stucci, only export if 'nor' enabled
if ((txtp==TEX_STUCCI) && !((mx->mapto & MAP_NORM) || (mx->maptoneg & MAP_NORM))) continue;
// In the case of an image texture, check that there is an actual image, otherwise ignore.
// Stupid error was here (...if (txtp & TEX_IMAGE)...),
// which happened to work sofar, but not anymore with the extended texture support..
if ((txtp==TEX_IMAGE) && (!tx->ima)) continue;
used_textures[tx->id.name] = mx;
}
}
// Make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later.
// ignore null object pointers.
// Also make list of facetexture images (material 'TexFace').
if (vlr->ob) {
int nv = 0; // number of vertices
if (vlr->v4) nv=4; else if (vlr->v3) nv=3;
if (nv) {
renderobs[vlr->ob->id.name] = vlr->ob;
all_objects[vlr->ob].push_back(vlr);
if (vlr->tface) {
Image* fc_img = (Image*)vlr->tface->tpage;
if (fc_img) {
Material* fmat = vlr->mat;
// only save if TexFace enabled
if (fmat && (fmat->mode & MA_FACETEXTURE)) imagetex[fc_img].insert(fmat);
}
}
}
}
}
// now remove any objects from dupliMtx_list which are not in the renderlist
for (map<string, vector<float> >::iterator dL=dupliMtx_list.begin();
dL!=dupliMtx_list.end();++dL)
{
string ro_name = dL->first;
if (renderobs.find(ro_name)==renderobs.end()) {
cout << "Object " << ro_name << " not in renderlist, removing from dupliMtx_list" << endl;
dL->second.clear();
dupliMtx_list.erase(ro_name);
}
}
// in case dupliMtx_list not empty, make sure that there is at least one source object
// in all_objects with the name given in dupliMtx_list
if (!dupliMtx_list.empty()) {
for (map<Object*, vector<VlakRen*> >::const_iterator obn=all_objects.begin();
obn!=all_objects.end();++obn)
{
Object* obj = obn->first;
string obname = obj->id.name;
if (dupliMtx_list.find(obname)!=dupliMtx_list.end()) dup_srcob[obname] = obj;
}
// if the name reference list is empty, return now, something was seriously wrong
if (dup_srcob.empty()) {
// error() doesn't work to well, when switching from Blender to console at least, so use stdout instead
cout << "ERROR: Duplilist non_empty, but no srcobs\n";
return false;
}
}
return true;
}
void yafrayRender_t::addDupliMtx(Object* obj)
{
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
dupliMtx_list[obj->id.name].push_back(obj->obmat[i][j]);
}
bool yafrayRender_t::objectKnownData(Object* obj)
{
// if object data already known, no need to include in renderlist, otherwise save object datapointer
if (objectData.find(obj->data)!=objectData.end()) {
Object* orgob = objectData[obj->data];
// first save original object matrix in dupliMtx_list, if not added yet
if (dupliMtx_list.find(orgob->id.name)==dupliMtx_list.end()) {
cout << "Added original matrix\n";
addDupliMtx(orgob);
}
// then save matrix of linked object in dupliMtx_list, using name of ORIGINAL object
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
dupliMtx_list[orgob->id.name].push_back(obj->obmat[i][j]);
return true;
}
// object not known yet
objectData[obj->data] = obj;
return false;
}