obj.cpp: handle convex n-gons (contributed by Fabrice Rousselle), shapeIndex feature
parent
89fd8c1d52
commit
4805fc570e
|
@ -52,15 +52,18 @@ MTS_NAMESPACE_BEGIN
|
||||||
* }
|
* }
|
||||||
* \parameter{flipTexCoords}{\Boolean}{
|
* \parameter{flipTexCoords}{\Boolean}{
|
||||||
* Treat the vertical component of the texture as inverted? Most OBJ files use
|
* Treat the vertical component of the texture as inverted? Most OBJ files use
|
||||||
* this convention. \default{\code{true}, i.e. flip them to get the
|
* this convention. \default{\code{true}}
|
||||||
* correct coordinates}.
|
|
||||||
* }
|
* }
|
||||||
* \parameter{toWorld}{\Transform\Or\Animation}{
|
* \parameter{toWorld}{\Transform\Or\Animation}{
|
||||||
* Specifies an optional linear object-to-world transformation.
|
* Specifies an optional linear object-to-world transformation.
|
||||||
* \default{none (i.e. object space $=$ world space)}
|
* \default{none (i.e. object space $=$ world space)}
|
||||||
* }
|
* }
|
||||||
|
* \parameter{shapeIndex}{\Integer}{
|
||||||
|
* When the file contains multiple meshes, this parameter can
|
||||||
|
* be used to select a single one. \default{\code{-1}, \mbox{i.e. load all}}
|
||||||
|
* }
|
||||||
* \parameter{collapse}{\Boolean}{
|
* \parameter{collapse}{\Boolean}{
|
||||||
* Collapse all contained meshes into a single object \default{\code{false}}
|
* Collapse all meshes into a single shape \default{\code{false}}
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* \renderings{
|
* \renderings{
|
||||||
|
@ -134,7 +137,6 @@ MTS_NAMESPACE_BEGIN
|
||||||
* valid vertex normals).
|
* valid vertex normals).
|
||||||
*
|
*
|
||||||
* \remarks{
|
* \remarks{
|
||||||
* \item The plugin currently only supports loading meshes constructed from triangles and quadrilaterals.
|
|
||||||
* \item Importing geometry via OBJ files should only be used as an absolutely
|
* \item Importing geometry via OBJ files should only be used as an absolutely
|
||||||
* last resort. Due to inherent limitations of this format, the files tend to be unreasonably
|
* last resort. Due to inherent limitations of this format, the files tend to be unreasonably
|
||||||
* large, and parsing them requires significant amounts of memory and processing power. What's worse
|
* large, and parsing them requires significant amounts of memory and processing power. What's worse
|
||||||
|
@ -205,6 +207,9 @@ public:
|
||||||
/* Causes all texture coordinates to be vertically flipped */
|
/* Causes all texture coordinates to be vertically flipped */
|
||||||
bool flipTexCoords = props.getBoolean("flipTexCoords", true);
|
bool flipTexCoords = props.getBoolean("flipTexCoords", true);
|
||||||
|
|
||||||
|
/// When the file contains multiple meshes, this index specifies which one to load
|
||||||
|
int shapeIndex = props.getInteger("shapeIndex", -1);
|
||||||
|
|
||||||
/* Object-space -> World-space transformation */
|
/* Object-space -> World-space transformation */
|
||||||
Transform objectToWorld = props.getTransform("toWorld", Transform());
|
Transform objectToWorld = props.getTransform("toWorld", Transform());
|
||||||
|
|
||||||
|
@ -226,7 +231,7 @@ public:
|
||||||
std::set<std::string> geomNames;
|
std::set<std::string> geomNames;
|
||||||
std::vector<Vertex> vertexBuffer;
|
std::vector<Vertex> vertexBuffer;
|
||||||
fs::path materialLibrary;
|
fs::path materialLibrary;
|
||||||
int geomIdx = 0;
|
int geomIndex = 0;
|
||||||
bool nameBeforeGeometry = false;
|
bool nameBeforeGeometry = false;
|
||||||
std::string materialName;
|
std::string materialName;
|
||||||
|
|
||||||
|
@ -260,8 +265,9 @@ public:
|
||||||
if (triangles.size() > 0) {
|
if (triangles.size() > 0) {
|
||||||
/// make sure that we have unique names
|
/// make sure that we have unique names
|
||||||
if (geomNames.find(targetName) != geomNames.end())
|
if (geomNames.find(targetName) != geomNames.end())
|
||||||
targetName = formatString("%s_%i", targetName.c_str(), geomIdx++);
|
targetName = formatString("%s_%i", targetName.c_str(), geomIndex++);
|
||||||
geomNames.insert(targetName);
|
geomNames.insert(targetName);
|
||||||
|
if (shapeIndex < 0 || geomIndex-1 == shapeIndex)
|
||||||
createMesh(targetName, vertices, normals, texcoords,
|
createMesh(targetName, vertices, normals, texcoords,
|
||||||
triangles, materialName, objectToWorld, vertexBuffer);
|
triangles, materialName, objectToWorld, vertexBuffer);
|
||||||
triangles.clear();
|
triangles.clear();
|
||||||
|
@ -271,11 +277,12 @@ public:
|
||||||
name = newName;
|
name = newName;
|
||||||
} else if (buf == "usemtl") {
|
} else if (buf == "usemtl") {
|
||||||
/* Flush if necessary */
|
/* Flush if necessary */
|
||||||
if (triangles.size() > 0) {
|
if (triangles.size() > 0 && !m_collapse) {
|
||||||
/// make sure that we have unique names
|
/// make sure that we have unique names
|
||||||
if (geomNames.find(name) != geomNames.end())
|
if (geomNames.find(name) != geomNames.end())
|
||||||
name = formatString("%s_%i", name.c_str(), geomIdx++);
|
name = formatString("%s_%i", name.c_str(), geomIndex++);
|
||||||
geomNames.insert(name);
|
geomNames.insert(name);
|
||||||
|
if (shapeIndex < 0 || geomIndex-1 == shapeIndex)
|
||||||
createMesh(name, vertices, normals, texcoords,
|
createMesh(name, vertices, normals, texcoords,
|
||||||
triangles, materialName, objectToWorld, vertexBuffer);
|
triangles, materialName, objectToWorld, vertexBuffer);
|
||||||
triangles.clear();
|
triangles.clear();
|
||||||
|
@ -298,25 +305,23 @@ public:
|
||||||
iss >> tmp; parse(t, 1, tmp);
|
iss >> tmp; parse(t, 1, tmp);
|
||||||
iss >> tmp; parse(t, 2, tmp);
|
iss >> tmp; parse(t, 2, tmp);
|
||||||
triangles.push_back(t);
|
triangles.push_back(t);
|
||||||
if (iss >> tmp) {
|
/* Handle n-gons assuming a convex shape */
|
||||||
t.p[1] = t.p[0];
|
while (iss >> tmp) {
|
||||||
t.uv[1] = t.uv[0];
|
t.p[1] = t.p[2];
|
||||||
t.n[1] = t.n[0];
|
t.uv[1] = t.uv[2];
|
||||||
parse(t, 0, tmp);
|
t.n[1] = t.n[2];
|
||||||
|
parse(t, 2, tmp);
|
||||||
triangles.push_back(t);
|
triangles.push_back(t);
|
||||||
}
|
}
|
||||||
if (iss >> tmp)
|
|
||||||
Log(EError, "Encountered an n-gon (with n>4)! Only "
|
|
||||||
"triangles and quads are supported by the OBJ loader.");
|
|
||||||
} else {
|
} else {
|
||||||
/* Ignore */
|
/* Ignore */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (geomNames.find(name) != geomNames.end())
|
if (geomNames.find(name) != geomNames.end())
|
||||||
/// make sure that we have unique names
|
/// make sure that we have unique names
|
||||||
name = formatString("%s_%i", m_name.c_str(), geomIdx);
|
name = formatString("%s_%i", m_name.c_str(), geomIndex);
|
||||||
|
|
||||||
|
if (shapeIndex < 0 || geomIndex-1 == shapeIndex)
|
||||||
createMesh(name, vertices, normals, texcoords,
|
createMesh(name, vertices, normals, texcoords,
|
||||||
triangles, materialName, objectToWorld, vertexBuffer);
|
triangles, materialName, objectToWorld, vertexBuffer);
|
||||||
|
|
||||||
|
@ -535,7 +540,7 @@ public:
|
||||||
bsdf->configure();
|
bsdf->configure();
|
||||||
|
|
||||||
if (bump) {
|
if (bump) {
|
||||||
props = Properties("bump");
|
props = Properties("bumpmap");
|
||||||
ref<BSDF> bumpBSDF = static_cast<BSDF *> (PluginManager::getInstance()->
|
ref<BSDF> bumpBSDF = static_cast<BSDF *> (PluginManager::getInstance()->
|
||||||
createObject(MTS_CLASS(BSDF), props));
|
createObject(MTS_CLASS(BSDF), props));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue