Repository: mne-tools/mne-python

Issue:
Dig points disappear under transparent skin surface using mne coreg GUI
### Description of the problem

Hi! Looks like there's something quirky going on with mne coreg. 

Additional points in a head digitization are disappearing from view when they sink beneath the skin surface, regardless of the opacity of the surface. While cHPI coils and EEG sensor locations persist (red & pink dots), additional dig points (white dots) disappear. 

### Steps to reproduce

```Python
1. Set your subjects dir path to point to the "subjects" directory of the MNE sample data set. 
2. In the command line, open `mne coreg`
3. In the "path to info" field, set "sample_audvis_raw.fif" from the mne-python MEG sample dataset as your digitization source. 
4. Using the translation buttons, decrease the y-translation value (hit the down arrow by "tY") until the digitization points in the back of the head cross the head surface.
```


### Link to data

_No response_

### Expected results

White dots should remain visible underneath the skin surface. 

### Actual results

![Screenshot from 2023-10-23 10-29-49](https://github.com/mne-tools/mne-python/assets/38704848/118b1c26-b8e4-4698-9d9f-3f3895b99b58)
![Screenshot from 2023-10-23 10-30-02](https://github.com/mne-tools/mne-python/assets/38704848/65ceed97-5846-44c5-96a2-a10ea815a854)


### Additional information

`>>> mne.sys_info()
Platform             Linux-6.2.0-34-generic-x86_64-with-glibc2.35
Python               3.11.5 | packaged by conda-forge | (main, Aug 27 2023, 03:34:09) [GCC 12.3.0]
Executable           /home/erica/miniconda3/envs/sprint_2023/bin/python
CPU                  x86_64 (24 cores)
Memory               62.7 GB

Core
├☑ mne               1.6.0.dev88+gb9e907667
├☑ numpy             1.26.0 (unknown linalg bindings (threadpoolctl module not found: No module named 'threadpoolctl'))
├☑ scipy             1.11.2
├☑ matplotlib        3.8.0 (backend=QtAgg)
├☑ pooch             1.7.0
└☑ jinja2            3.1.2

Numerical (optional)
├☑ nibabel           5.1.0
├☑ dipy              1.7.0
├☑ pandas            2.1.1
└☐ unavailable       sklearn, numba, nilearn, openmeeg, cupy

Visualization (optional)
├☑ pyvista           0.42.2 (OpenGL 4.6 (Core Profile) Mesa 23.0.4-0ubuntu1~22.04.1 via AMD Radeon RX 570 Series (polaris10, LLVM 15.0.7, DRM 3.49, 6.2.0-34-generic))
├☑ pyvistaqt         0.11.0
├☑ vtk               9.2.6
Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.
├☑ qtpy              2.4.0 (PyQt5=5.15.2)
└☐ unavailable       ipympl, pyqtgraph, mne-qt-browser, ipywidgets, trame_client, trame_server, trame_vtk, trame_vuetify

Ecosystem (optional)
├☑ mne-bids          0.14.dev0
├☑ mne-connectivity  0.6.0dev0
└☐ unavailable       mne-nirs, mne-features, mne-icalabel, mne-bids-pipeline
`


Discussion:
Running this to try to rule some stuff out
```
MNE_COREG_HEAD_OPACITY=0.25 MNE_COREG_ADVANCED_RENDERING=false MNE_COREG_MARK_INSIDE=false mne coreg --subjects-dir=~/mne_data/MNE-sample-data/subjects -s sample -f ~/mne_data/MNE-sample-data/MEG/sample/sample_audvis_raw.fif --trans ~/mne_data/MNE-sample-data/MEG/sample/sample_audvis_raw-trans.fif
```
and then clicking "lock fiducials" and setting the EEG weight to zero (so the EEG electrodes disappear) it's still clear that many extra points are missing:

![Screenshot from 2023-10-23 14-05-34](https://github.com/mne-tools/mne-python/assets/2365790/daef91bf-dc3f-4529-9951-659fd18af4f4)


Will have to look into why this is the case... this is where the plotting happens if you want to look into it before I get a chance to in the coming days @nordme 

https://github.com/mne-tools/mne-python/blob/c54d229913c5fe1bdb7a76b70930f66a89601c95/mne/viz/_3d.py#L1280-L1332

Resolving patch:
diff --git a/mne/commands/mne_coreg.py b/mne/commands/mne_coreg.py
--- a/mne/commands/mne_coreg.py
+++ b/mne/commands/mne_coreg.py
@@ -44,7 +44,7 @@ def run():
         "--tabbed",
         dest="tabbed",
         action="store_true",
-        default=False,
+        default=None,
         help="Option for small screens: Combine "
         "the data source panel and the coregistration panel "
         "into a single panel with tabs.",
@@ -103,6 +103,7 @@ def run():
         "--simple-rendering",
         action="store_false",
         dest="advanced_rendering",
+        default=None,
         help="Use simplified OpenGL rendering",
     )
     _add_verbose_flag(parser)
@@ -131,7 +132,7 @@ def run():
 
     faulthandler.enable()
     mne.gui.coregistration(
-        options.tabbed,
+        tabbed=options.tabbed,
         inst=options.inst,
         subject=options.subject,
         subjects_dir=subjects_dir,
@@ -139,7 +140,7 @@ def run():
         head_opacity=options.head_opacity,
         head_high_res=head_high_res,
         trans=trans,
-        scrollable=True,
+        scrollable=None,
         interaction=options.interaction,
         scale=options.scale,
         advanced_rendering=options.advanced_rendering,
diff --git a/mne/gui/_gui.py b/mne/gui/_gui.py
--- a/mne/gui/_gui.py
+++ b/mne/gui/_gui.py
@@ -7,8 +7,9 @@
 
 @verbose
 def coregistration(
-    tabbed=False,
-    split=True,
+    *,
+    tabbed=None,
+    split=None,
     width=None,
     inst=None,
     subject=None,
@@ -18,15 +19,14 @@ def coregistration(
     head_opacity=None,
     head_high_res=None,
     trans=None,
-    scrollable=True,
-    *,
-    orient_to_surface=True,
-    scale_by_distance=True,
-    mark_inside=True,
+    scrollable=None,
+    orient_to_surface=None,
+    scale_by_distance=None,
+    mark_inside=None,
     interaction=None,
     scale=None,
     advanced_rendering=None,
-    head_inside=True,
+    head_inside=None,
     fullscreen=None,
     show=True,
     block=False,
@@ -143,10 +143,10 @@ def coregistration(
     .. youtube:: ALV5qqMHLlQ
     """
     unsupported_params = {
-        "tabbed": (tabbed, False),
-        "split": (split, True),
-        "scrollable": (scrollable, True),
-        "head_inside": (head_inside, True),
+        "tabbed": tabbed,
+        "split": split,
+        "scrollable": scrollable,
+        "head_inside": head_inside,
         "guess_mri_subject": guess_mri_subject,
         "scale": scale,
         "advanced_rendering": advanced_rendering,
@@ -158,22 +158,17 @@ def coregistration(
             to_raise = val is not None
         if to_raise:
             warn(
-                f"The parameter {key} is not supported with"
-                " the pyvistaqt 3d backend. It will be ignored."
+                f"The parameter {key} is deprecated and will be removed in 1.7, do "
+                "not pass a value for it",
+                FutureWarning,
             )
+    del tabbed, split, scrollable, head_inside, guess_mri_subject, scale
+    del advanced_rendering
     config = get_config()
-    if guess_mri_subject is None:
-        guess_mri_subject = config.get("MNE_COREG_GUESS_MRI_SUBJECT", "true") == "true"
     if head_high_res is None:
         head_high_res = config.get("MNE_COREG_HEAD_HIGH_RES", "true") == "true"
-    if advanced_rendering is None:
-        advanced_rendering = (
-            config.get("MNE_COREG_ADVANCED_RENDERING", "true") == "true"
-        )
     if head_opacity is None:
         head_opacity = config.get("MNE_COREG_HEAD_OPACITY", 0.8)
-    if head_inside is None:
-        head_inside = config.get("MNE_COREG_HEAD_INSIDE", "true").lower() == "true"
     if width is None:
         width = config.get("MNE_COREG_WINDOW_WIDTH", 800)
     if height is None:
@@ -183,23 +178,23 @@ def coregistration(
             subjects_dir = config["SUBJECTS_DIR"]
         elif "MNE_COREG_SUBJECTS_DIR" in config:
             subjects_dir = config["MNE_COREG_SUBJECTS_DIR"]
+    false_like = ("false", "0")
     if orient_to_surface is None:
-        orient_to_surface = config.get("MNE_COREG_ORIENT_TO_SURFACE", "") == "true"
+        orient_to_surface = config.get("MNE_COREG_ORIENT_TO_SURFACE", "true").lower()
+        orient_to_surface = orient_to_surface not in false_like
     if scale_by_distance is None:
-        scale_by_distance = config.get("MNE_COREG_SCALE_BY_DISTANCE", "") == "true"
+        scale_by_distance = config.get("MNE_COREG_SCALE_BY_DISTANCE", "true").lower()
+        scale_by_distance = scale_by_distance not in false_like
     if interaction is None:
         interaction = config.get("MNE_COREG_INTERACTION", "terrain")
     if mark_inside is None:
-        mark_inside = config.get("MNE_COREG_MARK_INSIDE", "") == "true"
-    if scale is None:
-        scale = config.get("MNE_COREG_SCENE_SCALE", 0.16)
+        mark_inside = config.get("MNE_COREG_MARK_INSIDE", "true").lower()
+        mark_inside = mark_inside not in false_like
     if fullscreen is None:
         fullscreen = config.get("MNE_COREG_FULLSCREEN", "") == "true"
     head_opacity = float(head_opacity)
-    head_inside = bool(head_inside)
     width = int(width)
     height = int(height)
-    scale = float(scale)
 
     from ..viz.backends.renderer import MNE_3D_BACKEND_TESTING
     from ._coreg import CoregistrationUI
diff --git a/mne/viz/_3d.py b/mne/viz/_3d.py
--- a/mne/viz/_3d.py
+++ b/mne/viz/_3d.py
@@ -1252,10 +1252,9 @@ def _orient_glyphs(
     proj_pts, proj_nn = _get_nearest(nearest, check_inside, project_to_trans, proj_rr)
     vec = pts - proj_pts  # point to the surface
     nn = proj_nn
+    scalars = np.ones(len(pts))
     if mark_inside and not project_to_surface:
-        scalars = (~check_inside(proj_rr)).astype(int)
-    else:
-        scalars = np.ones(len(pts))
+        scalars[:] = ~check_inside(proj_rr)
     dist = np.linalg.norm(vec, axis=-1, keepdims=True)
     vectors = (250 * dist + 1) * nn
     return scalars, vectors, proj_pts
@@ -1277,28 +1276,16 @@ def _plot_glyphs(
     check_inside=None,
     nearest=None,
 ):
+    from matplotlib.colors import ListedColormap, to_rgba
+
+    _validate_type(mark_inside, bool, "mark_inside")
     if surf is not None and len(loc) > 0:
         defaults = DEFAULTS["coreg"]
         scalars, vectors, proj_pts = _orient_glyphs(
             loc, surf, project_points, mark_inside, check_inside, nearest
         )
         if mark_inside:
-            from matplotlib.colors import ListedColormap
-
-            color = np.append(color, 1)
-            colormap = ListedColormap(
-                np.array(
-                    [
-                        (
-                            0,
-                            0,
-                            0,
-                            1,
-                        ),
-                        color,
-                    ]
-                )
-            )
+            colormap = ListedColormap([to_rgba("darkslategray"), to_rgba(color)])
             color = None
             clim = [0, 1]
         else:


Test patch: