diff --git a/.clang-format b/.clang-format
index a114609f392618fec5fd1d6907e7298cc71d0ee7..cb0ac8b90a4575b18e8f0491ba08dca9ec846bd4 100644
--- a/.clang-format
+++ b/.clang-format
@@ -54,3 +54,6 @@ AccessModifierOffset: -4
 FixNamespaceComments: false
 AlignTrailingComments: true
 CommentPragmas: '!Api.*'
+
+# Includes
+IncludeBlocks: Preserve
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b0f97b62601aa4646e3e7ec41f8ba5417ee57d09..4a753246cc41d3af84be398883149be2f98ee1d8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,7 +10,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
 set_property(GLOBAL PROPERTY USE_FOLDERS ON)
 
-option(PM_BUILD_TESTS "Build polymesh tests" OFF)
+option(PPOLYMESH_BUILD_TESTS "Build polymesh tests" ON)
 
 
 # ==============================================================================
@@ -107,6 +107,8 @@ foreach(dir ${SAMPLE_DIRS})
 
     target_compile_options(${sample} PUBLIC ${SAMPLE_FLAGS})
 
+    set_property(TARGET ${sample} PROPERTY FOLDER "Samples")
+
 endforeach()
 
 
@@ -146,9 +148,12 @@ endif()
 
 foreach(TARGET_NAME
     polymesh
-    typed-geometry-src
+    typed-geometry
+    ctracer
+    glad
+    glow
+    glow-extras
+    imgui
 )
-    if (TARGET ${TARGET_NAME})
-        set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "Extern")
-    endif()
+    set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "Extern")
 endforeach()
diff --git a/extern/glow b/extern/glow
index 9d530fdab79ef0ab428142e730866cb5e66a3188..fc0789b07bbb79044b020a4a3a8deee4b877d70b 160000
--- a/extern/glow
+++ b/extern/glow
@@ -1 +1 @@
-Subproject commit 9d530fdab79ef0ab428142e730866cb5e66a3188
+Subproject commit fc0789b07bbb79044b020a4a3a8deee4b877d70b
diff --git a/extern/glow-extras b/extern/glow-extras
index 10f97e63e8f73731e33cc0d3159f1b7a10ce5b56..9ce358681287a8cebcf0be4785cace4902f9ee7f 160000
--- a/extern/glow-extras
+++ b/extern/glow-extras
@@ -1 +1 @@
-Subproject commit 10f97e63e8f73731e33cc0d3159f1b7a10ce5b56
+Subproject commit 9ce358681287a8cebcf0be4785cace4902f9ee7f
diff --git a/extern/polymesh b/extern/polymesh
index cd4589aad58e4429311af9d63c2aadb9aeb4d1bd..ee575532d0eba2da77b672219bbda8082638e657 160000
--- a/extern/polymesh
+++ b/extern/polymesh
@@ -1 +1 @@
-Subproject commit cd4589aad58e4429311af9d63c2aadb9aeb4d1bd
+Subproject commit ee575532d0eba2da77b672219bbda8082638e657
diff --git a/extern/typed-geometry b/extern/typed-geometry
index 1d9862713da6b845580b378275cd2c02382a16d4..fceee8531d1eb879f8b4dbb802f879bebb095616 160000
--- a/extern/typed-geometry
+++ b/extern/typed-geometry
@@ -1 +1 @@
-Subproject commit 1d9862713da6b845580b378275cd2c02382a16d4
+Subproject commit fceee8531d1eb879f8b4dbb802f879bebb095616
diff --git a/tests/algorithms/edge_split.cc b/tests/algorithms/edge_split.cc
index a36f804bfc8854efaf98427fb38e8ef4bc9746f5..c37475d628194f99997946a374138344ce887ffa 100644
--- a/tests/algorithms/edge_split.cc
+++ b/tests/algorithms/edge_split.cc
@@ -16,24 +16,72 @@ TEST_CASE("edge split")
 
     tg::rng rng;
     auto s = 8;
-    pm::objects::add_quad(m, [&](auto v, float x, float y) { pos[v] = {x * s + uniform(rng, -.2f, .2f), 0, y * s + uniform(rng, -.2f, .2f)}; }, s, s);
+    pm::objects::add_quad(
+        m,
+        [&](auto v, float x, float y) {
+            pos[v] = {x * s + uniform(rng, -.2f, .2f), 0, y * s + uniform(rng, -.2f, .2f)};
+        },
+        s, s);
 
     pm::triangulate_naive(m);
     m.compactify();
 
-    pm::split_edges_trimesh(m,
-                            [&](pm::edge_handle e) -> tg::optional<float> {
-                                auto l = distance(pos[e.vertexA()], pos[e.vertexB()]);
-                                if (l < 0.2f)
-                                    return {};
-                                return l;
-                            },
-                            [&](pm::vertex_handle v, pm::halfedge_handle, pm::vertex_handle v_from, pm::vertex_handle v_to) {
-                                pos[v] = mix(pos[v_from], pos[v_to], 0.5f);
-                                // is OK! m.assert_consistency();
-                            });
+    pm::split_edges_trimesh(
+        m,
+        [&](pm::edge_handle e) -> tg::optional<float> {
+            auto l = distance(pos[e.vertexA()], pos[e.vertexB()]);
+            if (l < 0.2f)
+                return {};
+            return l;
+        },
+        [&](pm::vertex_handle v, pm::halfedge_handle, pm::vertex_handle v_from, pm::vertex_handle v_to) {
+            pos[v] = mix(pos[v_from], pos[v_to], 0.5f);
+            // is OK! m.assert_consistency();
+        });
 
     return; // DO NOT ACTUALLY SHOW
-    auto v = view(pos);
-    view(lines(pos).line_width_world(0.003f));
+    auto v = gv::view(pos);
+    gv::view(gv::lines(pos).line_width_world(0.003f));
 }
+
+TEST_CASE("edge tri_split")
+{
+    pm::Mesh m;
+    auto v00 = m.vertices().add();
+    auto v10 = m.vertices().add();
+    auto v11 = m.vertices().add();
+    auto v01 = m.vertices().add();
+
+    auto f0 = m.faces().add(v00, v01, v10);
+    auto f1 = m.faces().add(v11, v10, v01);
+
+    m.assert_consistency();
+
+    {
+        auto e = pm::edge_between(v01, v10);
+        CHECK(e.is_valid());
+        auto v = m.edges().split_and_triangulate(e);
+
+        CHECK(v.is_valid());
+        CHECK(pm::edge_between(v, v00).is_valid());
+        CHECK(pm::edge_between(v, v01).is_valid());
+        CHECK(pm::edge_between(v, v10).is_valid());
+        CHECK(pm::edge_between(v, v11).is_valid());
+        CHECK(m.faces().size() == 4);
+        CHECK(m.vertices().size() == 5);
+        CHECK(m.edges().size() == 8);
+        m.assert_consistency();
+    }
+
+    {
+        auto e = pm::edge_between(v00, v01);
+        CHECK(e.is_valid());
+        auto vv = m.edges().split_and_triangulate(e);
+
+        CHECK(vv.is_valid());
+        CHECK(m.faces().size() == 5);
+        CHECK(m.vertices().size() == 6);
+        CHECK(m.edges().size() == 10);
+        m.assert_consistency();
+    }
+}
\ No newline at end of file
diff --git a/tests/viewer/viewer-test.cc b/tests/viewer/viewer-test.cc
index 19832d615118c9231b4c8f32a904887b92763750..cbd301b0c2e0a844b2de94d5a4acf04c2f96b843 100644
--- a/tests/viewer/viewer-test.cc
+++ b/tests/viewer/viewer-test.cc
@@ -13,7 +13,12 @@ TEST_CASE("glow::viewer test")
     pm::Mesh m;
     auto pos = pm::vertex_attribute<tg::pos3>(m);
 
-    pm::objects::add_quad(m, [&](auto v, float x, float y) { pos[v] = {x, 0, y}; }, 32, 32);
+    pm::objects::add_quad(
+        m,
+        [&](auto v, float x, float y) {
+            pos[v] = {x, 0, y};
+        },
+        32, 32);
 
     float noise = 0.01f;
 
@@ -24,7 +29,7 @@ TEST_CASE("glow::viewer test")
         for (auto& p : pos)
             p.y = gaussian(rng, 0.f, noise);
 
-        auto v = view(pos, gv::clear_accumulation(changed));
-        view(lines(pos).line_width_world(0.001f));
+        auto v = gv::view(pos, gv::clear_accumulation(changed));
+        gv::view(gv::lines(pos).line_width_world(0.001f));
     });
 }