cylinder shape cleanup, support for recursive scene upgrades
parent
edb1869cd4
commit
bdaaa217ba
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue