Changed MeshRelation API (#184)
* cause repro * added originalID to BaryRef * make coverage check informational * unique meshIDs for compose * make AsOriginal decimate * remove vscode properties from git * update docs * remove vertNormal handling * Revert "remove vertNormal handling" This reverts commit c92d590e4d23795504db9afb62eb45adb43d5308. * alternative fix
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
informational: true
|
||||
patch:
|
||||
default:
|
||||
informational: true
|
||||
@@ -107,3 +107,4 @@ Temporary Items
|
||||
|
||||
build
|
||||
__pycache__
|
||||
.vscode/c_cpp_properties.json
|
||||
Vendored
-22
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Mac",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [],
|
||||
"macFrameworkPath": [
|
||||
"/System/Library/Frameworks",
|
||||
"/Library/Frameworks"
|
||||
],
|
||||
"compilerPath": "/usr/bin/clang",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
|
||||
"configurationProvider": "vector-of-bool.cmake-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
@@ -54,7 +54,12 @@ Manifold MengerSponge(int n) {
|
||||
result -= hole;
|
||||
hole = hole.Rotate(0, 0, 90);
|
||||
result -= hole;
|
||||
result = result.AsOriginal();
|
||||
|
||||
// Alternative order causes degenerate triangles
|
||||
// Manifold tmp1 = hole.Rotate(90) + hole.Rotate(90).Rotate(0, 0, 90);
|
||||
// Manifold tmp2 = hole + tmp1;
|
||||
// result = result - tmp2;
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace manifold
|
||||
|
||||
@@ -118,7 +118,7 @@ class Manifold {
|
||||
*/
|
||||
///@{
|
||||
MeshRelation GetMeshRelation() const;
|
||||
std::vector<int> GetMeshIDs() const;
|
||||
int OriginalID() const;
|
||||
Manifold AsOriginal() const;
|
||||
///@}
|
||||
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
#include "par.h"
|
||||
#include "polygon.h"
|
||||
|
||||
// Mark the meshID as coming from P by flipping the 30th bit.
|
||||
// The 30th bit is used to avoid flipping the sign.
|
||||
constexpr int kFromP = 1 << 30;
|
||||
|
||||
using namespace manifold;
|
||||
using namespace thrust::placeholders;
|
||||
|
||||
@@ -421,6 +417,8 @@ struct CreateBarycentric {
|
||||
glm::vec3 *barycentricR;
|
||||
BaryRef *faceRef;
|
||||
int *idx;
|
||||
|
||||
const int offsetQ;
|
||||
const int firstNewVert;
|
||||
const glm::vec3 *vertPosR;
|
||||
const glm::vec3 *vertPosP;
|
||||
@@ -446,9 +444,10 @@ struct CreateBarycentric {
|
||||
const BaryRef oldRef = halfedgeRef.PQ == 0 ? triBaryP[tri] : triBaryQ[tri];
|
||||
|
||||
faceRef[halfedgeR.face] = oldRef;
|
||||
if (halfedgeRef.PQ == 0) {
|
||||
// Mark the meshID as coming from P
|
||||
faceRef[halfedgeR.face].meshID |= kFromP;
|
||||
|
||||
if (halfedgeRef.PQ == 1) {
|
||||
// Mark the meshID as coming from Q
|
||||
faceRef[halfedgeR.face].meshID += offsetQ;
|
||||
}
|
||||
|
||||
if (halfedgeR.startVert < firstNewVert) { // retained vert
|
||||
@@ -488,6 +487,8 @@ std::pair<VecDH<BaryRef>, VecDH<int>> CalculateMeshRelation(
|
||||
outR.meshRelation_.barycentric.resize(outR.halfedge_.size());
|
||||
VecDH<BaryRef> faceRef(numFaceR);
|
||||
VecDH<int> halfedgeBary(halfedgeRef.size());
|
||||
|
||||
const int offsetQ = Manifold::Impl::meshIDCounter_;
|
||||
VecDH<int> idx(1, 0);
|
||||
for_each_n(
|
||||
autoPolicy(halfedgeRef.size()),
|
||||
@@ -495,12 +496,13 @@ std::pair<VecDH<BaryRef>, VecDH<int>> CalculateMeshRelation(
|
||||
halfedgeRef.size(),
|
||||
CreateBarycentric(
|
||||
{outR.meshRelation_.barycentric.ptrD(), faceRef.ptrD(), idx.ptrD(),
|
||||
firstNewVert, outR.vertPos_.cptrD(), inP.vertPos_.cptrD(),
|
||||
offsetQ, firstNewVert, outR.vertPos_.cptrD(), inP.vertPos_.cptrD(),
|
||||
inQ.vertPos_.cptrD(), inP.halfedge_.cptrD(), inQ.halfedge_.cptrD(),
|
||||
inP.meshRelation_.triBary.cptrD(), inQ.meshRelation_.triBary.cptrD(),
|
||||
inP.meshRelation_.barycentric.cptrD(),
|
||||
inQ.meshRelation_.barycentric.cptrD(), invertQ, outR.precision_}));
|
||||
outR.meshRelation_.barycentric.resize(idx[0]);
|
||||
|
||||
return std::make_pair(faceRef, halfedgeBary);
|
||||
}
|
||||
} // namespace
|
||||
@@ -674,19 +676,7 @@ Manifold::Impl Boolean3::Result(Manifold::OpType op) const {
|
||||
if (ManifoldParams().intermediateChecks)
|
||||
ASSERT(outR.Is2Manifold(), logicErr, "simplified mesh is not 2-manifold!");
|
||||
|
||||
// Index starting from 0 is chosen because I want the kernel part as simple as
|
||||
// possible.
|
||||
VecDH<int> meshIDs;
|
||||
VecDH<int> original;
|
||||
for (auto &entry : inP_.meshRelation_.originalID) {
|
||||
meshIDs.push_back(entry.first | kFromP);
|
||||
original.push_back(entry.second);
|
||||
}
|
||||
for (auto &entry : inQ_.meshRelation_.originalID) {
|
||||
meshIDs.push_back(entry.first);
|
||||
original.push_back(entry.second);
|
||||
}
|
||||
outR.UpdateMeshIDs(meshIDs, original);
|
||||
outR.IncrementMeshIDs(0, outR.NumTri());
|
||||
|
||||
#ifdef MANIFOLD_DEBUG
|
||||
simplify.Stop();
|
||||
|
||||
@@ -381,13 +381,6 @@ std::vector<Manifold> Manifold::Decompose() const {
|
||||
return meshes;
|
||||
}
|
||||
VecDH<int> vertLabel(components);
|
||||
// meshID mapping for UpdateMeshIDs
|
||||
VecDH<int> meshIDs;
|
||||
VecDH<int> original;
|
||||
for (auto& entry : pImpl_->meshRelation_.originalID) {
|
||||
meshIDs.push_back(entry.first);
|
||||
original.push_back(entry.second);
|
||||
}
|
||||
|
||||
std::vector<Manifold> meshes;
|
||||
for (int i = 0; i < numLabel; ++i) {
|
||||
@@ -421,9 +414,6 @@ std::vector<Manifold> Manifold::Decompose() const {
|
||||
|
||||
impl->Finish();
|
||||
|
||||
// meshIDs and original will only be sorted after successful updates, so we
|
||||
// can keep using the old one.
|
||||
impl->UpdateMeshIDs(meshIDs, original);
|
||||
meshes.push_back(Manifold(impl));
|
||||
}
|
||||
return meshes;
|
||||
|
||||
@@ -210,18 +210,10 @@ Manifold::Impl CsgLeafNode::Compose(
|
||||
combined.halfedge_.begin() + nextEdge,
|
||||
UpdateHalfedge({nextVert, nextEdge, nextTri}));
|
||||
|
||||
// Assign new IDs to triangles added in this iteration, to differentiate
|
||||
// triangles coming from different manifolds.
|
||||
VecDH<int> meshIDs;
|
||||
VecDH<int> original;
|
||||
for (auto &entry : node->pImpl_->meshRelation_.originalID) {
|
||||
meshIDs.push_back(entry.first);
|
||||
original.push_back(entry.second);
|
||||
}
|
||||
int meshIDStart = combined.meshRelation_.originalID.size();
|
||||
combined.UpdateMeshIDs(meshIDs, original, nextTri,
|
||||
node->pImpl_->meshRelation_.triBary.size(),
|
||||
meshIDStart);
|
||||
// Since the nodes may be copies containing the same meshIDs, it is
|
||||
// important to increment them separately so that each node instance gets
|
||||
// unique meshIDs.
|
||||
combined.IncrementMeshIDs(nextTri, node->pImpl_->NumTri());
|
||||
|
||||
nextVert += node->pImpl_->NumVert();
|
||||
nextEdge += 2 * node->pImpl_->NumEdge();
|
||||
|
||||
+45
-48
@@ -146,11 +146,29 @@ struct InitializeBaryRef {
|
||||
int tri = thrust::get<1>(inOut);
|
||||
|
||||
baryRef.meshID = meshID;
|
||||
baryRef.originalID = meshID;
|
||||
baryRef.tri = tri;
|
||||
baryRef.vertBary = {-3, -2, -1};
|
||||
}
|
||||
};
|
||||
|
||||
struct MarkMeshID {
|
||||
int* includesMeshID;
|
||||
|
||||
__host__ __device__ void operator()(BaryRef& ref) {
|
||||
includesMeshID[ref.meshID] = 1;
|
||||
}
|
||||
};
|
||||
|
||||
struct UpdateMeshID {
|
||||
const int* meshIDold2new;
|
||||
const int meshIDoffset;
|
||||
|
||||
__host__ __device__ void operator()(BaryRef& ref) {
|
||||
ref.meshID = meshIDold2new[ref.meshID] + meshIDoffset;
|
||||
}
|
||||
};
|
||||
|
||||
struct CheckProperties {
|
||||
const int numSets;
|
||||
|
||||
@@ -349,9 +367,8 @@ void Manifold::Impl::ReinitializeReference(int meshID) {
|
||||
// 0 -> meshID, because the meshID after boolean operation also starts from 0.
|
||||
for_each_n(autoPolicy(NumTri()),
|
||||
zip(meshRelation_.triBary.begin(), countAt(0)), NumTri(),
|
||||
InitializeBaryRef({0, halfedge_.cptrD()}));
|
||||
meshRelation_.originalID.clear();
|
||||
meshRelation_.originalID[0] = meshID;
|
||||
InitializeBaryRef({meshID, halfedge_.cptrD()}));
|
||||
meshRelation_.originalID = meshID;
|
||||
}
|
||||
|
||||
int Manifold::Impl::InitializeNewReference(
|
||||
@@ -591,53 +608,33 @@ void Manifold::Impl::CalculateNormals() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update meshID and originalID in meshRelation_.triBary[startTri..startTri+n]
|
||||
* according to meshIDs -> originalIDs mapping. The updated meshID will start
|
||||
* from startID.
|
||||
* Will raise an exception if meshRelation_.triBary[startTri..startTri+n]
|
||||
* contains a meshID not in meshIDs.
|
||||
*
|
||||
* We remap them into indices starting from startID. The exact value value is
|
||||
* not important as long as
|
||||
* 1. They are distinct
|
||||
* 2. `originalID[meshID]` is the original mesh ID of the triangle
|
||||
*
|
||||
* Use this when the mesh is a combination of several meshes or a subset of a
|
||||
* larger mesh, e.g. after performing boolean operations, compose or decompose.
|
||||
* Remaps all the contained meshIDs to new unique values to represent new
|
||||
* instances of these meshes.
|
||||
*/
|
||||
void Manifold::Impl::UpdateMeshIDs(VecDH<int>& meshIDs, VecDH<int>& originalIDs,
|
||||
int startTri, int n, int startID) {
|
||||
if (n == -1) n = meshRelation_.triBary.size();
|
||||
sort_by_key(autoPolicy(n), meshIDs.begin(), meshIDs.end(),
|
||||
originalIDs.begin());
|
||||
constexpr int kOccurred = 1 << 30;
|
||||
VecDH<int> error(1, -1);
|
||||
const int numMesh = meshIDs.size();
|
||||
const int* meshIDsPtr = meshIDs.cptrD();
|
||||
int* originalPtr = originalIDs.ptrD();
|
||||
int* errorPtr = error.ptrD();
|
||||
for_each(autoPolicy(n), meshRelation_.triBary.begin() + startTri,
|
||||
meshRelation_.triBary.begin() + startTri + n,
|
||||
[=] __host__ __device__(BaryRef & b) {
|
||||
int index = thrust::lower_bound(meshIDsPtr, meshIDsPtr + numMesh,
|
||||
b.meshID) -
|
||||
meshIDsPtr;
|
||||
if (index >= numMesh || meshIDsPtr[index] != b.meshID) {
|
||||
*errorPtr = b.meshID;
|
||||
}
|
||||
b.meshID = index + startID;
|
||||
originalPtr[index] |= kOccurred;
|
||||
});
|
||||
void Manifold::Impl::IncrementMeshIDs(int start, int length) {
|
||||
VecDH<BaryRef>& triBary = meshRelation_.triBary;
|
||||
ASSERT(start >= 0 && length >= 0 && start + length <= triBary.size(),
|
||||
logicErr, "out of bounds");
|
||||
const auto policy = autoPolicy(length);
|
||||
// Use double the space since the Boolean has P and Q instances.
|
||||
VecDH<int> includesMeshID(2 * Manifold::Impl::meshIDCounter_, 0);
|
||||
|
||||
ASSERT(error[0] == -1, logicErr,
|
||||
"Manifold::UpdateMeshIDs: meshID " + std::to_string(error[0]) +
|
||||
" not found in meshIDs.");
|
||||
for (int i = 0; i < numMesh; ++i) {
|
||||
if (originalIDs[i] & kOccurred) {
|
||||
originalIDs[i] &= ~kOccurred;
|
||||
meshRelation_.originalID[i + startID] = originalIDs[i];
|
||||
}
|
||||
}
|
||||
auto begin = triBary.begin() + start;
|
||||
auto end = begin + length;
|
||||
|
||||
for_each(policy, begin, end, MarkMeshID({includesMeshID.ptrD()}));
|
||||
|
||||
inclusive_scan(autoPolicy(includesMeshID.size()), includesMeshID.begin(),
|
||||
includesMeshID.end(), includesMeshID.begin());
|
||||
|
||||
const int numMeshIDs = includesMeshID[includesMeshID.size() - 1];
|
||||
const int meshIDstart = Manifold::Impl::meshIDCounter_.fetch_add(
|
||||
numMeshIDs, std::memory_order_relaxed);
|
||||
|
||||
// We do start - 1 because the inclusive scan makes our first index 1 instead
|
||||
// of 0.
|
||||
for_each(policy, begin, end,
|
||||
UpdateMeshID({includesMeshID.cptrD(), meshIDstart - 1}));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-12
@@ -27,17 +27,9 @@ namespace manifold {
|
||||
struct Manifold::Impl {
|
||||
struct MeshRelationD {
|
||||
VecDH<glm::vec3> barycentric;
|
||||
/// meshID in BaryRef has different meaning in MeshRelation and
|
||||
/// MeshRelationD:
|
||||
/// - In `MeshRelation`: The original mesh triangle index.
|
||||
/// - In `MeshRelationD`: The original mesh triangle index =
|
||||
/// `originalID[meshID]`
|
||||
///
|
||||
/// @note Triangles coming from different manifolds should have different
|
||||
/// mesh ID, otherwise `SimplifyTopology` will not work properly.
|
||||
VecDH<BaryRef> triBary;
|
||||
/// meshID to originalID mapping.
|
||||
std::unordered_map<int, int> originalID;
|
||||
/// The meshID of this Manifold if it is an original; -1 otherwise.
|
||||
int originalID = -1;
|
||||
};
|
||||
|
||||
Box bBox_;
|
||||
@@ -70,8 +62,7 @@ struct Manifold::Impl {
|
||||
void ReinitializeReference(int meshID);
|
||||
void CreateHalfedges(const VecDH<glm::ivec3>& triVerts);
|
||||
void CalculateNormals();
|
||||
void UpdateMeshIDs(VecDH<int>& meshIDs, VecDH<int>& originalIDs,
|
||||
int startTri = 0, int n = -1, int startID = 0);
|
||||
void IncrementMeshIDs(int start, int length);
|
||||
|
||||
void Update();
|
||||
void MarkFailure(Error status);
|
||||
|
||||
@@ -275,60 +275,56 @@ Curvature Manifold::GetCurvature() const {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the relationship to the previous mesh, for the purpose of assinging
|
||||
* Gets the relationship to the previous meshes, for the purpose of assinging
|
||||
* properties like texture coordinates. The triBary vector is the same length as
|
||||
* Mesh.triVerts and .meshID indicates the mesh instance and .tri is that mesh's
|
||||
* triangle index to which these barycentric coordinates refer. BaryRef.vertBary
|
||||
* gives an index for each vertex into the barycentric vector if that index is
|
||||
* >= 0, indicating it is a new vertex. If the index is < 0, this indicates it
|
||||
* is an original vertex, the index + 3 vert of the referenced triangle.
|
||||
* Mesh.triVerts: BaryRef.originalID indicates the source mesh and BaryRef.tri
|
||||
* is that mesh's triangle index to which these barycentric coordinates refer.
|
||||
* BaryRef.vertBary gives an index for each vertex into the barycentric vector
|
||||
* if that index is >= 0, indicating it is a new vertex. If the index is < 0,
|
||||
* this indicates it is an original vertex, the index + 3 vert of the referenced
|
||||
* triangle.
|
||||
*
|
||||
* BaryRef.meshID is a unique ID to the particular instance of a given mesh. For
|
||||
* instance, if you want to convert the triangle mesh to a polygon mesh, all the
|
||||
* triangles from a given face will have the same .meshID and .tri values.
|
||||
*/
|
||||
MeshRelation Manifold::GetMeshRelation() const {
|
||||
MeshRelation out;
|
||||
const auto& relation = GetCsgLeafNode().GetImpl()->meshRelation_;
|
||||
out.triBary.insert(out.triBary.end(), relation.triBary.begin(),
|
||||
relation.triBary.end());
|
||||
for (auto& bary : out.triBary) {
|
||||
bary.meshID = relation.originalID.at(bary.meshID);
|
||||
}
|
||||
out.barycentric.insert(out.barycentric.end(), relation.barycentric.begin(),
|
||||
relation.barycentric.end());
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vector of unique meshIDs that are referenced by this manifold's
|
||||
* meshRelation. If this manifold has been newly constructed then there will
|
||||
* only be a single meshID, which can be associated with the input mesh for
|
||||
* future reference.
|
||||
* If this mesh is an original, this returns its meshID that can be referenced
|
||||
* by product manifolds' MeshRelation. If this manifold is a product, this
|
||||
* returns -1.
|
||||
*/
|
||||
std::vector<int> Manifold::GetMeshIDs() const {
|
||||
std::vector<int> out;
|
||||
out.reserve(GetCsgLeafNode().GetImpl()->meshRelation_.originalID.size());
|
||||
for (auto& entry : GetCsgLeafNode().GetImpl()->meshRelation_.originalID) {
|
||||
out.push_back(entry.second);
|
||||
}
|
||||
return out;
|
||||
int Manifold::OriginalID() const {
|
||||
return GetCsgLeafNode().GetImpl()->meshRelation_.originalID;
|
||||
}
|
||||
|
||||
/**
|
||||
* If you copy a manifold, but you want this new copy to have new properties
|
||||
* (e.g. a different UV mapping), you can reset its meshID as an original,
|
||||
* (e.g. a different UV mapping), you can reset its meshIDs to a new original,
|
||||
* meaning it will now be referenced by its descendents instead of the meshes it
|
||||
* was built from, allowing you to differentiate the copies when applying your
|
||||
* properties to the final result. Its new meshID is returned.
|
||||
* properties to the final result.
|
||||
*
|
||||
* This function also condenses all coplanar faces in the relation, allowing
|
||||
* these edges to be collapsed. If you plan to have inconsistent properties
|
||||
* across these faces, meaning you want to preserve some of these edges, you
|
||||
* should instead call GetMesh(), calculate your properties and use these to
|
||||
* construct a new manifold.
|
||||
*
|
||||
* @returns New Mesh
|
||||
* This function also condenses all coplanar faces in the relation, and
|
||||
* collapses those edges. If you want to have inconsistent properties across
|
||||
* these faces, meaning you want to preserve some of these edges, you should
|
||||
* instead call GetMesh(), calculate your properties and use these to construct
|
||||
* a new manifold.
|
||||
*/
|
||||
Manifold Manifold::AsOriginal() const {
|
||||
auto newImpl = std::make_shared<Impl>(*GetCsgLeafNode().GetImpl());
|
||||
newImpl->InitializeNewReference();
|
||||
newImpl->SimplifyTopology();
|
||||
newImpl->Finish();
|
||||
return Manifold(std::make_shared<CsgLeafNode>(newImpl));
|
||||
}
|
||||
|
||||
|
||||
@@ -107,13 +107,15 @@ struct InteriorVerts {
|
||||
const int b = (i == n - 1) ? -1 : first + n - i + 1;
|
||||
const int c = (j == n - 1) ? -3 : first + 1;
|
||||
glm::ivec3 vertBary(c, a, b);
|
||||
triBary[posTri] = {-1, tri, vertBary};
|
||||
triBaryNew[posTri++] = {baryOld.meshID, baryOld.tri, vertBary};
|
||||
triBary[posTri] = {-1, -1, tri, vertBary};
|
||||
triBaryNew[posTri++] = {baryOld.meshID, baryOld.originalID, baryOld.tri,
|
||||
vertBary};
|
||||
if (j < n - 1 - i) {
|
||||
int d = b + 1; // d cannot be a retained vert
|
||||
vertBary = {b, d, c};
|
||||
triBary[posTri] = {-1, tri, vertBary};
|
||||
triBaryNew[posTri++] = {baryOld.meshID, baryOld.tri, vertBary};
|
||||
triBary[posTri] = {-1, -1, tri, vertBary};
|
||||
triBaryNew[posTri++] = {baryOld.meshID, baryOld.originalID,
|
||||
baryOld.tri, vertBary};
|
||||
}
|
||||
|
||||
if (i == 0 || j == 0 || k == 0) continue;
|
||||
|
||||
@@ -208,9 +208,12 @@ void Manifold::Impl::Finish() {
|
||||
ASSERT(faceNormal_.size() == NumTri() || faceNormal_.size() == 0, logicErr,
|
||||
"faceNormal size = " + std::to_string(faceNormal_.size()) +
|
||||
", NumTri = " + std::to_string(NumTri()));
|
||||
ASSERT(vertNormal_.size() == NumVert() || vertNormal_.size() == 0, logicErr,
|
||||
"vertNormal size = " + std::to_string(vertNormal_.size()) +
|
||||
", NumVert = " + std::to_string(NumVert()));
|
||||
// TODO: figure out why this has a flaky failure and then enable reading
|
||||
// vertNormals from a Mesh.
|
||||
// ASSERT(vertNormal_.size() == NumVert() || vertNormal_.size() == 0,
|
||||
// logicErr,
|
||||
// "vertNormal size = " + std::to_string(vertNormal_.size()) +
|
||||
// ", NumVert = " + std::to_string(NumVert()));
|
||||
|
||||
CalculateNormals();
|
||||
collider_ = Collider(faceBox, faceMorton);
|
||||
|
||||
@@ -222,8 +222,13 @@ struct Curvature {
|
||||
* Mesh.
|
||||
*/
|
||||
struct BaryRef {
|
||||
/// The original mesh triangle index.
|
||||
/// The unique ID of the mesh instance of this triangle. If .meshID and .tri
|
||||
/// match for two triangles, then they are coplanar and came from the same
|
||||
/// face.
|
||||
int meshID;
|
||||
/// The OriginalID of the mesh this triangle came from. This ID is ideal for
|
||||
/// reapplying properties like UV coordinates to the output mesh.
|
||||
int originalID;
|
||||
/// The triangle index of the original triangle this was part of:
|
||||
/// Mesh.triVerts[tri].
|
||||
int tri;
|
||||
@@ -446,7 +451,8 @@ inline std::ostream& operator<<(std::ostream& stream, const glm::mat4x3& mat) {
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& stream, const BaryRef& ref) {
|
||||
return stream << "meshID: " << ref.meshID << ", tri: " << ref.tri
|
||||
return stream << "meshID: " << ref.meshID
|
||||
<< ", originalID: " << ref.originalID << ", tri: " << ref.tri
|
||||
<< ", uvw idx: " << ref.vertBary;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ namespace manifold {
|
||||
*/
|
||||
struct Material {
|
||||
/// Roughness value between 0 (shiny) and 1 (matte).
|
||||
float roughness = 1;
|
||||
float roughness = 0.2;
|
||||
/// Metalness value, generally either 0 (dielectric) or 1 (metal).
|
||||
float metalness = 0;
|
||||
float metalness = 1;
|
||||
/// Color (RGBA) multiplier to apply to the whole mesh (each value between 0
|
||||
/// and 1).
|
||||
glm::vec4 color = glm::vec4(1.0f);
|
||||
|
||||
+22
-22
@@ -75,7 +75,7 @@ void Related(const Manifold& out, const std::vector<Mesh>& input,
|
||||
Mesh output = out.GetMesh();
|
||||
MeshRelation relation = out.GetMeshRelation();
|
||||
for (int tri = 0; tri < out.NumTri(); ++tri) {
|
||||
int meshID = relation.triBary[tri].meshID;
|
||||
int meshID = relation.triBary[tri].originalID;
|
||||
int meshIdx = meshID2idx.at(meshID);
|
||||
ASSERT_LT(meshIdx, input.size());
|
||||
const Mesh& inMesh = input[meshIdx];
|
||||
@@ -99,14 +99,14 @@ void RelatedOp(const Manifold& inP, const Manifold& inQ, const Manifold& outR) {
|
||||
std::vector<Mesh> input;
|
||||
std::map<int, int> meshID2idx;
|
||||
|
||||
std::vector<int> meshIDs = inP.GetMeshIDs();
|
||||
EXPECT_EQ(meshIDs.size(), 1);
|
||||
meshID2idx[meshIDs[0]] = input.size();
|
||||
int meshID = inP.OriginalID();
|
||||
EXPECT_GE(meshID, 0);
|
||||
meshID2idx[meshID] = input.size();
|
||||
input.push_back(inP.GetMesh());
|
||||
|
||||
meshIDs = inQ.GetMeshIDs();
|
||||
EXPECT_EQ(meshIDs.size(), 1);
|
||||
meshID2idx[meshIDs[0]] = input.size();
|
||||
meshID = inQ.OriginalID();
|
||||
EXPECT_GE(meshID, 0);
|
||||
meshID2idx[meshID] = input.size();
|
||||
input.push_back(inQ.GetMesh());
|
||||
|
||||
Related(outR, input, meshID2idx);
|
||||
@@ -298,9 +298,9 @@ TEST(Manifold, Decompose) {
|
||||
std::map<int, int> meshID2idx;
|
||||
|
||||
for (const Manifold& manifold : manifoldList) {
|
||||
std::vector<int> meshIDs = manifold.GetMeshIDs();
|
||||
EXPECT_EQ(meshIDs.size(), 1);
|
||||
meshID2idx[meshIDs[0]] = input.size();
|
||||
int meshID = manifold.OriginalID();
|
||||
EXPECT_GE(meshID, 0);
|
||||
meshID2idx[meshID] = input.size();
|
||||
input.push_back(manifold.GetMesh());
|
||||
}
|
||||
|
||||
@@ -563,9 +563,9 @@ TEST(Manifold, MeshRelation) {
|
||||
input.push_back(ImportMesh("data/gyroidpuzzle.ply"));
|
||||
Manifold gyroid(input[0]);
|
||||
|
||||
std::vector<int> meshIDs = gyroid.GetMeshIDs();
|
||||
EXPECT_EQ(meshIDs.size(), 1);
|
||||
meshID2idx[meshIDs[0]] = input.size() - 1;
|
||||
int meshID = gyroid.OriginalID();
|
||||
EXPECT_GE(meshID, 0);
|
||||
meshID2idx[meshID] = input.size() - 1;
|
||||
|
||||
Related(gyroid, input, meshID2idx);
|
||||
}
|
||||
@@ -577,9 +577,9 @@ TEST(Manifold, MeshRelationRefine) {
|
||||
input.push_back(Csaszar());
|
||||
Manifold csaszar(input[0]);
|
||||
|
||||
std::vector<int> meshIDs = csaszar.GetMeshIDs();
|
||||
EXPECT_EQ(meshIDs.size(), 1);
|
||||
meshID2idx[meshIDs[0]] = input.size() - 1;
|
||||
int meshID = csaszar.OriginalID();
|
||||
EXPECT_GE(meshID, 0);
|
||||
meshID2idx[meshID] = input.size() - 1;
|
||||
|
||||
Related(csaszar, input, meshID2idx);
|
||||
csaszar.Refine(4);
|
||||
@@ -864,14 +864,14 @@ TEST(Boolean, Gyroid) {
|
||||
std::vector<Mesh> input;
|
||||
std::map<int, int> meshID2idx;
|
||||
|
||||
std::vector<int> meshIDs = gyroid.GetMeshIDs();
|
||||
EXPECT_EQ(meshIDs.size(), 1);
|
||||
meshID2idx[meshIDs[0]] = input.size();
|
||||
int meshID = gyroid.OriginalID();
|
||||
EXPECT_GE(meshID, 0);
|
||||
meshID2idx[meshID] = input.size();
|
||||
input.push_back(gyroidpuzzle);
|
||||
|
||||
meshIDs = gyroid2.GetMeshIDs();
|
||||
EXPECT_EQ(meshIDs.size(), 1);
|
||||
meshID2idx[meshIDs[0]] = input.size();
|
||||
meshID = gyroid2.OriginalID();
|
||||
EXPECT_GE(meshID, 0);
|
||||
meshID2idx[meshID] = input.size();
|
||||
input.push_back(gyroidpuzzle2);
|
||||
|
||||
Related(result, input, meshID2idx);
|
||||
|
||||
Reference in New Issue
Block a user