cylinder shape cleanup, support for recursive scene upgrades
parent
edb1869cd4
commit
bdaaa217ba
|
@ -153,6 +153,14 @@
|
||||||
<xsl:attribute name="name">flipNormals</xsl:attribute>
|
<xsl:attribute name="name">flipNormals</xsl:attribute>
|
||||||
</xsl:template>
|
</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 -->
|
<!-- Update the name of the lambertian plugin -->
|
||||||
<xsl:template match="bsdf[@type='lambertian']/@type">
|
<xsl:template match="bsdf[@type='lambertian']/@type">
|
||||||
<xsl:attribute name="type">diffuse</xsl:attribute>
|
<xsl:attribute name="type">diffuse</xsl:attribute>
|
||||||
|
|
|
@ -77,7 +77,7 @@ paramMap = StringMap()
|
||||||
paramMap['myParameter'] = 'value'
|
paramMap['myParameter'] = 'value'
|
||||||
|
|
||||||
# Load the scene from an XML file
|
# 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
|
# Display a textual summary of the scene's contents
|
||||||
print(scene)
|
print(scene)
|
||||||
|
|
|
@ -603,16 +603,15 @@ Point2 squareToDisk(const Point2 &sample) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void coordinateSystem(const Vector &a, Vector &b, Vector &c) {
|
void coordinateSystem(const Vector &a, Vector &b, Vector &c) {
|
||||||
if (std::abs(a.x) > std::abs(a.y)) {
|
if (std::abs(a.x) > std::abs(a.y)) {
|
||||||
Float invLen = 1.0f / std::sqrt(a.x * a.x + a.z * a.z);
|
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 {
|
} else {
|
||||||
Float invLen = 1.0f / std::sqrt(a.y * a.y + a.z * a.z);
|
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) {
|
Point2 squareToTriangle(const Point2 &sample) {
|
||||||
|
|
|
@ -293,9 +293,9 @@ void Scene::initialize() {
|
||||||
if (!m_luminairePDF.isReady()) {
|
if (!m_luminairePDF.isReady()) {
|
||||||
if (m_luminaires.size() == 0) {
|
if (m_luminaires.size() == 0) {
|
||||||
Log(EWarn, "No luminaires found -- adding a sky luminaire");
|
Log(EWarn, "No luminaires found -- adding a sky luminaire");
|
||||||
Properties skyProps("sunsky");
|
Properties skyProps("sky");
|
||||||
skyProps.setFloat("skyScale", 0.1f);
|
skyProps.setFloat("skyScale", 0.1f);
|
||||||
skyProps.setFloat("sunScale", 0.1f);
|
//skyProps.setFloat("sunScale", 0.1f);
|
||||||
skyProps.setBoolean("extend", true);
|
skyProps.setBoolean("extend", true);
|
||||||
ref<Luminaire> luminaire = static_cast<Luminaire *>(
|
ref<Luminaire> luminaire = static_cast<Luminaire *>(
|
||||||
PluginManager::getInstance()->createObject(MTS_CLASS(Luminaire), skyProps));
|
PluginManager::getInstance()->createObject(MTS_CLASS(Luminaire), skyProps));
|
||||||
|
|
|
@ -145,9 +145,10 @@ void UpgradeManager::performUpgrade(const QString &filename, const Version &vers
|
||||||
++nTransformations;
|
++nTransformations;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nTransformations == 0)
|
if (nTransformations == 0) {
|
||||||
SLog(EError, "Strange -- no transformations were applied? "
|
SLog(EError, "Strange -- no transformations were applied? "
|
||||||
"Stopping the upgrade operation.");
|
"Stopping the upgrade operation.");
|
||||||
|
}
|
||||||
|
|
||||||
/* Done, write back to disk */
|
/* Done, write back to disk */
|
||||||
SLog(EInfo, "Successfully applied %i transformations, writing the result "
|
SLog(EInfo, "Successfully applied %i transformations, writing the result "
|
||||||
|
@ -158,10 +159,36 @@ void UpgradeManager::performUpgrade(const QString &filename, const Version &vers
|
||||||
"the upgrade operation.", filename.toStdString().c_str());
|
"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 input(inputArray);
|
||||||
QTextStream output(&file);
|
QTextStream output(&file);
|
||||||
output << "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
output << "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||||
<< endl << endl;
|
<< endl << endl;
|
||||||
cleanupXML(input, output);
|
cleanupXML(input, output);
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
QDomDocument tooltipDoc;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,10 @@ MTS_NAMESPACE_BEGIN
|
||||||
/*!\plugin{cylinder}{Cylinder intersection primitive}
|
/*!\plugin{cylinder}{Cylinder intersection primitive}
|
||||||
* \order{2}
|
* \order{2}
|
||||||
* \parameters{
|
* \parameters{
|
||||||
* \parameter{a}{\Point}{
|
* \parameter{p0}{\Point}{
|
||||||
* Starting point of the cylinder's centerline \default{(0, 0, 0)}
|
* 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)}
|
* Endpoint of the cylinder's centerline \default{(0, 0, 1)}
|
||||||
* }
|
* }
|
||||||
* \parameter{radius}{\Float}{
|
* \parameter{radius}{\Float}{
|
||||||
|
@ -43,6 +43,9 @@ MTS_NAMESPACE_BEGIN
|
||||||
* \default{none (i.e. object space $=$ world space)}
|
* \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 {
|
class Cylinder : public Shape {
|
||||||
private:
|
private:
|
||||||
|
@ -51,32 +54,25 @@ private:
|
||||||
Float m_radius, m_length, m_invSurfaceArea;
|
Float m_radius, m_length, m_invSurfaceArea;
|
||||||
public:
|
public:
|
||||||
Cylinder(const Properties &props) : Shape(props) {
|
Cylinder(const Properties &props) : Shape(props) {
|
||||||
/**
|
Float radius = props.getFloat("radius", 1.0f);
|
||||||
* There are two ways of instantiating cylinders: either,
|
Point p1 = props.getPoint("p0", Point(0.0f, 0.0f, 0.0f));
|
||||||
* one can specify a linear transformation to from the
|
Point p2 = props.getPoint("p1", Point(0.0f, 0.0f, 1.0f));
|
||||||
* unit cylinder using the 'toWorld' parameter, or one
|
Vector d = p2 - p1;
|
||||||
* can explicitly specify two points and a radius.
|
Float length = d.length();
|
||||||
*/
|
|
||||||
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();
|
|
||||||
|
|
||||||
m_objectToWorld =
|
m_objectToWorld =
|
||||||
Transform::translate(Vector(p1)) *
|
Transform::translate(Vector(p1)) *
|
||||||
Transform::fromFrame(Frame(rel/length));
|
Transform::fromFrame(Frame(d / length)) *
|
||||||
m_radius = radius;
|
Transform::scale(Vector(radius, radius, length));
|
||||||
m_length = length;
|
|
||||||
} else {
|
if (props.hasProperty("toWorld"))
|
||||||
Transform objectToWorld = props.getTransform("toWorld", Transform());
|
m_objectToWorld = props.getTransform("toWorld") * m_objectToWorld;
|
||||||
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
|
// Remove the scale from the object-to-world transform
|
||||||
m_objectToWorld = objectToWorld * Transform::scale(
|
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));
|
Vector(1/m_radius, 1/m_radius, 1/m_length));
|
||||||
}
|
|
||||||
m_worldToObject = m_objectToWorld.inverse();
|
m_worldToObject = m_objectToWorld.inverse();
|
||||||
m_invSurfaceArea = 1/(2*M_PI*m_radius*m_length);
|
m_invSurfaceArea = 1/(2*M_PI*m_radius*m_length);
|
||||||
Assert(m_length > 0 && m_radius > 0);
|
Assert(m_length > 0 && m_radius > 0);
|
||||||
|
|
Loading…
Reference in New Issue