stla/cgalMeshes

Memory corruption issue

Closed this issue · 9 comments

dwoll commented

Adapting my Shiny app to cgalMeshes, I think I've encountered a memory corruption issue. Given the three attached meshes (renamed to *.PLY, the following code reliably crashes R for me (R 4.2.0 on Linux via Windows WSL2, 4.2.1 on Windows 10, error "memory not mapped"). While the crash occurs when calling Rvcg::vcgMetro(), I think the issue is caused earlier on. Depending on previous operations on the cgalMesh objects, the crash occurs in earlier or later calls to vcgMetro(). For example, omitting the calls mesh$volume() and mesh$centroid() makes the code run through without errors. Adding more calls makes R crash earlier.

library(cgalMeshes)
library(SurfaceReconstruction)
library(Rvcg)

read_mesh <- function(x) {
    mesh <- cgalMesh$new(x)
    if(!mesh$isClosed() || !mesh$boundsVolume()) {
        mesh_r <- AFSreconstruction(mesh$vertices())
        mesh   <- cgalMesh$new(mesh_r)
        mesh$orientToBoundVolume()
    }
            
    if(mesh$selfIntersects()) {
        mesh$removeSelfIntersections()
    }

    list(mesh=mesh,
         volume=mesh$volume(),
         centroid=mesh$centroid())
}

get_mesh_metro_pair <- function(x, ...) {
    mesh1_rgl <- x$mesh1$mesh$getMesh(normals=FALSE)
    mesh2_rgl <- x$mesh2$mesh$getMesh(normals=FALSE)
    vcgMetro(mesh1_rgl, mesh2_rgl, ...)
}

## all pairs from list of meshes
get_mesh_pairs <- function(x) {
    pairs_idx <- t(combn(seq_along(x), 2))
    lapply(seq_len(nrow(pairs_idx)), function(i) {
        idx1  <- pairs_idx[i, 1]
        idx2  <- pairs_idx[i, 2]
        mesh1 <- x[[idx1]]
        mesh2 <- x[[idx2]]
        list(mesh1=mesh1, mesh2=mesh2)
    })
}

ff <- list.files("data/", pattern="HEART", full.names=TRUE)

meshL <- Map(read_mesh, ff)

pairL  <- get_mesh_pairs(meshL)
metro1 <- get_mesh_metro_pair(pairL[[1]])
metro2 <- get_mesh_metro_pair(pairL[[2]])
metro3 <- get_mesh_metro_pair(pairL[[3]])

HEART_OBS1.txt
HEART_OBS2.txt
HEART_OBS3.txt

stla commented

Hi,

I reported a bug today to the CGAL team, maybe it's the same issue.

stla commented

The problem regarding the centroid is solved.

dwoll commented

Thanks for looking into this! Further testing showed that in the (simplified) script I use, R does not crash when commenting out the call to removeSelfIntersections(). Otherwise, R crashes for with get_mesh_metro_pair(pairL[[4]]) when vcgMetro() is called. Simply printing the exported mesh3d objects in get_mesh_metro_pair() does not trigger the crash.

library(cgalMeshes)
library(Rvcg)

ff <- list.files("data/", pattern="HEART.+\\.ply", full.names=TRUE)

read_mesh <- function(x) {
    mesh <- cgalMesh$new(x)
    if(!mesh$isClosed() || !mesh$boundsVolume()) {
        mesh_r <- AFSreconstruction(mesh$vertices())
        mesh   <- mesh_r
        mesh$orientToBoundVolume()
    }
    
    # if commenting out the following line, R does not crash
    mesh$removeSelfIntersections()
    mesh
}

get_mesh_metro_pair <- function(x, ...) {
    mesh1_rgl <- x$mesh1$getMesh(normals=FALSE)
    mesh2_rgl <- x$mesh2$getMesh(normals=FALSE)
    vcgMetro(mesh1_rgl, mesh2_rgl, ...)
}

## all pairs from list of meshes
get_mesh_pairs <- function(x) {
    pairs_idx <- t(combn(seq_along(x), 2))
    lapply(seq_len(nrow(pairs_idx)), function(i) {
        idx1  <- pairs_idx[i, 1]
        idx2  <- pairs_idx[i, 2]
        mesh1 <- x[[idx1]]
        mesh2 <- x[[idx2]]
        list(mesh1=mesh1, mesh2=mesh2)
    })
}

meshL  <- lapply(ff, read_mesh)
pairL  <- get_mesh_pairs(meshL)
metro1 <- get_mesh_metro_pair(pairL[[1]])
metro2 <- get_mesh_metro_pair(pairL[[2]])
metro3 <- get_mesh_metro_pair(pairL[[3]])
metro4 <- get_mesh_metro_pair(pairL[[4]])
metro5 <- get_mesh_metro_pair(pairL[[5]])
metro6 <- get_mesh_metro_pair(pairL[[6]])
metro7 <- get_mesh_metro_pair(pairL[[7]])

HEART_OBS1.txt
HEART_OBS2.txt
HEART_OBS3.txt
HEART_OBS4.txt
HEART_OBS5.txt
HEART_OBS6.txt
HEART_OBS7.txt

stla commented

Hi,

removeSelfIntersections calls an experimental CGAL function. Do you know which mesh triggers the crash? I can report this issue to the CGAL team.

stla commented

PS: you don't need the SurfaceReconstruction package anymore: the AFS reconstruction is now implemented in cgalMeshes.

dwoll commented

Good thinking. Perhaps the attached mesh is somewhat responsible. With pairL as defined above, these comparisons all crash:

metro4 <- get_mesh_metro_pair(pairL[[4]])  # mesh 1 vs. 5
metro7 <- get_mesh_metro_pair(pairL[[9]])  # mesh 2 vs. 5
metro16 <- get_mesh_metro_pair(pairL[[16]]) # mesh 4 vs. 5
metro19 <- get_mesh_metro_pair(pairL[[19]]) # mesh 5 vs. 6
metro20 <- get_mesh_metro_pair(pairL[[20]]) # mesh 5 vs. 7

Oddly, this comparison involving mesh 5 does not crash

metro13 <- get_mesh_metro_pair(pairL[[13]]) # mesh 3 vs. 5

HEART_OBS5.txt

stla commented

Thanks. Issue reported: CGAL/cgal#7019

stla commented

Fixed now!

dwoll commented

Great, many thanks! I confirm that R does not crash anymore with the calculations I'm doing.