Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CompactInPlace failure #43

Merged
merged 2 commits into from
Feb 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
280 changes: 149 additions & 131 deletions mesh/DMesh3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2406,166 +2406,184 @@ public InPlaceCompactInfo CompactInPlace(bool bComputeCompactInfo = false)
ci = new InPlaceCompactInfo(mapV, mapT);
}

// find first free vertex, and last used vertex
int iLastV = MaxVertexID - 1, iCurV = 0;
while (vertices_refcount.isValidUnsafe(iLastV) == false)
iLastV--;
while (vertices_refcount.isValidUnsafe(iCurV))
iCurV++;

DVector<short> vref = vertices_refcount.RawRefCounts;

while (iCurV < iLastV) {
int kc = iCurV * 3, kl = iLastV * 3;
vertices[kc] = vertices[kl]; vertices[kc+1] = vertices[kl+1]; vertices[kc+2] = vertices[kl+2];
if ( normals != null ) {
normals[kc] = normals[kl]; normals[kc+1] = normals[kl+1]; normals[kc+2] = normals[kl+2];
}
if (colors != null) {
colors[kc] = colors[kl]; colors[kc+1] = colors[kl+1]; colors[kc+2] = colors[kl+2];
}
if (uv != null) {
int ukc = iCurV * 2, ukl = iLastV * 2;
uv[ukc] = uv[ukl]; uv[ukc+1] = uv[ukl+1];
}
/** shift vertices **/
if (!vertices_refcount.is_dense)
{
// find first free vertex, and last used vertex
int iLastV = vertices_refcount.max_index - 1, iCurV = 0;
while (iLastV >= 0 && !vertices_refcount.isValidUnsafe(iLastV))
iLastV--;
while (iCurV < vertices_refcount.max_index && vertices_refcount.isValidUnsafe(iCurV))
iCurV++;

foreach ( int eid in vertex_edges.ValueItr(iLastV) ) {
// replace vertex in edges
replace_edge_vertex(eid, iLastV, iCurV);
DVector<short> vref = vertices_refcount.RawRefCounts;

// replace vertex in triangles
int t0 = edges[4*eid + 2];
replace_tri_vertex(t0, iLastV, iCurV);
int t1 = edges[4*eid + 3];
if ( t1 != DMesh3.InvalidID )
replace_tri_vertex(t1, iLastV, iCurV);
}
while (iCurV < iLastV)
{
int kc = iCurV * 3, kl = iLastV * 3;
vertices[kc] = vertices[kl]; vertices[kc + 1] = vertices[kl + 1]; vertices[kc + 2] = vertices[kl + 2];
if (normals != null)
{
normals[kc] = normals[kl]; normals[kc + 1] = normals[kl + 1]; normals[kc + 2] = normals[kl + 2];
}
if (colors != null)
{
colors[kc] = colors[kl]; colors[kc + 1] = colors[kl + 1]; colors[kc + 2] = colors[kl + 2];
}
if (uv != null)
{
int ukc = iCurV * 2, ukl = iLastV * 2;
uv[ukc] = uv[ukl]; uv[ukc + 1] = uv[ukl + 1];
}

// shift vertex refcount to new position
vref[iCurV] = vref[iLastV];
vref[iLastV] = RefCountVector.invalid;
foreach (int eid in vertex_edges.ValueItr(iLastV))
{
// replace vertex in edges
replace_edge_vertex(eid, iLastV, iCurV);

// replace vertex in triangles
int t0 = edges[4 * eid + 2];
replace_tri_vertex(t0, iLastV, iCurV);
int t1 = edges[4 * eid + 3];
if (t1 != DMesh3.InvalidID)
replace_tri_vertex(t1, iLastV, iCurV);
}

// move edge list
vertex_edges.Move(iLastV, iCurV);
// shift vertex refcount to new position
vref[iCurV] = vref[iLastV];
vref[iLastV] = RefCountVector.invalid;

if (mapV != null)
mapV[iLastV] = iCurV;
// move edge list
vertex_edges.Move(iLastV, iCurV);

// move cur forward one, last back one, and then search for next valid
iLastV--; iCurV++;
while (vertices_refcount.isValidUnsafe(iLastV) == false)
iLastV--;
while (vertices_refcount.isValidUnsafe(iCurV) && iCurV < iLastV)
iCurV++;
}
if (mapV != null)
mapV[iLastV] = iCurV;

// move cur forward one, last back one, and then search for next valid
iLastV--; iCurV++;
while (iLastV >= 0 && vertices_refcount.isValidUnsafe(iLastV) == false)
iLastV--;
while (vertices_refcount.isValidUnsafe(iCurV) && iCurV < iLastV)
iCurV++;
}

// trim vertices data structures
vertices_refcount.trim(VertexCount);
vertices.resize(VertexCount*3);
if (normals != null)
normals.resize(VertexCount * 3);
if (colors != null)
colors.resize(VertexCount * 3);
if (uv != null)
uv.resize(VertexCount * 2);
// trim vertices data structures
vertices_refcount.trim(VertexCount);
vertices.resize(VertexCount * 3);
if (normals != null)
normals.resize(VertexCount * 3);
if (colors != null)
colors.resize(VertexCount * 3);
if (uv != null)
uv.resize(VertexCount * 2);
}

