cylinder shape cleanup, support for recursive scene upgrades

metadata
Wenzel Jakob 2011-08-23 02:02:44 -04:00
parent edb1869cd4
commit bdaaa217ba
6 changed files with 68 additions and 38 deletions

View File

@ -153,11 +153,19 @@
<xsl:attribute name="name">flipNormals</xsl:attribute>
</xsl:template>
<!-- Update the parameters of the cylinder plugin -->
<xsl:template match="shape[@type='cylinder']/point[@name='p1']/@name">
<xsl:attribute name="name">p0</xsl:attribute>
</xsl:template>
<xsl:template match="shape[@type='cylinder']/point[@name='p2']/@name">
<xsl:attribute name="name">p1</xsl:attribute>
</xsl:template>
<!-- Update the name of the lambertian plugin -->
<xsl:template match="bsdf[@type='lambertian']/@type">
<xsl:attribute name="type">diffuse</xsl:attribute>
</xsl:template>
<!-- Update the parameters of the ward plugin -->
<xsl:template match="bsdf[@type='ward']/float[@name='alphaX']/@name">
<xsl:attribute name="name">alphaU</xsl:attribute>
@ -165,7 +173,7 @@
<xsl:template match="bsdf[@type='ward']/float[@name='alphaY']/@name">
<xsl:attribute name="name">alphaV</xsl:attribute>
</xsl:template>
<!-- Update the name of the microfacet plugin -->
<xsl:template match="bsdf[@type='microfacet']/@type">
<xsl:attribute name="type">roughplastic</xsl:attribute>

View File

@ -77,7 +77,7 @@ paramMap = StringMap()
paramMap['myParameter'] = 'value'
# Load the scene from an XML file
scene = SceneHandler.loadScene(fileResolver, paramMap)
scene = SceneHandler.loadScene(fileResolver.resolve("scene.xml"), paramMap)
# Display a textual summary of the scene's contents
print(scene)

View File

