control animation export
parent
f098c3c455
commit
f67566ffcc
|
@ -98,20 +98,12 @@
|
||||||
|
|
||||||
<!-- LUMINAIRE Element -->
|
<!-- LUMINAIRE Element -->
|
||||||
<xsd:complexType name="luminaire">
|
<xsd:complexType name="luminaire">
|
||||||
<xsd:complexContent>
|
|
||||||
<xsd:extension base="object">
|
|
||||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
|
||||||
<xsd:element name="texture" type="texture"/>
|
|
||||||
<xsd:element name="luminaire" type="luminaire"/>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:extension>
|
|
||||||
</xsd:complexContent>
|
|
||||||
<xsd:complexContent>
|
<xsd:complexContent>
|
||||||
<xsd:extension base="objectBase">
|
<xsd:extension base="objectBase">
|
||||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
<xsd:group ref="objectGroup"/>
|
<xsd:group ref="objectGroup"/>
|
||||||
<xsd:element name="integrator" type="integrator"/>
|
<xsd:element name="texture" type="texture"/>
|
||||||
<xsd:element name="sampler" type="object"/>
|
<xsd:element name="luminaire" type="luminaire"/>
|
||||||
</xsd:choice>
|
</xsd:choice>
|
||||||
</xsd:extension>
|
</xsd:extension>
|
||||||
</xsd:complexContent>
|
</xsd:complexContent>
|
||||||
|
|
|
@ -1621,20 +1621,22 @@ void GeometryConverter::convertCollada(const fs::path &inputFile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
domLibrary_animations_Array &libraryAnimations = document->getLibrary_animations_array();
|
if (m_importAnimations) {
|
||||||
for (size_t i=0; i<libraryAnimations.getCount(); ++i) {
|
domLibrary_animations_Array &libraryAnimations = document->getLibrary_animations_array();
|
||||||
domAnimation_Array &animations = libraryAnimations[i]->getAnimation_array();
|
for (size_t i=0; i<libraryAnimations.getCount(); ++i) {
|
||||||
for (size_t j=0; j<animations.getCount(); ++j)
|
domAnimation_Array &animations = libraryAnimations[i]->getAnimation_array();
|
||||||
loadAnimation(ctx, *animations[j]);
|
for (size_t j=0; j<animations.getCount(); ++j)
|
||||||
|
loadAnimation(ctx, *animations[j]);
|
||||||
|
}
|
||||||
|
mergeRotations(ctx);
|
||||||
}
|
}
|
||||||
mergeRotations(ctx);
|
|
||||||
|
|
||||||
for (size_t i=0; i<nodes.getCount(); ++i)
|
for (size_t i=0; i<nodes.getCount(); ++i)
|
||||||
computeRefCounts(ctx, *nodes[i]);
|
computeRefCounts(ctx, *nodes[i]);
|
||||||
|
|
||||||
for (size_t i=0; i<nodes.getCount(); ++i)
|
for (size_t i=0; i<nodes.getCount(); ++i)
|
||||||
loadNode(ctx, Transform(), *nodes[i], "");
|
loadNode(ctx, Transform(), *nodes[i], "");
|
||||||
|
|
||||||
for (AnimationMap::iterator it = ctx.animations.begin();
|
for (AnimationMap::iterator it = ctx.animations.begin();
|
||||||
it != ctx.animations.end(); ++it)
|
it != ctx.animations.end(); ++it)
|
||||||
it->second->decRef();
|
it->second->decRef();
|
||||||
|
|
|
@ -195,9 +195,11 @@ void GeometryConverter::convert(const fs::path &inputFile,
|
||||||
if (id != "" && nodeMap.find(id) != nodeMap.end()) {
|
if (id != "" && nodeMap.find(id) != nodeMap.end()) {
|
||||||
DOMNode *node = nodeMap[id], *parent = node->getParentNode();
|
DOMNode *node = nodeMap[id], *parent = node->getParentNode();
|
||||||
if (strcmp(nodeName, "append") == 0) {
|
if (strcmp(nodeName, "append") == 0) {
|
||||||
DOMNode *node = nodeMap[id];
|
|
||||||
for (DOMNode *child2 = child->getFirstChild(); child2 != 0; child2=child2->getNextSibling())
|
for (DOMNode *child2 = child->getFirstChild(); child2 != 0; child2=child2->getNextSibling())
|
||||||
node->insertBefore(doc->importNode(child2, true), NULL);
|
node->insertBefore(doc->importNode(child2, true), NULL);
|
||||||
|
} else if (strcmp(nodeName, "prepend") == 0) {
|
||||||
|
for (DOMNode *child2 = child->getFirstChild(); child2 != 0; child2=child2->getNextSibling())
|
||||||
|
node->insertBefore(doc->importNode(child2, true), node->getFirstChild());
|
||||||
} else if (parent == insertBeforeNode->getParentNode()) {
|
} else if (parent == insertBeforeNode->getParentNode()) {
|
||||||
parent->removeChild(node);
|
parent->removeChild(node);
|
||||||
docRoot->insertBefore(doc->importNode(child, true), insertBeforeNode);
|
docRoot->insertBefore(doc->importNode(child, true), insertBeforeNode);
|
||||||
|
@ -212,10 +214,13 @@ void GeometryConverter::convert(const fs::path &inputFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMLSSerializer *serializer = impl->createLSSerializer();
|
DOMLSSerializer *serializer = impl->createLSSerializer();
|
||||||
DOMConfiguration *serConf(serializer->getDomConfig());
|
DOMConfiguration *serConf = serializer->getDomConfig();
|
||||||
DOMLSOutput *output = impl->createLSOutput();
|
|
||||||
serConf->setParameter(XMLUni::fgDOMErrorHandler, &errorHandler);
|
serConf->setParameter(XMLUni::fgDOMErrorHandler, &errorHandler);
|
||||||
serConf->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
|
if (serConf->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true))
|
||||||
|
serConf->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
|
||||||
|
if (serConf->canSetParameter(XMLUni::fgDOMWRTXercesPrettyPrint, true))
|
||||||
|
serConf->setParameter(XMLUni::fgDOMWRTXercesPrettyPrint, true);
|
||||||
|
DOMLSOutput *output = impl->createLSOutput();
|
||||||
XMLFormatTarget *target = new LocalFileFormatTarget(outputFile.file_string().c_str());
|
XMLFormatTarget *target = new LocalFileFormatTarget(outputFile.file_string().c_str());
|
||||||
output->setByteStream(target);
|
output->setByteStream(target);
|
||||||
serializer->write(doc, output);
|
serializer->write(doc, output);
|
||||||
|
|
|
@ -28,6 +28,8 @@ public:
|
||||||
m_xres = m_yres = -1;
|
m_xres = m_yres = -1;
|
||||||
m_filmType = "exrfilm";
|
m_filmType = "exrfilm";
|
||||||
m_packGeometry = true;
|
m_packGeometry = true;
|
||||||
|
m_importMaterials = true;
|
||||||
|
m_importAnimations = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(const fs::path &inputFile,
|
void convert(const fs::path &inputFile,
|
||||||
|
@ -42,6 +44,7 @@ public:
|
||||||
inline void setResolution(int xres, int yres) { m_xres = xres; m_yres = yres; }
|
inline void setResolution(int xres, int yres) { m_xres = xres; m_yres = yres; }
|
||||||
inline void setPackGeometry(bool packGeometry) { m_packGeometry = packGeometry; }
|
inline void setPackGeometry(bool packGeometry) { m_packGeometry = packGeometry; }
|
||||||
inline void setImportMaterials(bool importMaterials) { m_importMaterials = importMaterials; }
|
inline void setImportMaterials(bool importMaterials) { m_importMaterials = importMaterials; }
|
||||||
|
inline void setImportAnimations(bool importAnimations) { m_importAnimations = importAnimations; }
|
||||||
inline void setFilmType(const std::string &filmType) { m_filmType = filmType; }
|
inline void setFilmType(const std::string &filmType) { m_filmType = filmType; }
|
||||||
inline const fs::path &getFilename() const { return m_filename; }
|
inline const fs::path &getFilename() const { return m_filename; }
|
||||||
private:
|
private:
|
||||||
|
@ -52,7 +55,8 @@ private:
|
||||||
const fs::path &textureDirectory,
|
const fs::path &textureDirectory,
|
||||||
const fs::path &meshesDirectory);
|
const fs::path &meshesDirectory);
|
||||||
public:
|
public:
|
||||||
bool m_srgb, m_mapSmallerSide, m_importMaterials;
|
bool m_srgb, m_mapSmallerSide;
|
||||||
|
bool m_importMaterials, m_importAnimations;
|
||||||
int m_xres, m_yres;
|
int m_xres, m_yres;
|
||||||
fs::path m_filename, m_outputDirectory;
|
fs::path m_filename, m_outputDirectory;
|
||||||
std::string m_filmType;
|
std::string m_filmType;
|
||||||
|
|
|
@ -56,6 +56,7 @@ void help() {
|
||||||
<< " -v Be more verbose" << endl << endl
|
<< " -v Be more verbose" << endl << endl
|
||||||
<< " -s Assume that colors are in sRGB space." << endl << endl
|
<< " -s Assume that colors are in sRGB space." << endl << endl
|
||||||
<< " -m Map the larger image side to the full field of view" << endl << endl
|
<< " -m Map the larger image side to the full field of view" << endl << endl
|
||||||
|
<< " -z Import animations" << endl << endl
|
||||||
<< " -y Don't pack all geometry data into a single file" << endl << endl
|
<< " -y Don't pack all geometry data into a single file" << endl << endl
|
||||||
<< " -n Don't import any materials (an adjustments file will be necessary)" << endl << endl
|
<< " -n Don't import any materials (an adjustments file will be necessary)" << endl << endl
|
||||||
<< " -l <type> Override the type of film (e.g. 'exrfilm', 'pngfilm', ..)" << endl << endl
|
<< " -l <type> Override the type of film (e.g. 'exrfilm', 'pngfilm', ..)" << endl << endl
|
||||||
|
@ -70,12 +71,12 @@ int colladaMain(int argc, char **argv) {
|
||||||
std::string filmType = "exrfilm";
|
std::string filmType = "exrfilm";
|
||||||
FileResolver *fileResolver = Thread::getThread()->getFileResolver();
|
FileResolver *fileResolver = Thread::getThread()->getFileResolver();
|
||||||
ELogLevel logLevel = EInfo;
|
ELogLevel logLevel = EInfo;
|
||||||
bool packGeometry = true;
|
bool packGeometry = true, importMaterials = true,
|
||||||
bool importMaterials = true;
|
importAnimations = false;
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
|
|
||||||
while ((optchar = getopt(argc, argv, "snvyhmr:a:l:")) != -1) {
|
while ((optchar = getopt(argc, argv, "snzvyhmr:a:l:")) != -1) {
|
||||||
switch (optchar) {
|
switch (optchar) {
|
||||||
case 'a': {
|
case 'a': {
|
||||||
std::vector<std::string> paths = tokenize(optarg, ";");
|
std::vector<std::string> paths = tokenize(optarg, ";");
|
||||||
|
@ -92,6 +93,9 @@ int colladaMain(int argc, char **argv) {
|
||||||
case 'n':
|
case 'n':
|
||||||
importMaterials = false;
|
importMaterials = false;
|
||||||
break;
|
break;
|
||||||
|
case 'z':
|
||||||
|
importAnimations = true;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
logLevel = EDebug;
|
logLevel = EDebug;
|
||||||
break;
|
break;
|
||||||
|
@ -132,6 +136,7 @@ int colladaMain(int argc, char **argv) {
|
||||||
converter.setSRGB(srgb);
|
converter.setSRGB(srgb);
|
||||||
converter.setResolution(xres, yres);
|
converter.setResolution(xres, yres);
|
||||||
converter.setImportMaterials(importMaterials);
|
converter.setImportMaterials(importMaterials);
|
||||||
|
converter.setImportAnimations(importAnimations);
|
||||||
converter.setMapSmallerSide(mapSmallerSide);
|
converter.setMapSmallerSide(mapSmallerSide);
|
||||||
converter.setPackGeometry(packGeometry);
|
converter.setPackGeometry(packGeometry);
|
||||||
converter.setFilmType(filmType);
|
converter.setFilmType(filmType);
|
||||||
|
|
|
@ -215,6 +215,17 @@ class MtsAdjustments:
|
||||||
self.out.write('\t\t</shape>\n')
|
self.out.write('\t\t</shape>\n')
|
||||||
self.out.write('\n')
|
self.out.write('\n')
|
||||||
|
|
||||||
|
def exportCameraSettings(self, scene, camera):
|
||||||
|
if scene.mitsuba_integrator.motionblur:
|
||||||
|
frameTime = 1.0/scene.render.fps
|
||||||
|
shuttertime = scene.mitsuba_integrator.shuttertime
|
||||||
|
shutterOpen = (scene.frame_current - shuttertime/2) * frameTime
|
||||||
|
shutterClose = (scene.frame_current + shuttertime/2) * frameTime
|
||||||
|
self.out.write('\t<prepend id="%s-camera">\n' % translate_id(camera.name))
|
||||||
|
self.out.write('\t\t<float name="shutterOpen" value="%f"/>\n' % shutterOpen)
|
||||||
|
self.out.write('\t\t<float name="shutterClose" value="%f"/>\n' % shutterClose)
|
||||||
|
self.out.write('\t</prepend>\n')
|
||||||
|
|
||||||
def export(self, scene):
|
def export(self, scene):
|
||||||
idx = 0
|
idx = 0
|
||||||
self.writeHeader()
|
self.writeHeader()
|
||||||
|
@ -228,6 +239,8 @@ class MtsAdjustments:
|
||||||
self.exportMaterial(mat)
|
self.exportMaterial(mat)
|
||||||
if len(obj.data.materials) > 0 and obj.data.materials[0].mitsuba_emission.use_emission:
|
if len(obj.data.materials) > 0 and obj.data.materials[0].mitsuba_emission.use_emission:
|
||||||
self.exportEmission(obj)
|
self.exportEmission(obj)
|
||||||
|
elif obj.type == 'CAMERA':
|
||||||
|
self.exportCameraSettings(scene, obj)
|
||||||
idx = idx+1
|
idx = idx+1
|
||||||
self.writeFooter()
|
self.writeFooter()
|
||||||
|
|
||||||
|
|
|
@ -184,9 +184,11 @@ class EXPORT_OT_mitsuba(bpy.types.Operator):
|
||||||
|
|
||||||
MtsLog("MtsBlend: Launching mtsimport")
|
MtsLog("MtsBlend: Launching mtsimport")
|
||||||
try:
|
try:
|
||||||
process = subprocess.Popen(
|
command = [mtsimport_binary, '-r', '%dx%d' % (width, height),
|
||||||
[mtsimport_binary, '-r', '%dx%d' % (width, height),
|
'-n', '-l', 'pngfilm', mts_dae_file, mts_xml_file, mts_adj_file]
|
||||||
'-n', '-l', 'pngfilm', mts_dae_file, mts_xml_file, mts_adj_file],
|
if scene.mitsuba_integrator.motionblur:
|
||||||
|
command += ['-z']
|
||||||
|
process = subprocess.Popen(command,
|
||||||
env = env,
|
env = env,
|
||||||
cwd = mts_path
|
cwd = mts_path
|
||||||
)
|
)
|
||||||
|
|
|
@ -28,8 +28,13 @@ class mitsuba_integrator(declarative_property_group):
|
||||||
|
|
||||||
controls = [
|
controls = [
|
||||||
'type',
|
'type',
|
||||||
'sampleCount'
|
['motionblur',
|
||||||
|
'shuttertime']
|
||||||
]
|
]
|
||||||
|
|
||||||
|
visibility = {
|
||||||
|
'shuttertime': { 'motionblur': True }
|
||||||
|
}
|
||||||
|
|
||||||
properties = [
|
properties = [
|
||||||
{
|
{
|
||||||
|
@ -43,6 +48,24 @@ class mitsuba_integrator(declarative_property_group):
|
||||||
('path', 'Path tracer', 'path'),
|
('path', 'Path tracer', 'path'),
|
||||||
],
|
],
|
||||||
'save_in_preset': True
|
'save_in_preset': True
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'type': 'bool',
|
||||||
|
'attr': 'motionblur',
|
||||||
|
'name': 'Motion Blur',
|
||||||
|
'description': 'Should motion blur be enabled?',
|
||||||
|
'default' : False,
|
||||||
|
'save_in_preset': True
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'type': 'float',
|
||||||
|
'attr': 'shuttertime',
|
||||||
|
'name': 'Shutter time',
|
||||||
|
'description': 'Amount of time, for which the shutter remains open (measured in frames)',
|
||||||
|
'save_in_preset': True,
|
||||||
|
'min': 0,
|
||||||
|
'max': 100,
|
||||||
|
'default': 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
import bpy, copy
|
import bpy
|
||||||
from properties_material import MaterialButtonsPanel
|
from properties_material import MaterialButtonsPanel
|
||||||
|
|
||||||
from extensions_framework.ui import property_group_renderer
|
from extensions_framework.ui import property_group_renderer
|
||||||
|
@ -27,13 +27,20 @@ material_cache = {}
|
||||||
cached_spp = None
|
cached_spp = None
|
||||||
cached_depth = None
|
cached_depth = None
|
||||||
|
|
||||||
|
def copy(value):
|
||||||
|
if value == None or isinstance(value, str) or isinstance(value, bool) \
|
||||||
|
or isinstance(value, float) or isinstance(value, int):
|
||||||
|
return value
|
||||||
|
elif getattr(value, '__len__', False):
|
||||||
|
return list(value)
|
||||||
|
else:
|
||||||
|
raise Exception("Copy: don't know how to handle '%s'" % str(vlaue))
|
||||||
|
|
||||||
class mitsuba_material_base(MaterialButtonsPanel, property_group_renderer):
|
class mitsuba_material_base(MaterialButtonsPanel, property_group_renderer):
|
||||||
COMPAT_ENGINES = {'mitsuba'}
|
COMPAT_ENGINES = {'mitsuba'}
|
||||||
MTS_PROPS = ['type']
|
MTS_PROPS = ['type']
|
||||||
|
|
||||||
def draw(self, context):
|
def validate(self, context):
|
||||||
if not hasattr(context, 'material'):
|
|
||||||
return
|
|
||||||
global material_cache
|
global material_cache
|
||||||
mat = context.material
|
mat = context.material
|
||||||
if mat.name in material_cache:
|
if mat.name in material_cache:
|
||||||
|
@ -45,15 +52,20 @@ class mitsuba_material_base(MaterialButtonsPanel, property_group_renderer):
|
||||||
mat = self.get_contents(mat)
|
mat = self.get_contents(mat)
|
||||||
repaint = False
|
repaint = False
|
||||||
for prop in self.MTS_PROPS:
|
for prop in self.MTS_PROPS:
|
||||||
prop_value = getattr(mat, prop)
|
prop_value = copy(getattr(mat, prop))
|
||||||
prop_cache_value = mat_cached[prop] if prop in mat_cached else None
|
prop_cache_value = mat_cached[prop] if prop in mat_cached else None
|
||||||
if prop_cache_value != prop_value:
|
if prop_cache_value != prop_value:
|
||||||
mat_cached[prop] = copy.copy(prop_value)
|
mat_cached[prop] = prop_value
|
||||||
repaint = True
|
repaint = True
|
||||||
if repaint:
|
if repaint:
|
||||||
# Cause a repaint
|
# Cause a repaint
|
||||||
MtsLog("Forcing a repaint")
|
MtsLog("Forcing a repaint")
|
||||||
context.material.preview_render_type = context.material.preview_render_type
|
context.material.preview_render_type = context.material.preview_render_type
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
if not hasattr(context, 'material'):
|
||||||
|
return
|
||||||
|
self.validate(context)
|
||||||
return super().draw(context)
|
return super().draw(context)
|
||||||
|
|
||||||
def get_contents(self, mat):
|
def get_contents(self, mat):
|
||||||
|
@ -93,10 +105,10 @@ class mitsuba_material_sub(MaterialButtonsPanel, property_group_renderer):
|
||||||
repaint = False
|
repaint = False
|
||||||
for prop_entry in props:
|
for prop_entry in props:
|
||||||
prop = prop_entry['attr']
|
prop = prop_entry['attr']
|
||||||
prop_value = getattr(mat, prop) if hasattr(mat, prop) else None
|
prop_value = copy(getattr(mat, prop) if hasattr(mat, prop) else None)
|
||||||
prop_cache_value = mat_cached[prop] if prop in mat_cached else None
|
prop_cache_value = mat_cached[prop] if prop in mat_cached else None
|
||||||
if prop_cache_value != prop_value:
|
if prop_cache_value != copy(prop_value):
|
||||||
mat_cached[prop] = copy.copy(prop_value)
|
mat_cached[prop] = prop_value
|
||||||
repaint = True
|
repaint = True
|
||||||
if repaint:
|
if repaint:
|
||||||
# Cause a repaint
|
# Cause a repaint
|
||||||
|
|
|
@ -41,3 +41,4 @@ class emission(mitsuba_material_base, bpy.types.Panel):
|
||||||
if hasattr(context, "material"):
|
if hasattr(context, "material"):
|
||||||
mat = active_node_mat(context.material)
|
mat = active_node_mat(context.material)
|
||||||
self.layout.prop(mat.mitsuba_emission, "use_emission", text="")
|
self.layout.prop(mat.mitsuba_emission, "use_emission", text="")
|
||||||
|
self.validate(context)
|
||||||
|
|
Loading…
Reference in New Issue