// [TODO] vertex_edges!!!

/** shift triangles **/
if (!triangles_refcount.is_dense)
{
// find first free triangle, and last valid triangle
int iLastT = triangles_refcount.max_index - 1, iCurT = 0;
while (iLastT > 0 && !triangles_refcount.isValidUnsafe(iLastT))
iLastT--;
while (iCurT < triangles_refcount.max_index && triangles_refcount.isValidUnsafe(iCurT))
iCurT++;

// find first free triangle, and last valid triangle
int iLastT = MaxTriangleID - 1, iCurT = 0;
while (triangles_refcount.isValidUnsafe(iLastT) == false)
iLastT--;
while (triangles_refcount.isValidUnsafe(iCurT))
iCurT++;

DVector<short> tref = triangles_refcount.RawRefCounts;
DVector<short> tref = triangles_refcount.RawRefCounts;

while (iCurT < iLastT) {
int kc = iCurT * 3, kl = iLastT * 3;
while (iCurT < iLastT)
{
int kc = iCurT * 3, kl = iLastT * 3;

// shift triangle
for (int j = 0; j < 3; ++j) {
triangles[kc + j] = triangles[kl + j];
triangle_edges[kc + j] = triangle_edges[kl + j];
}
if (triangle_groups != null)
triangle_groups[iCurT] = triangle_groups[iLastT];
// shift triangle
for (int j = 0; j < 3; ++j)
{
triangles[kc + j] = triangles[kl + j];
triangle_edges[kc + j] = triangle_edges[kl + j];
}
if (triangle_groups != null)
triangle_groups[iCurT] = triangle_groups[iLastT];

// update edges
for (int j = 0; j < 3; ++j)
{
int eid = triangle_edges[kc + j];
replace_edge_triangle(eid, iLastT, iCurT);
}

// update edges
for ( int j = 0; j < 3; ++j ) {
int eid = triangle_edges[kc + j];
replace_edge_triangle(eid, iLastT, iCurT);
}
// shift triangle refcount to new position
tref[iCurT] = tref[iLastT];
tref[iLastT] = RefCountVector.invalid;

// shift triangle refcount to new position
tref[iCurT] = tref[iLastT];
tref[iLastT] = RefCountVector.invalid;
if (mapT != null)
mapT[iLastT] = iCurT;

if (mapT != null)
mapT[iLastT] = iCurT;
// move cur forward one, last back one, and then search for next valid
iLastT--; iCurT++;
while (iLastT >= 0 && triangles_refcount.isValidUnsafe(iLastT) == false)
iLastT--;
while (triangles_refcount.isValidUnsafe(iCurT) && iCurT < iLastT)
iCurT++;
}

// move cur forward one, last back one, and then search for next valid
iLastT--; iCurT++;
while (triangles_refcount.isValidUnsafe(iLastT) == false)
iLastT--;
while (triangles_refcount.isValidUnsafe(iCurT) && iCurT < iLastT)
iCurT++;
// trim triangles data structures
triangles_refcount.trim(TriangleCount);
triangles.resize(TriangleCount * 3);
triangle_edges.resize(TriangleCount * 3);
if (triangle_groups != null)
triangle_groups.resize(TriangleCount);
}

// trim triangles data structures
triangles_refcount.trim(TriangleCount);
triangles.resize(TriangleCount*3);
triangle_edges.resize(TriangleCount*3);
if (triangle_groups != null)
triangle_groups.resize(TriangleCount);

/** shift edges **/
if (!edges_refcount.is_dense)
{
// find first free edge, and last used edge
int iLastE = edges_refcount.max_index - 1, iCurE = 0;
while (iLastE >= 0 && !edges_refcount.isValidUnsafe(iLastE))
iLastE--;
while (iCurE < edges_refcount.max_index && edges_refcount.isValidUnsafe(iCurE))
iCurE++;

// find first free edge, and last used edge
int iLastE = MaxEdgeID - 1, iCurE = 0;
while (edges_refcount.isValidUnsafe(iLastE) == false)
iLastE--;
while (edges_refcount.isValidUnsafe(iCurE))
iCurE++;
DVector<short> eref = edges_refcount.RawRefCounts;

DVector<short> eref = edges_refcount.RawRefCounts;
while (iCurE < iLastE)
{
int kc = iCurE * 4, kl = iLastE * 4;

while (iCurE < iLastE) {
int kc = iCurE * 4, kl = iLastE * 4;
// shift edge
for (int j = 0; j < 4; ++j)
{
edges[kc + j] = edges[kl + j];
}

// shift edge
for (int j = 0; j < 4; ++j) {
edges[kc + j] = edges[kl + j];
// replace edge in vertex edges lists
int v0 = edges[kc], v1 = edges[kc + 1];
vertex_edges.Replace(v0, (eid) => { return eid == iLastE; }, iCurE);
vertex_edges.Replace(v1, (eid) => { return eid == iLastE; }, iCurE);

// replace edge in triangles
replace_triangle_edge(edges[kc + 2], iLastE, iCurE);
if (edges[kc + 3] != DMesh3.InvalidID)
replace_triangle_edge(edges[kc + 3], iLastE, iCurE);

// shift triangle refcount to new position
eref[iCurE] = eref[iLastE];
eref[iLastE] = RefCountVector.invalid;

// move cur forward one, last back one, and then search for next valid
iLastE--; iCurE++;
while (iLastE >= 0 && edges_refcount.isValidUnsafe(iLastE) == false)
iLastE--;
while (edges_refcount.isValidUnsafe(iCurE) && iCurE < iLastE)
iCurE++;
}

// replace edge in vertex edges lists
int v0 = edges[kc], v1 = edges[kc + 1];
vertex_edges.Replace(v0, (eid) => { return eid == iLastE; }, iCurE);
vertex_edges.Replace(v1, (eid) => { return eid == iLastE; }, iCurE);

// replace edge in triangles
replace_triangle_edge(edges[kc + 2], iLastE, iCurE);
if (edges[kc + 3] != DMesh3.InvalidID)
replace_triangle_edge(edges[kc + 3], iLastE, iCurE);

// shift triangle refcount to new position
eref[iCurE] = eref[iLastE];
eref[iLastE] = RefCountVector.invalid;

// move cur forward one, last back one, and then search for next valid
iLastE--; iCurE++;
while (edges_refcount.isValidUnsafe(iLastE) == false)
iLastE--;
while (edges_refcount.isValidUnsafe(iCurE) && iCurE < iLastE)
iCurE++;
// trim edge data structures
edges_refcount.trim(EdgeCount);
edges.resize(EdgeCount * 4);
}

// trim edge data structures
edges_refcount.trim(EdgeCount);
edges.resize(EdgeCount*4);

return ci;
}

Expand Down
Loading