@ -603,16 +603,15 @@ Point2 squareToDisk(const Point2 &sample) {
);
}
void coordinateSystem(const Vector &a, Vector &b, Vector &c) {
if (std::abs(a.x) > std::abs(a.y)) {
Float invLen = 1.0f / std::sqrt(a.x * a.x + a.z * a.z);
b = Vector(-a.z * invLen, 0.0f, a.x * invLen);
c = Vector(a.z * invLen, 0.0f, -a.x * invLen);
} else {
Float invLen = 1.0f / std::sqrt(a.y * a.y + a.z * a.z);
b = Vector(0.0f, -a.z * invLen, a.y * invLen);
c = Vector(0.0f, a.z * invLen, -a.y * invLen);
}
c = cross(a, b);
b = cross(c, a);
}
Point2 squareToTriangle(const Point2 &sample) {

View File

@ -293,9 +293,9 @@ void Scene::initialize() {
if (!m_luminairePDF.isReady()) {
if (m_luminaires.size() == 0) {
Log(EWarn, "No luminaires found -- adding a sky luminaire");
Properties skyProps("sunsky");
Properties skyProps("sky");
skyProps.setFloat("skyScale", 0.1f);
skyProps.setFloat("sunScale", 0.1f);
//skyProps.setFloat("sunScale", 0.1f);
skyProps.setBoolean("extend", true);
ref<Luminaire> luminaire = static_cast<Luminaire *>(
PluginManager::getInstance()->createObject(MTS_CLASS(Luminaire), skyProps));

View File

@ -145,9 +145,10 @@ void UpgradeManager::performUpgrade(const QString &filename, const Version &vers
++nTransformations;
}
if (nTransformations == 0)
if (nTransformations == 0) {
SLog(EError, "Strange -- no transformations were applied? "
"Stopping the upgrade operation.");
}
/* Done, write back to disk */
SLog(EInfo, "Successfully applied %i transformations, writing the result "
@ -157,11 +158,37 @@ void UpgradeManager::performUpgrade(const QString &filename, const Version &vers
SLog(EError, "Unable to open \"%s\" with write access -- stopping "
"the upgrade operation.", filename.toStdString().c_str());
}
int line, column;
QString errorMsg;
QDomDocument doc;
if (!doc.setContent(inputArray, &errorMsg, &line, &column))
SLog(EError, "Unable to parse file: error %s at line %i, colum %i",
errorMsg.toStdString().c_str(), line, column);
QDomElement root = doc.documentElement();
/* Search for include nodes */
QDomNode n = root.firstChild();
while (!n.isNull()) {
QDomElement e = n.toElement();
if (!e.isNull()) {
if (e.tagName() == "include") {
fs::path path = m_resolver->resolve(e.attribute("filename").toStdString());
SLog(EInfo, "Recursively upgrading include file \"%s\" ..",
path.file_string().c_str());
performUpgrade(path.file_string().c_str(), version);
}
}
n = n.nextSibling();
}
QTextStream input(inputArray);
QTextStream output(&file);
output << "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
<< endl << endl;
cleanupXML(input, output);
file.close();
QDomDocument tooltipDoc;
}

View File

@ -28,10 +28,10 @@ MTS_NAMESPACE_BEGIN
/*!\plugin{cylinder}{Cylinder intersection primitive}
* \order{2}
* \parameters{
* \parameter{a}{\Point}{
* \parameter{p0}{\Point}{
* Starting point of the cylinder's centerline \default{(0, 0, 0)}
* }
* \parameter{b}{\Point}{
* \parameter{p1}{\Point}{
* Endpoint of the cylinder's centerline \default{(0, 0, 1)}
* }
* \parameter{radius}{\Float}{
@ -43,6 +43,9 @@ MTS_NAMESPACE_BEGIN
* \default{none (i.e. object space $=$ world space)}
* }
* }
* This shape plugin describes a simple cylinder intersection primitive.
* It should always be preferred over approximations modeled using
* triangles.
*/
class Cylinder : public Shape {
private:
@ -51,32 +54,25 @@ private:
Float m_radius, m_length, m_invSurfaceArea;
public:
Cylinder(const Properties &props) : Shape(props) {
/**
* There are two ways of instantiating cylinders: either,
* one can specify a linear transformation to from the
* unit cylinder using the 'toWorld' parameter, or one
* can explicitly specify two points and a radius.
*/
if (props.hasProperty("p1") && props.hasProperty("p2")
&& props.hasProperty("radius")) {
Point p1 = props.getPoint("p1"), p2 = props.getPoint("p2");
Vector rel = p2 - p1;
Float radius = props.getFloat("radius");
Float length = rel.length();
Float radius = props.getFloat("radius", 1.0f);
Point p1 = props.getPoint("p0", Point(0.0f, 0.0f, 0.0f));
Point p2 = props.getPoint("p1", Point(0.0f, 0.0f, 1.0f));
Vector d = p2 - p1;
Float length = d.length();
m_objectToWorld =
Transform::translate(Vector(p1)) *
Transform::fromFrame(Frame(d / length)) *
Transform::scale(Vector(radius, radius, length));
if (props.hasProperty("toWorld"))
m_objectToWorld = props.getTransform("toWorld") * m_objectToWorld;
// Remove the scale from the object-to-world transform
m_radius = m_objectToWorld(Vector(1,0,0)).length();
m_length = m_objectToWorld(Vector(0,0,1)).length();
m_objectToWorld = m_objectToWorld * Transform::scale(
Vector(1/m_radius, 1/m_radius, 1/m_length));
m_objectToWorld =
Transform::translate(Vector(p1)) *
Transform::fromFrame(Frame(rel/length));
m_radius = radius;
m_length = length;
} else {
Transform objectToWorld = props.getTransform("toWorld", Transform());
m_radius = objectToWorld(Vector(1,0,0)).length();
m_length = objectToWorld(Vector(0,0,1)).length();
// Remove the scale from the object-to-world transform
m_objectToWorld = objectToWorld * Transform::scale(
Vector(1/m_radius, 1/m_radius, 1/m_length));
}
m_worldToObject = m_objectToWorld.inverse();
m_invSurfaceArea = 1/(2*M_PI*m_radius*m_length);
Assert(m_length > 0 && m_radius > 0);