<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged blender</title>
<link>https://coderlegion.com/tag/blender</link>
<description>Powered by Question2Answer</description>
<item>
<title>Designing a High-Converting Forex Landing Page with Framer + 3D Workflow</title>
<link>https://coderlegion.com/14131/designing-a-high-converting-forex-landing-page-with-framer-3d-workflow</link>
<description>&lt;p&gt;I recently worked on a forex landing page concept—not just from a design perspective, but as a full front-end experience.&lt;/p&gt;
&lt;p&gt;The goal wasn’t aesthetics alone.&lt;br&gt;
It was performance, clarity, and conversion.&lt;/p&gt;
&lt;p&gt;Here’s how I approached it:&lt;/p&gt;
&lt;p&gt;– Built in Framer for rapid iteration + production-ready output&lt;br&gt;
– Structured layout to guide user flow (not just visual hierarchy)&lt;br&gt;
– Integrated chart-style visuals to simulate real trading context&lt;br&gt;
– Used subtle motion + depth (inspired by 3D workflows like Blender) without killing performance&lt;br&gt;
– Focused on clean UI + fast load (avoiding heavy embeds like Spline)&lt;/p&gt;
&lt;p&gt;One key thing I’m learning:&lt;/p&gt;
&lt;p&gt;The best “designs” in web today are actually engineered experiences.&lt;/p&gt;
&lt;p&gt;It’s no longer just UI vs Dev.&lt;br&gt;
The line is blurred and tools like Framer are sitting right in the middle.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/14131/designing-a-high-converting-forex-landing-page-with-framer-3d-workflow</guid>
<pubDate>Tue, 07 Apr 2026 06:16:58 +0000</pubDate>
</item>
<item>
<title>I Built an ML Routing Engine for 3D Mesh Retopology — Here's How It Works</title>
<link>https://coderlegion.com/13196/i-built-an-ml-routing-engine-for-3d-mesh-retopology-heres-how-it-works</link>
<description>&lt;p&gt;I've spent the last several months building Quadify Ultra, a Blender 5.0 addon that uses a KNN-based ML engine to automatically route meshes to the right retopology algorithm. This post is about the technical decisions behind it — the parts that were harder than expected and the approaches that actually worked.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-problem-retopology-algorithm-selection-is-a-classification-task&quot;&gt;The problem: retopology algorithm selection is a classification task&lt;/h3&gt;
&lt;p&gt;Retopology — converting triangulated meshes to clean quad topology — isn't one problem. It's five different problems depending on what kind of mesh you're dealing with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open curved panels (car doors, fenders) need edge-flip and greedy quad matching that preserves vertex positions&lt;/li&gt;
&lt;li&gt;CAD imports with hard edges need boundary detection before any merging happens&lt;/li&gt;
&lt;li&gt;Flat CAD surfaces with n-gon triangulation need dissolve passes before quadification&lt;/li&gt;
&lt;li&gt;Closed flat meshes need field-guided remeshing (QuadriFlow)&lt;/li&gt;
&lt;li&gt;Organic meshes and scans with broken topology need voxel rebuilding&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The routing decision — &lt;em&gt;which algorithm for this mesh&lt;/em&gt; — is something experienced artists do implicitly. I wanted to automate it.&lt;/p&gt;
&lt;p&gt;The input features I settled on after testing:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;features = [
    tri_ratio,           # fraction of triangles
    quad_ratio,          # fraction of quads  
    ngon_ratio,          # fraction of n-gons
    boundary_ratio,      # open boundary edges / total edges
    non_manifold_ratio,  # non-manifold edges / total edges
    normal_std,          # standard deviation of face normals (surface curvature proxy)
    edge_length_cv,      # coefficient of variation of edge lengths
    face_area_cv,        # coefficient of variation of face areas
    avg_valence,         # average vertex valence
    pole_ratio,          # fraction of vertices with valence != 4
    # ... 8 more geometric ratios
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;18 features total. All normalised ratios — no absolute values, so the classifier is scale-independent.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-classifier-knn-with-confidence-blending&quot;&gt;The classifier: KNN with confidence blending&lt;/h3&gt;
&lt;p&gt;I went with KNN rather than a neural net for two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Interpretability&lt;/strong&gt; — when the engine recommends Smart mode at 73% confidence, I can inspect the k nearest neighbours and understand why&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cold start&lt;/strong&gt; — a neural net needs hundreds of examples before it's useful. KNN with k=3 gives reasonable results from the first 10 operations&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The confidence score is the fraction of the k nearest neighbours that agree on the top recommendation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def get_confidence(neighbours, top_strategy):
    agreeing = sum(1 for n in neighbours if n['strategy'] == top_strategy)
    return agreeing / len(neighbours)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At low DB count the system blends toward a deterministic heuristic:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;blend_weight = min(1.0, db_count / 30)
confidence = (ml_confidence * blend_weight) + (heuristic_confidence * (1 - blend_weight))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This means the first 30 operations use mostly heuristic routing, gradually transitioning to learned routing as the DB grows.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-hardest-bug-voxel-remesh-freezing-blender&quot;&gt;The hardest bug: voxel remesh freezing Blender&lt;/h3&gt;
&lt;p&gt;The original implementation used &lt;code&gt;bpy.ops.object.voxel_remesh()&lt;/code&gt;. This is a synchronous operator — it runs on Python's main thread and blocks the entire UI. On a 39,000-face burger mesh it produced about 731,000 intermediate voxel faces and froze Blender for several minutes.&lt;/p&gt;
&lt;p&gt;The fix came from reading Quadify Pro's source code. They use a &lt;strong&gt;REMESH modifier&lt;/strong&gt; instead:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;mod              = obj.modifiers.new(&quot;QP_VoxelRebuild&quot;, &quot;REMESH&quot;)
mod.mode         = 'VOXEL'
mod.voxel_size   = max(0.0005, min(0.05, world_diag / resolution))
mod.use_smooth_shade = True
bpy.ops.object.modifier_apply(modifier=mod.name)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The modifier executes in Blender's C stack, not Python. It never blocks the UI. Same result, dramatically faster, works on any mesh size.&lt;/p&gt;
&lt;p&gt;The voxel_size formula needed one more fix. The original code had:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;voxel_size = max(
    min_dim / 20.0,      # THIS was the bug
    local_diag / voxel_resolution,
    0.0005,
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;min_dim / 20.0&lt;/code&gt; floor was designed to prevent microscopic voxels on large meshes, but it overrode the resolution setting for small objects. A burger mesh at 0.2m scale gave &lt;code&gt;min_dim / 20.0 = 0.01&lt;/code&gt; — 15x larger than the resolution-based target of &lt;code&gt;0.00064&lt;/code&gt;. With 0.01 voxels the mesh produced only 3,138 intermediate faces. QuadriFlow then got &lt;code&gt;min(target_faces, 3138)&lt;/code&gt; = 3,138 as its target and produced a low-detail result.&lt;/p&gt;
&lt;p&gt;Fix: remove the floor entirely, use world-space diagonal from &lt;code&gt;matrix_world @ Vector(v)&lt;/code&gt; for scale independence, and add a 150k face cap to prevent genuinely large meshes from freezing:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;bb_world = [obj.matrix_world @ Vector(v) for v in obj.bound_box]
diag = max((p - bb_world[0]).length for p in bb_world)
voxel_size = max(0.0001, min(0.05, diag / voxel_resolution))

# Cap to prevent freeze on large meshes
estimated_faces = (diag / voxel_size) ** 2
if estimated_faces &amp;gt; 150000:
    voxel_size = diag / math.sqrt(150000)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-community-telemetry-system&quot;&gt;The community telemetry system&lt;/h3&gt;
&lt;p&gt;Each opted-in operation sends 18 geometry ratios and the algorithm result to Supabase:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;payload = {
    'version':   1,
    'features':  [float(f) for f in features],  # 18 ratios only
    'strategy':  strategy,
    'quad_pct':  quad_pct,
    'corrected': corrected,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No mesh geometry. No vertex positions. No filenames. Just the feature vector and outcome.&lt;/p&gt;
&lt;p&gt;The fetch uses only &lt;code&gt;apikey&lt;/code&gt; header — no &lt;code&gt;Authorization: Bearer&lt;/code&gt; — because the new Supabase &lt;code&gt;sb_publishable_*&lt;/code&gt; key format explicitly rejects the Authorization header:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;req = urllib.request.Request(url, headers={
    'apikey':  SUPABASE_KEY,
    'Accept':  'application/json',
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Applying the update merges remote records into the local KNN experience DB, with deduplication and Postgres array format handling (&lt;code&gt;{0.1,0.2,...}&lt;/code&gt; → Python list).&lt;/p&gt;
&lt;p&gt;The callback uses &lt;code&gt;bpy.app.timers&lt;/code&gt; to write results back to Blender properties on the main thread — background threads cannot write to Blender properties directly:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def apply_result():
    if _result[0] is None:
        return 0.5  # check again in 0.5s
    success, data = _result[0]
    scene.quadify_ultra.ml_update_status = f&quot;Updated — {total:,} operations&quot;
    return None  # stop timer

bpy.app.timers.register(apply_result, first_interval=0.5)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;numpy-boolean-ambiguity-in-batch-processing&quot;&gt;numpy boolean ambiguity in batch processing&lt;/h3&gt;
&lt;p&gt;One subtle bug that cost time: &lt;code&gt;MeshFeatureExtractor.extract()&lt;/code&gt; returns a numpy array. In the batch loop:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;normal_std = features[5] if features else 0.3  # WRONG
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;if features&lt;/code&gt; on a numpy array raises &lt;code&gt;ValueError: The truth value of an array is ambiguous&lt;/code&gt;. The fix:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;normal_std = float(features[5]) if features is not None else 0.3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;float()&lt;/code&gt; wrapper also prevents numpy scalar type issues downstream in JSON serialisation.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-s-live&quot;&gt;What's live&lt;/h3&gt;
&lt;p&gt;Quadify Ultra is available on Superhive: &lt;a rel=&quot;nofollow&quot; href=&quot;https://superhivemarket.com/products/quadify&quot;&gt;https://superhivemarket.com/products/quadify&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;$200 one-time, Blender 5.0+, MIT licensed. The ML model improves as the community database grows — currently ~160+ operations from early testers.&lt;/p&gt;
&lt;p&gt;Happy to go deeper on any part of the implementation.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Asset credit:&lt;/strong&gt; Car mesh © 2017 Khronos Group. CC BY 4.0 — &lt;a rel=&quot;nofollow&quot; href=&quot;https://creativecommons.org/licenses/by/4.0/&quot;&gt;https://creativecommons.org/licenses/by/4.0/&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/13196/i-built-an-ml-routing-engine-for-3d-mesh-retopology-heres-how-it-works</guid>
<pubDate>Thu, 19 Mar 2026 12:31:11 +0000</pubDate>
</item>
<item>
<title>I Built a Batch Asset Validator for Blender in Python — Here's What I Learned</title>
<link>https://coderlegion.com/12945/i-built-a-batch-asset-validator-for-blender-in-python-heres-what-i-learned</link>
<description>&lt;h2 id=&quot;i-built-a-batch-asset-validator-for-blender-in-python-here-s-what-i-learned&quot;&gt;I Built a Batch Asset Validator for Blender in Python — Here's What I Learned&lt;/h2&gt;
&lt;p&gt;Game developers and 3D artists deal with a problem that doesn't get talked about enough: &lt;strong&gt;you find out your assets are broken after you've already submitted them.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Wrong scale. Tri count way over budget. Missing textures. Unapplied transforms. Negative scale that makes your mesh flip inside-out in Unity. These issues are obvious in hindsight, but catching them manually across a folder of 50 FBX files before every export is the kind of tedious work that either doesn't happen, or happens inconsistently.&lt;/p&gt;
&lt;p&gt;So I built AssetSentinel — a Blender addon that batch validates FBX and glTF assets against a target platform profile before they leave your machine. Here's the technical breakdown of how it works, what I ran into building it, and a full demo video at the end.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-core-problem-validation-belongs-before-export-not-after&quot;&gt;The Core Problem: Validation Belongs Before Export, Not After&lt;/h3&gt;
&lt;p&gt;Most 3D pipelines look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Model → Export FBX/glTF → Import to Engine → Discover problem → Go back to Blender
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The discovery step is the expensive one. If you're submitting to a marketplace like Fab or CGTrader, a rejection costs you review time. If you're a studio delivering to a client, it costs credibility. The fix is moving validation to before the export step:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Model → Validate → Fix → Export FBX/glTF → Import to Engine
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's what AssetSentinel does.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;how-it-works-temp-scene-import-loop&quot;&gt;How It Works: Temp Scene Import Loop&lt;/h3&gt;
&lt;p&gt;The core mechanism is a &lt;strong&gt;modal operator&lt;/strong&gt; that imports each file into a temporary Blender scene, runs a series of checks, then destroys the scene and moves to the next file. This keeps the user's working scene completely untouched.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def _evaluate_in_temp_scene(context, path: str, profile: dict) -&amp;gt; dict:
    win = context.window
    orig_scene = win.scene
    temp_scene = bpy.data.scenes.new(name=&quot;ASSETSENTINEL_TEMP&quot;)
    win.scene = temp_scene
    try:
        _import_file(path)
        # run all checks here
        tris, verts = _tri_vert_counts()
        ngons = _ngon_count()
        # ... more checks
    except Exception:
        # classify the import failure
        detail = _tb_last_meaningful_line(traceback.format_exc())
        ftype, suggestion = _classify_import_failure(detail)
    finally:
        win.scene = orig_scene
        bpy.data.scenes.remove(temp_scene)
        bpy.ops.outliner.orphans_purge(do_recursive=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;finally&lt;/code&gt; block is non-negotiable. You have to restore the original scene and purge orphan data whether the import succeeded or failed — otherwise you accumulate stale mesh data across every file in the batch.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-modal-operator-pattern&quot;&gt;The Modal Operator Pattern&lt;/h3&gt;
&lt;p&gt;Blender's UI locks up if you run long operations on the main thread. The solution is a &lt;strong&gt;modal operator&lt;/strong&gt; driven by a timer event. Each tick of the timer processes one file, then yields back to Blender so the UI stays responsive and the user can cancel with ESC.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def modal(self, context, event):
    wm = context.window_manager
    if event.type == &quot;ESC&quot;:
        wm.assetsentinel_cancel_requested = True
    if event.type != &quot;TIMER&quot;:
        return {&quot;PASS_THROUGH&quot;}
    if self._idx &amp;gt;= len(self._files):
        wm.assetsentinel_status = &quot;Done&quot;
        return self._finish(context, cancelled=False)
    # process one file per tick
    path = self._files[self._idx]
    res = _evaluate_in_temp_scene(context, path, prof)
    self._results.append(res)
    self._idx += 1
    wm.assetsentinel_progress = int((self._idx / len(self._files)) * 100)
    return {&quot;RUNNING_MODAL&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The timer interval is 0.1 seconds. Fast enough to feel responsive, slow enough not to hammer the CPU.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;profile-based-validation&quot;&gt;Profile-Based Validation&lt;/h3&gt;
&lt;p&gt;Rather than hardcoding limits, AssetSentinel uses &lt;strong&gt;JSON profiles&lt;/strong&gt; — one per target platform. Each profile defines the limits that matter for that destination:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;UNITY_MOBILE&quot;: {
    &quot;label&quot;: &quot;Unity - Mobile&quot;,
    &quot;max_tris&quot;: 20000,
    &quot;max_texture_res&quot;: 2048,
    &quot;max_material_slots&quot;: 4,
    &quot;lod_required&quot;: true,
    &quot;no_spaces&quot;: true,
    &quot;min_bbox_m&quot;: 0.05,
    &quot;max_bbox_m&quot;: 10.0,
    &quot;tri_over_is_error&quot;: true,
    &quot;lod_missing_is_error&quot;: false
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;_is_error&lt;/code&gt; flags per rule let you configure severity independently. A tri count violation might be a hard error on mobile, but only a warning on desktop. The profile system auto-merges on load — if a user has an older &lt;code&gt;profiles.json&lt;/code&gt;, new keys from the defaults get added without losing their custom values.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-checks&quot;&gt;The Checks&lt;/h3&gt;
&lt;p&gt;Here's what runs on every imported asset:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Geometry:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Triangle and vertex count via &lt;code&gt;me.calc_loop_triangles()&lt;/code&gt; — falls back to bmesh triangulate if that fails&lt;/li&gt;
&lt;li&gt;Ngon detection by checking &lt;code&gt;p.loop_total &amp;gt; 4&lt;/code&gt; on every polygon&lt;/li&gt;
&lt;li&gt;Negative scale on any axis&lt;/li&gt;
&lt;li&gt;Unapplied transforms (scale/rotation not at identity)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Textures:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Total image count from &lt;code&gt;bpy.data.images&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;External file resolution — whether the filepath exists on disk&lt;/li&gt;
&lt;li&gt;Max texture resolution from &lt;code&gt;img.size[0]&lt;/code&gt; and &lt;code&gt;img.size[1]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Missing external textures list&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Naming:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Regex match against &lt;code&gt;allowed_name_chars&lt;/code&gt; from the profile&lt;/li&gt;
&lt;li&gt;Space detection in object and material names&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Scale:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;World-space bounding box via &lt;code&gt;evaluated_get(depsgraph).bound_box&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Compared against &lt;code&gt;min_bbox_m&lt;/code&gt; and &lt;code&gt;max_bbox_m&lt;/code&gt; in the profile&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;LOD:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Name-based detection — checks for &lt;code&gt;_LOD0&lt;/code&gt;, &lt;code&gt;_LOD1&lt;/code&gt;, &lt;code&gt;_LOD2&lt;/code&gt;, &lt;code&gt;_LOD3&lt;/code&gt; substrings&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;import-failure-classification&quot;&gt;Import Failure Classification&lt;/h3&gt;
&lt;p&gt;One of the more useful features: when an import fails, it doesn't just say &quot;import error.&quot; It classifies the failure and suggests a fix:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def _classify_import_failure(detail_line: str) -&amp;gt; tuple[str, str]:
    s = (detail_line or &quot;&quot;).lower()
    if &quot;khr_texture_basisu&quot; in s:
        return (
            &quot;UNSUPPORTED_EXTENSION&quot;,
            &quot;Re-export without BasisU/KHR_texture_basisu and try again.&quot;
        )
    if &quot;bad gltf&quot; in s and &quot;json error&quot; in s:
        return (
            &quot;INVALID_GLTF&quot;,
            &quot;The glTF/GLB appears corrupted. Re-export from your DCC.&quot;
        )
    return (&quot;UNKNOWN&quot;, &quot;Try re-exporting and verify the file opens in Blender.&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is genuinely useful in practice. &lt;code&gt;KHR_texture_basisu&lt;/code&gt; failures come up frequently with AI-generated GLB files and photogrammetry exports. The error message from Blender's importer isn't helpful on its own — this surfaces the actual fix.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-html-report&quot;&gt;The HTML Report&lt;/h3&gt;
&lt;p&gt;After the scan, results are exported as an HTML report with a CSV alongside it. The report uses a dark theme, shows per-asset pass/warning/fail status with a triangle count bar against the profile limit, and includes filter controls to show only failed or warning assets.&lt;/p&gt;
&lt;p&gt;The report also surfaces &quot;top violations&quot; — which checks failed most frequently across the batch. On a folder of 26 game assets, the most common failures were tri count overages and suspicious bounding box scales. Both are things that would have caused problems in the engine.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;watch-the-full-demo&quot;&gt;Watch the Full Demo&lt;/h3&gt;
&lt;p&gt;[embed: https://www.youtube.com/watch?v=64qQiMLCSD0]&lt;/p&gt;
&lt;p&gt;The video walks through a real batch scan of 26 assets against the Unreal Desktop profile — showing the scan running, reading the HTML report, and interpreting the results.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;get-the-addon&quot;&gt;Get the Addon&lt;/h3&gt;
&lt;p&gt;AssetSentinel is available on Superhive (Blender Market): &lt;a rel=&quot;nofollow&quot; href=&quot;https://superhivemarket.com/products/assetsentinel&quot;&gt;https://superhivemarket.com/products/assetsentinel&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Supports Blender 3.6 and above. No external dependencies — pure Python, no PyPI packages.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-i-d-do-differently&quot;&gt;What I'd Do Differently&lt;/h3&gt;
&lt;p&gt;A few things I'd approach differently if I started over:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Results storage.&lt;/strong&gt; I'm serialising the results to JSON and storing them in a &lt;code&gt;WindowManager&lt;/code&gt; property string. It works but it's awkward — a proper addon-level data store would be cleaner.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The modal pattern.&lt;/strong&gt; The timer-based modal is the right approach for Blender, but the 0.1s interval is a guess. A smarter approach would adapt the interval based on file size or import time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Profile UI.&lt;/strong&gt; Right now profiles are JSON files edited externally. An in-panel profile editor would make this accessible to artists who don't want to touch JSON.&lt;/p&gt;
&lt;p&gt;Happy to answer questions about any part of the implementation — drop them in the comments.&lt;/p&gt;
&lt;hr&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/12945/i-built-a-batch-asset-validator-for-blender-in-python-heres-what-i-learned</guid>
<pubDate>Mon, 16 Mar 2026 13:58:07 +0000</pubDate>
</item>
<item>
<title>ThreeDimensions Version-1.0.0 is here !</title>
<link>https://coderlegion.com/12471/threedimensions-version-1-0-0-is-here</link>
<description>&lt;h2 id=&quot;threedimensions&quot;&gt;ThreeDimensions&lt;/h2&gt;
&lt;p&gt;Version-1.0.0 Repo - &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/LegedsDaD/ThreeDimensions-v1.1.1&quot;&gt;https://github.com/LegedsDaD/ThreeDimensions-v1.1.1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ThreeDimensions is a programmable 3D modeling library for Python, backed by a C++ geometry kernel for heavy mesh operations.&lt;/p&gt;
&lt;p&gt;Do check out &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/LegedsDaD/ThreeDimensions&quot;&gt;Main Repository&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;send-your-creations-using-threedimensions-in-models-by-filling-in-the-form-the-best-models-will-be-added-to-the-examples-of-threedimensions-others-will-be-added-to-the-models-groups-see-current-submissions-in-submissions-do-participate-&quot;&gt;Send your creations using ThreeDimensions in &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/LegedsDaD/Models&quot;&gt;Models&lt;/a&gt; by filling in the &lt;a rel=&quot;nofollow&quot; href=&quot;https://forms.gle/Z8WpocwLCv92MZU17&quot;&gt;Form&lt;/a&gt;. The best models will be added to the examples of ThreeDimensions. Others will be added to the models groups. See current submissions in &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/LegedsDaD/Models/blob/main/README.md&quot;&gt;Submissions&lt;/a&gt;. Do participate !&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Version: 1.0.0&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Python-first API (&lt;code&gt;import threedimensions as td&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;C++ core for mesh math/topology/modifiers when available&lt;/li&gt;
&lt;li&gt;Pure-Python fallback so the package remains usable without compiling native code&lt;/li&gt;
&lt;li&gt;Half-edge/topology-oriented editing workflow with sculpt, modifiers, curves, nodes, UV tools, and export&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;feature-highlights&quot;&gt;Feature Highlights&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Transform system: move/rotate/scale, pivot modes, snapping, mirror transform, proportional falloff&lt;/li&gt;
&lt;li&gt;Selection: vertex/edge/face, loop/ring, box/circle/lasso, select similar&lt;/li&gt;
&lt;li&gt;Editing: extrude, inset, bevel, bridge, fill, grid fill, subdivide, loop cut, spin, screw, solidify, wireframe&lt;/li&gt;
&lt;li&gt;Deformation: bend, twist, taper, stretch, shear, warp&lt;/li&gt;
&lt;li&gt;Symmetry: mirror and symmetrize helpers&lt;/li&gt;
&lt;li&gt;Sculpt: draw/clay/inflate/smooth/grab/pinch/crease/mask style brush workflow + filters&lt;/li&gt;
&lt;li&gt;Remesh/reduction: voxel remesh, quad remesh, decimate&lt;/li&gt;
&lt;li&gt;Primitives: cube, sphere, UV sphere, icosphere, cylinder, cone, torus, plane, grid&lt;/li&gt;
&lt;li&gt;Curves: Bezier, NURBS-style fallback, lathe, curve-to-mesh&lt;/li&gt;
&lt;li&gt;UV: unwrap, smart UV project, project from view, seams&lt;/li&gt;
&lt;li&gt;Retopo helpers: shrinkwrap, poly build, relax topology&lt;/li&gt;
&lt;li&gt;Modifier stack: subdivision, mirror, array, solidify, boolean, decimate, lattice&lt;/li&gt;
&lt;li&gt;Procedural NodeGraph API&lt;/li&gt;
&lt;li&gt;Optional OpenGL viewer (&lt;code&gt;td.viewer(mesh)&lt;/code&gt; or &lt;code&gt;with td.viewer() as scene&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;installation&quot;&gt;Installation&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install pip install threedimensions==1.1.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Optional viewer dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install glfw PyOpenGL
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;quick-start&quot;&gt;Quick Start&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import threedimensions as td

mesh = td.create_cube(1.0)
mesh.extrude(distance=0.2)
mesh.bevel(width=0.05)
mesh.subdivide(1)
mesh.save(&quot;model.obj&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;geometry-nodes-programmable-&quot;&gt;Geometry Nodes (Programmable)&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import threedimensions as td

graph = td.NodeGraph()
cube = graph.node(&quot;Cube&quot;, size=1.0)
subdiv = graph.node(&quot;Subdivision&quot;, levels=2)
extrude = graph.node(&quot;Extrude&quot;, distance=0.25)

graph.connect(cube, subdiv)
graph.connect(subdiv, extrude)

mesh = graph.evaluate()
mesh.save(&quot;graph.obj&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;viewer&quot;&gt;Viewer&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import threedimensions as td

mesh = td.create_torus()
td.viewer(mesh)  # blocking preview

with td.viewer() as scene:
    scene.update(mesh)
    scene.run()
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;architecture&quot;&gt;Architecture&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;python/threedimensions/&lt;/code&gt;: high-level Python API wrappers, fallback implementations, procedural nodes, viewer&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;license&quot;&gt;License&lt;/h3&gt;
&lt;p&gt;MIT&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/12471/threedimensions-version-1-0-0-is-here</guid>
<pubDate>Sun, 08 Mar 2026 05:38:07 +0000</pubDate>
</item>
<item>
<title>Why We Built a Deterministic Render Gate for Blender (and Why “Final” Is a Lie Without One)</title>
<link>https://coderlegion.com/10920/why-we-built-a-deterministic-render-gate-for-blender-and-why-final-is-a-lie-without-one</link>
<description>&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=11626053117748585632&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Most render failures don’t come from bugs.&lt;br&gt;
They come from assumptions.&lt;/p&gt;
&lt;p&gt;Assumptions that a scene hasn’t changed.&lt;br&gt;
That a render engine behaves “close enough.”&lt;br&gt;
That “Final” actually means final.&lt;/p&gt;
&lt;p&gt;After watching too many late-stage renders slip through with subtle but expensive problems, we started asking a different question:&lt;/p&gt;
&lt;p&gt;What would a render system look like if it treated “FINAL” as a contract instead of a label?&lt;/p&gt;
&lt;p&gt;That question eventually became RenderForge.&lt;/p&gt;
&lt;p&gt;The Problem With Traditional Render Validation&lt;/p&gt;
&lt;p&gt;Most render checks are advisory:&lt;/p&gt;
&lt;p&gt;warnings in the console&lt;/p&gt;
&lt;p&gt;notes in a checklist&lt;/p&gt;
&lt;p&gt;tribal knowledge passed between artists and TDs&lt;/p&gt;
&lt;p&gt;None of that is enforceable.&lt;br&gt;
None of it is auditable.&lt;br&gt;
And none of it survives a late-night change.&lt;/p&gt;
&lt;p&gt;In practice, “Final” usually means:&lt;/p&gt;
&lt;p&gt;“We hope nothing important changed.”&lt;/p&gt;
&lt;p&gt;That’s not good enough in production.&lt;/p&gt;
&lt;p&gt;A Different Approach: Deterministic Gates&lt;/p&gt;
&lt;p&gt;RenderForge was built around a simple principle:&lt;/p&gt;
&lt;p&gt;If a render is allowed, the system must be able to explain why.&lt;/p&gt;
&lt;p&gt;That means:&lt;/p&gt;
&lt;p&gt;Extracting stable scene facts&lt;/p&gt;
&lt;p&gt;Resolving all validation through a single failure taxonomy&lt;/p&gt;
&lt;p&gt;Treating intent (PREVIEW / LOOKDEV / FINAL) as a first-class input&lt;/p&gt;
&lt;p&gt;Blocking renders when assumptions are violated&lt;/p&gt;
&lt;p&gt;Recording exactly what was approved and under what risk&lt;/p&gt;
&lt;p&gt;No heuristics. No silent overrides.&lt;/p&gt;
&lt;p&gt;Hard vs Soft Failures (and Why This Matters)&lt;/p&gt;
&lt;p&gt;One of the biggest mistakes in tooling is treating all warnings equally.&lt;/p&gt;
&lt;p&gt;RenderForge separates failures into:&lt;/p&gt;
&lt;p&gt;HARD: delivery is invalid (blocked)&lt;/p&gt;
&lt;p&gt;SOFT: delivery is allowed only with explicit acknowledgement&lt;/p&gt;
&lt;p&gt;This distinction lets the system be strict without being dogmatic.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;Eevee FINAL isn’t banned outright&lt;/p&gt;
&lt;p&gt;It’s allowed only under defended constraints&lt;/p&gt;
&lt;p&gt;Any remaining approximation risk must be acknowledged&lt;/p&gt;
&lt;p&gt;Nothing is hidden. Nothing is implied.&lt;/p&gt;
&lt;p&gt;Approval as a Contract, Not a Button&lt;/p&gt;
&lt;p&gt;In RenderForge, approval isn’t a snapshot — it’s a contract.&lt;/p&gt;
&lt;p&gt;Approval records:&lt;/p&gt;
&lt;p&gt;the exact scene fingerprint&lt;/p&gt;
&lt;p&gt;the declared intent&lt;/p&gt;
&lt;p&gt;the render engine&lt;/p&gt;
&lt;p&gt;the policy version&lt;/p&gt;
&lt;p&gt;Which risks were acknowledged&lt;/p&gt;
&lt;p&gt;Change anything meaningful, and approval becomes stale automatically.&lt;/p&gt;
&lt;p&gt;No one has to remember to re-check.&lt;br&gt;
The system refuses to forget.&lt;/p&gt;
&lt;p&gt;Why This Is Interesting (Even If You Never Use the Tool)&lt;/p&gt;
&lt;p&gt;Even if you never install RenderForge, the idea is transferable:&lt;/p&gt;
&lt;p&gt;Deterministic validation beats best-effort checks&lt;/p&gt;
&lt;p&gt;Explicit risk acceptance beats silent warnings&lt;/p&gt;
&lt;p&gt;Systems should explain themselves when they block work&lt;/p&gt;
&lt;p&gt;“Final” should mean something measurable.&lt;/p&gt;
&lt;p&gt;Curious how others are handling render approval and late-stage drift. How do you keep ‘final’ honest in your pipeline?&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/10920/why-we-built-a-deterministic-render-gate-for-blender-and-why-final-is-a-lie-without-one</guid>
<pubDate>Mon, 02 Feb 2026 08:32:55 +0000</pubDate>
</item>
<item>
<title>Quadify Base, Premium, &amp; Pro</title>
<link>https://coderlegion.com/10721/quadify-base-premium-pro</link>
<description>&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=10382318079265432838&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=13977448222272469012&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=11643339873590559760&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;I’ve just released three variants of Quadify on Superhive: Base, Premium, and Pro.&lt;/p&gt;
&lt;p&gt;Quadify is a Blender toolset built around one idea:&lt;br&gt;
mesh cleanup and quad generation should be deterministic, intentional, and fast — not a guessing game.&lt;/p&gt;
&lt;p&gt;This isn’t a replacement for manual retopology tools. It’s designed to be used before them, when you’re dealing with messy geometry and trying to decide how much work is actually worth doing.&lt;/p&gt;
&lt;p&gt;Here’s how the three variants are intentionally scoped:&lt;/p&gt;
&lt;p&gt;Quadify Base&lt;br&gt;
Focused on safe, predictable tri-to-quad conversion.&lt;br&gt;
It handles the obvious cleanup first, preserves seams and materials, and clearly shows what still needs manual attention.&lt;br&gt;
Built for speed and transparency, not magic.&lt;/p&gt;
&lt;p&gt;Quadify Premium&lt;br&gt;
Adds manual quadification and region-based control.&lt;br&gt;
You decide where topology is rebuilt and what stays untouched.&lt;br&gt;
This turns quad cleanup into a deterministic decision process instead of a global operation you hope works.&lt;/p&gt;
&lt;p&gt;Quadify Pro&lt;br&gt;
Built for production pipelines and scale.&lt;br&gt;
Includes pipeline workflows, automation recipes, LOD generation, texel density tools, validation, and reporting.&lt;br&gt;
The focus here is repeatability and trust — knowing an asset is actually ready for downstream use.&lt;/p&gt;
&lt;p&gt;All three share the same core philosophy:&lt;/p&gt;
&lt;p&gt;deterministic behavior&lt;/p&gt;
&lt;p&gt;visibility before action&lt;/p&gt;
&lt;p&gt;control before commitment&lt;/p&gt;
&lt;p&gt;If you work with scans, AI-generated meshes, imported assets, or production pipelines where cleanup keeps breaking things, Quadify is meant to remove the mechanical, repeatable pain — not replace artistic judgment.&lt;/p&gt;
&lt;p&gt;The full release is live here on Superhive:&lt;br&gt;
 &lt;a rel=&quot;nofollow&quot; href=&quot;https://superhivemarket.com/products/quadify&quot;&gt;https://superhivemarket.com/products/quadify&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Happy to answer questions about design decisions, scope tradeoffs, or why certain things are intentionally not automated.&lt;/p&gt;
</description>
<category>Launches</category>
<guid isPermaLink="true">https://coderlegion.com/10721/quadify-base-premium-pro</guid>
<pubDate>Thu, 29 Jan 2026 15:54:44 +0000</pubDate>
</item>
<item>
<title>I build Blender automation tools. What repetitive production task should not exist anymore?</title>
<link>https://coderlegion.com/10720/build-blender-automation-tools-what-repetitive-production-task-should-not-exist-anymore</link>
<description>&lt;p&gt;I build Blender tools with a focus on automation and production speed, primarily for game art workflows.&lt;/p&gt;
&lt;p&gt;Before deciding what to build next, I want to hear directly from people who use Blender seriously and run into the same problems over and over—the kind where you think “this should not be manual in 2026.”&lt;/p&gt;
&lt;p&gt;I’m not looking for abstract feature ideas or wishlist items. I’m looking for concrete, repeatable pain points that:&lt;/p&gt;
&lt;p&gt;You hit frequently (daily or weekly)&lt;/p&gt;
&lt;p&gt;Are tedious, mechanical, or error-prone&lt;/p&gt;
&lt;p&gt;Feel like they should be solvable with a tool or add-on&lt;/p&gt;
&lt;p&gt;Aren’t already cleanly solved by an existing addon&lt;/p&gt;
&lt;p&gt;If you respond, please be specific. Context matters more than volume.&lt;/p&gt;
&lt;p&gt;Helpful examples:&lt;/p&gt;
&lt;p&gt;“When doing X, I always have to manually do A → B → C because Blender doesn’t expose Y.”&lt;/p&gt;
&lt;p&gt;“This part of my pipeline breaks unless I double-check Z every time.”&lt;/p&gt;
&lt;p&gt;“I waste time fixing the same class of mistake over and over.”&lt;/p&gt;
&lt;p&gt;Less helpful:&lt;/p&gt;
&lt;p&gt;“Blender’s UI is bad”&lt;/p&gt;
&lt;p&gt;“I want Maya feature X”&lt;/p&gt;
&lt;p&gt;“Everything should be procedural”&lt;/p&gt;
&lt;p&gt;If it helps, you can include:&lt;/p&gt;
&lt;p&gt;Your role (environment artist, character artist, tech artist, etc.)&lt;/p&gt;
&lt;p&gt;The kind of assets you work on&lt;/p&gt;
&lt;p&gt;Where the friction shows up (modeling, UVs, baking, export, scene management, cleanup, validation, etc.)&lt;/p&gt;
&lt;p&gt;I can’t promise I’ll build everything that’s mentioned, but I will prioritize problems that show up across multiple workflows and can be solved cleanly.&lt;/p&gt;
&lt;p&gt;If you’ve ever thought “I should script this, but I don’t have time,” that’s exactly the kind of problem I want to hear about.&lt;/p&gt;
&lt;p&gt;PS: Anyone whose suggestion I build will get a free copy with long-term support.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/10720/build-blender-automation-tools-what-repetitive-production-task-should-not-exist-anymore</guid>
<pubDate>Thu, 29 Jan 2026 15:46:17 +0000</pubDate>
</item>
<item>
<title>Demo video of smart uv tool at work</title>
<link>https://coderlegion.com/9298/demo-video-of-smart-uv-tool-at-work</link>
<description>&lt;p&gt;UV unwrapping shouldn’t feel like punishment.&lt;br&gt;
Smart UV Tool analyzes your mesh and unwraps it clean, fast, and distortion-free in one click.&lt;br&gt;
No stretching.&lt;br&gt;
No messy islands.&lt;br&gt;
No “why does this look like that?” moments.&lt;br&gt;
Built for artists who value speed, precision, and sanity.&lt;br&gt;
You can get this addon here &lt;a rel=&quot;nofollow&quot; href=&quot;https://superhivemarket.com/products/smart-uv-tool&quot;&gt;https://superhivemarket.com/products/smart-uv-tool&lt;/a&gt;&lt;/p&gt;
</description>
<category>Videos</category>
<guid isPermaLink="true">https://coderlegion.com/9298/demo-video-of-smart-uv-tool-at-work</guid>
<pubDate>Tue, 06 Jan 2026 09:10:35 +0000</pubDate>
</item>
<item>
<title>Scene cleanup wizard</title>
<link>https://coderlegion.com/9099/scene-cleanup-wizard</link>
<description>&lt;p&gt;Ever opened a Blender file and instantly regretted it?&lt;br&gt;
Unused data, messy meshes, broken transforms, random names everywhere.&lt;br&gt;
Scene Cleanup Wizard fixes all of that in one click.&lt;br&gt;
Clean scene. Smooth workflow. Less stress.&lt;/p&gt;
</description>
<category>Dev Tools</category>
<guid isPermaLink="true">https://coderlegion.com/9099/scene-cleanup-wizard</guid>
<pubDate>Tue, 30 Dec 2025 21:06:37 +0000</pubDate>
</item>
<item>
<title>Quadify</title>
<link>https://coderlegion.com/8733/quadify</link>
<description>&lt;p&gt;Quadify: Manual Selective Quadification for Real Production Assets&lt;/p&gt;
&lt;p&gt;Quadify is a Blender-based quadification tool designed around a simple observation:&lt;/p&gt;
&lt;p&gt;Most production meshes do not benefit from global quadification.&lt;/p&gt;
&lt;p&gt;Real assets are mixed by nature — hard-surface and organic elements, deforming and static parts, scanned and authored geometry — often combined in a single model. Treating all of that geometry as a uniform problem leads to unnecessary topology damage, cleanup work, and loss of author intent.&lt;/p&gt;
&lt;p&gt;Quadify introduces a manual selective quadification workflow that allows artists to decide where quadification should be applied and where it should not.&lt;/p&gt;
&lt;p&gt;The Problem Quadify Is Addressing&lt;/p&gt;
</description>
<category>Productivity Tools</category>
<guid isPermaLink="true">https://coderlegion.com/8733/quadify</guid>
<pubDate>Mon, 22 Dec 2025 16:10:47 +0000</pubDate>
</item>
<item>
<title>Manual Selective Quadification: Taking Back Control of Retopology</title>
<link>https://coderlegion.com/8732/manual-selective-quadification-taking-back-control-of-retopology</link>
<description>&lt;p&gt;Quadification is often discussed as if it were a single operation: press a button, convert triangles to quads, and move on.&lt;/p&gt;
&lt;p&gt;In real production environments, that framing is misleading.&lt;/p&gt;
&lt;p&gt;Meshes used in games, VFX, visualization, and technical pipelines are rarely uniform. They are layered artifacts—built over time, modified by different tools, combined from scans, CAD data, or kitbashed parts. Expecting a single global quadification pass to treat all of that geometry appropriately is not only unrealistic, it is often counterproductive.&lt;/p&gt;
&lt;p&gt;This update introduces Manual Selective Quadification, a workflow designed around how assets are actually built and used. Rather than attempting to “solve” topology everywhere, it allows artists to decide where quadification is appropriate, where it is unnecessary, and where it should be avoided entirely.&lt;/p&gt;
&lt;p&gt;This article explains the reasoning behind that design, how to use it effectively, and why selective quadification is often the most technically correct approach.&lt;/p&gt;
&lt;p&gt;What Quadification Is Really For&lt;/p&gt;
&lt;p&gt;Quadification is not an aesthetic goal.&lt;br&gt;
It is a functional intervention.&lt;/p&gt;
&lt;p&gt;Quads are valuable because they:&lt;/p&gt;
&lt;p&gt;Deform predictably during animation&lt;/p&gt;
&lt;p&gt;Subdivide cleanly&lt;/p&gt;
&lt;p&gt;Support sculpting and surface refinement&lt;/p&gt;
&lt;p&gt;Produce more stable shading under certain workflows&lt;/p&gt;
&lt;p&gt;But not all geometry needs these properties.&lt;/p&gt;
&lt;p&gt;Many real-world assets include:&lt;/p&gt;
&lt;p&gt;Rigid mechanical components&lt;/p&gt;
&lt;p&gt;Flat or planar surfaces&lt;/p&gt;
&lt;p&gt;Boolean-heavy CAD geometry&lt;/p&gt;
&lt;p&gt;Already-acceptable triangulation&lt;/p&gt;
&lt;p&gt;Non-deforming or secondary elements&lt;/p&gt;
&lt;p&gt;Applying quadification indiscriminately to these areas does not improve the asset. In many cases, it actively degrades it by introducing unnecessary edge flow, breaking hard edges, or increasing cleanup time.&lt;/p&gt;
&lt;p&gt;The mistake is treating quadification as a requirement rather than a tool.&lt;/p&gt;
&lt;p&gt;Why Global Quadification Breaks Down&lt;/p&gt;
&lt;p&gt;Global quadification workflows implicitly assume three things:&lt;/p&gt;
&lt;p&gt;All parts of a mesh have the same topology needs&lt;/p&gt;
&lt;p&gt;A single algorithmic strategy is suitable everywhere&lt;/p&gt;
&lt;p&gt;Artistic intent can be inferred from geometry alone&lt;/p&gt;
&lt;p&gt;These assumptions do not hold in production.&lt;/p&gt;
&lt;p&gt;Consider a vehicle model:&lt;/p&gt;
&lt;p&gt;Tires benefit from controlled quad flow&lt;/p&gt;
&lt;p&gt;Body panels may already be clean&lt;/p&gt;
&lt;p&gt;Interior parts may never deform&lt;/p&gt;
&lt;p&gt;Bolts, trims, and small details often should remain untouched&lt;/p&gt;
&lt;p&gt;A global quadification pass treats all of these regions as equivalent problems. The result is predictable: some areas improve, others degrade, and the overall cleanup cost increases.&lt;/p&gt;
&lt;p&gt;Manual Selective Quadification exists to break this pattern.&lt;/p&gt;
&lt;p&gt;The Core Idea: Apply Automation Only Where It Helps&lt;/p&gt;
&lt;p&gt;Selective quadification is built on a simple premise:&lt;/p&gt;
&lt;p&gt;The artist already knows which parts of the mesh are problematic.&lt;/p&gt;
&lt;p&gt;Instead of forcing automation to guess, the workflow allows the artist to explicitly declare intent.&lt;/p&gt;
&lt;p&gt;This shifts the role of automation:&lt;/p&gt;
&lt;p&gt;From decision-maker → to execution engine&lt;/p&gt;
&lt;p&gt;From global transformer → to localized operator&lt;/p&gt;
&lt;p&gt;Automation still does the heavy lifting—but only where it has been invited to do so.&lt;/p&gt;
&lt;p&gt;Selection as a Technical Signal&lt;/p&gt;
&lt;p&gt;In this workflow, selection is not just a UI convenience.&lt;br&gt;
It is a semantic input.&lt;/p&gt;
&lt;p&gt;When you select specific meshes and set the target mode to Selected, you are providing information that no algorithm can reliably infer:&lt;/p&gt;
&lt;p&gt;These areas deform&lt;/p&gt;
&lt;p&gt;These areas will be subdivided&lt;/p&gt;
&lt;p&gt;These areas currently have poor topology&lt;/p&gt;
&lt;p&gt;These areas justify restructuring&lt;/p&gt;
&lt;p&gt;Everything not selected implicitly communicates the opposite:&lt;/p&gt;
&lt;p&gt;Preserve existing structure&lt;/p&gt;
&lt;p&gt;Do not reinterpret intent&lt;/p&gt;
&lt;p&gt;Avoid unnecessary changes&lt;/p&gt;
&lt;p&gt;This is a far stronger signal than curvature analysis or density heuristics alone.&lt;/p&gt;
&lt;p&gt;Practical Workflow Breakdown&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Evaluate the Asset in Regions&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Instead of treating the mesh as a single unit, identify regions with different requirements:&lt;/p&gt;
&lt;p&gt;Deforming vs static&lt;/p&gt;
&lt;p&gt;Organic vs mechanical&lt;/p&gt;
&lt;p&gt;High-density vs low-density&lt;/p&gt;
&lt;p&gt;Legacy/problematic vs acceptable&lt;/p&gt;
&lt;p&gt;This is already how experienced artists think—the tool simply aligns with that mental model.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Select Only What Needs Quadification&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Using viewport selection or the outliner:&lt;/p&gt;
&lt;p&gt;Select meshes or parts that genuinely benefit from quadification&lt;/p&gt;
&lt;p&gt;Leave stable or intentional topology untouched&lt;/p&gt;
&lt;p&gt;The goal is precision, not completeness.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Set Target Mode to “Selected”&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This constrains quadification strictly to the selected elements:&lt;/p&gt;
&lt;p&gt;No global reinterpretation&lt;/p&gt;
&lt;p&gt;No accidental topology damage elsewhere&lt;/p&gt;
&lt;p&gt;No unnecessary processing&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Run Quadify&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Quadification is applied only where specified, producing a hybrid result:&lt;/p&gt;
&lt;p&gt;Automated quad flow where useful&lt;/p&gt;
&lt;p&gt;Original topology preserved elsewhere&lt;/p&gt;
&lt;p&gt;Predictable outcomes with less cleanup&lt;/p&gt;
&lt;p&gt;Why This Matters in Real Production&lt;/p&gt;
&lt;p&gt;Selective quadification is not just a quality-of-life feature—it is a production safeguard.&lt;/p&gt;
&lt;p&gt;It helps:&lt;/p&gt;
&lt;p&gt;Reduce unintended topology changes&lt;/p&gt;
&lt;p&gt;Preserve authored edge flow&lt;/p&gt;
&lt;p&gt;Minimize downstream cleanup&lt;/p&gt;
&lt;p&gt;Maintain consistency across iterations&lt;/p&gt;
&lt;p&gt;Most importantly, it acknowledges a reality often ignored by automation tools: artists already understand their assets better than any heuristic.&lt;/p&gt;
&lt;p&gt;Broader Design Philosophy&lt;/p&gt;
&lt;p&gt;This update reflects a broader shift in tool design:&lt;/p&gt;
&lt;p&gt;Automation should amplify judgment, not replace it.&lt;/p&gt;
&lt;p&gt;Instead of pursuing a mythical one-click solution, Manual Selective Quadification embraces constraint, intent, and context. It allows automation to work with artistic decision-making rather than against it.&lt;/p&gt;
&lt;p&gt;This philosophy underpins the continued development of Quadify as a production tool rather than a novelty feature set. For those interested in exploring the tool in more depth, Quadify is available as part of its ongoing development and update cycle:&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://superhivemarket.com/products/quadify&quot;&gt;Quadify&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Docs&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://quadify3d.com/&quot;&gt;https://quadify3d.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The emphasis, however, remains on workflow clarity rather than feature accumulation.&lt;/p&gt;
&lt;p&gt;When Selective Quadification Is (and Isn’t) Appropriate&lt;/p&gt;
&lt;p&gt;Use it when:&lt;/p&gt;
&lt;p&gt;Only parts of a mesh have poor topology&lt;/p&gt;
&lt;p&gt;Assets combine hard-surface and organic elements&lt;/p&gt;
&lt;p&gt;You want predictable, low-risk automation&lt;/p&gt;
&lt;p&gt;Avoid it when:&lt;/p&gt;
&lt;p&gt;You are in the early blockout stages&lt;/p&gt;
&lt;p&gt;The entire mesh clearly needs uniform restructuring&lt;/p&gt;
&lt;p&gt;Manual retopology is intentionally required everywhere&lt;/p&gt;
&lt;p&gt;Like any effective tool, it is about choosing the right moment.&lt;/p&gt;
&lt;p&gt;Final Thoughts&lt;/p&gt;
&lt;p&gt;Quadification should not be an act of faith.&lt;br&gt;
It should be an informed decision.&lt;/p&gt;
&lt;p&gt;Manual Selective Quadification reframes quadification as a targeted operation rather than a blanket transformation. By allowing artists to control where automation applies, it reduces risk, preserves intent, and aligns topology changes with real production needs.&lt;/p&gt;
&lt;p&gt;It does not attempt to outthink the artist.&lt;br&gt;
It simply executes when the artist decides it should.&lt;/p&gt;
&lt;p&gt;That shift—subtle as it may seem—makes a meaningful difference.&lt;/p&gt;
</description>
<category>Automation Tools</category>
<guid isPermaLink="true">https://coderlegion.com/8732/manual-selective-quadification-taking-back-control-of-retopology</guid>
<pubDate>Mon, 22 Dec 2025 15:53:13 +0000</pubDate>
</item>
<item>
<title>The Blender ↔ Unity Axis &amp; Scale Problem: A Complete Technical Guide</title>
<link>https://coderlegion.com/8146/the-blender-unity-axis-scale-problem-a-complete-technical-guide</link>
<description>&lt;h2 id=&quot;the-blender-unity-axis-amp-scale-problem-a-complete-technical-guide&quot;&gt;The Blender ↔ Unity Axis &amp;amp; Scale Problem: A Complete Technical Guide&lt;/h2&gt;
&lt;p&gt;(and How Unit &amp;amp; Scale Doctor Pro Solves It Reliably)&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;1-introduction-the-silent-production-killer&quot;&gt;&lt;strong&gt;1. Introduction — The Silent Production Killer&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Every 3D developer eventually encounters the classic trap:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;“It looked correct in Blender… but Unity imported it wrong.”&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Rotations are flipped.&lt;/li&gt;
&lt;li&gt;Objects appear microscopic or gigantic.&lt;/li&gt;
&lt;li&gt;Animations distort.&lt;/li&gt;
&lt;li&gt;Rig orientations break.&lt;/li&gt;
&lt;li&gt;Prefabs drift or rotate 90°.&lt;/li&gt;
&lt;li&gt;Root bones flip forward.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is not user error—it’s the unavoidable result of &lt;strong&gt;two unrelated coordinate systems colliding&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Unity and Blender simply do not speak the same native “3D language.”&lt;/p&gt;
&lt;p&gt;This article is a deep dive into:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Why scale &amp;amp; axis mismatches occur&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The real mathematical and pipeline causes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why attempting to ‘just apply transforms’ is unreliable&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How to manually fix models in a production-safe, deterministic way&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How to automate everything with Unit &amp;amp; Scale Doctor Pro&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you build technical art pipelines, maintain game studios' asset workflows, or run multi-DCC pipelines, this is essential knowledge.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;2-the-root-cause-two-worlds-two-coordinate-systems&quot;&gt;&lt;strong&gt;2. The Root Cause — Two Worlds, Two Coordinate Systems&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;blender-uses-&quot;&gt;&lt;strong&gt;Blender uses:&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unit&lt;/strong&gt;: &lt;em&gt;Meters&lt;/em&gt; by default, but functionally unitless&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Axis&lt;/strong&gt;: +Z &lt;strong&gt;up&lt;/strong&gt;, +Y &lt;strong&gt;forward&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Object default scale&lt;/strong&gt;: (1,1,1)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;unity-uses-&quot;&gt;&lt;strong&gt;Unity uses:&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unit&lt;/strong&gt;: &lt;em&gt;Meters&lt;/em&gt; but 1 Blender meter ≠ 1 Unity meter without context&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Axis&lt;/strong&gt;: +Y &lt;strong&gt;up&lt;/strong&gt;, +Z &lt;strong&gt;forward&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FBX importer behavior&lt;/strong&gt;: secretly compensates, inconsistently&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;the-fundamental-conflict&quot;&gt;&lt;strong&gt;The Fundamental Conflict&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Blender’s &lt;em&gt;Z-up&lt;/em&gt; means the “world up” vector is different.&lt;br&gt;
Unity’s &lt;em&gt;Y-up&lt;/em&gt; means the “world up” vector is different.&lt;/p&gt;
&lt;p&gt;This leads to the classic &lt;strong&gt;90° rotation offset&lt;/strong&gt;, often around X or sometimes Z, depending on export settings.&lt;/p&gt;
&lt;p&gt;The scale mismatch is even worse:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Blender’s &lt;em&gt;grid scale&lt;/em&gt; ≠ the FBX exporter’s &lt;em&gt;unit scale&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Unity’s FBX importer applies hidden conversions&lt;/li&gt;
&lt;li&gt;Blender’s “Apply Scale” resets object-level scaling but alters animation meaning&lt;/li&gt;
&lt;li&gt;Armatures store rest pose matrices relative to Blender’s coordinate system&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;If you think this sounds messy—you’re correct.&lt;/strong&gt;&lt;br&gt;
And every studio spends hundreds of hours per year fighting it.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;3-the-axis-dichotomy-why-objects-rotate-wrong&quot;&gt;&lt;strong&gt;3. The Axis Dichotomy — Why Objects Rotate Wrong&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;case-1-blender-to-unity-rotation&quot;&gt;Case 1: Blender to Unity Rotation&lt;/h4&gt;
&lt;p&gt;Blender’s +Y forward is Unity’s +Z forward.&lt;/p&gt;
&lt;p&gt;Converting between the two requires:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Rotation = Rotate -90° around X
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But this is &lt;em&gt;only&lt;/em&gt; correct for static meshes.&lt;/p&gt;
&lt;p&gt;For rigs, bones, animation curves, constraints, and IK solvers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The armature object must rotate&lt;/li&gt;
&lt;li&gt;Every bone’s roll must be corrected&lt;/li&gt;
&lt;li&gt;Animation keyframes must be reinterpreted&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you simply “apply” the rotation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IK chains break&lt;/li&gt;
&lt;li&gt;Pose orientation becomes invalid&lt;/li&gt;
&lt;li&gt;Animation curves produce different results&lt;/li&gt;
&lt;li&gt;Bone roll becomes inconsistent (critical for weapons, fingers, mechanical rigs)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is why the internet is full of contradictory advice—&lt;br&gt;
&lt;strong&gt;because most of it works for simple meshes, but destroys complex rigs.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;4-the-scale-dichotomy-why-objects-import-too-small-or-too-large&quot;&gt;&lt;strong&gt;4. The Scale Dichotomy — Why Objects Import Too Small or Too Large&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;key-misconception-&quot;&gt;Key misconception:&lt;/h4&gt;
&lt;blockquote&gt;&lt;p&gt;“Blender units = meters = Unity meters.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is only &lt;em&gt;theoretically&lt;/em&gt; true.&lt;/p&gt;
&lt;p&gt;Here’s the reality:&lt;/p&gt;
&lt;h4 id=&quot;blender-s-exporters&quot;&gt;&lt;strong&gt;Blender's Exporters&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;FBX exporter has hidden unit scaling&lt;/li&gt;
&lt;li&gt;glTF uses meters but assumes Z-up needs conversion&lt;/li&gt;
&lt;li&gt;OBJ has no unit semantics&lt;/li&gt;
&lt;li&gt;CAD imports often come in cm/mm&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;unity-s-importers&quot;&gt;&lt;strong&gt;Unity’s Importers&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;FBX importer has a &lt;em&gt;Scale Factor&lt;/em&gt; (sometimes 0.01)&lt;/li&gt;
&lt;li&gt;Legacy FBX workflows still assume Maya’s centimeter world&lt;/li&gt;
&lt;li&gt;glTF importer assumes meters&lt;/li&gt;
&lt;li&gt;CAD importers assume millimeters&lt;/li&gt;
&lt;li&gt;Custom pipelines override scale silently&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In practice, you see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Assets 100× too small&lt;/li&gt;
&lt;li&gt;Assets 1/100th expected size&lt;/li&gt;
&lt;li&gt;Rigs where animation offsets are scaled differently&lt;/li&gt;
&lt;li&gt;Physics collider mismatches&lt;/li&gt;
&lt;li&gt;Prefabs with broken child offsets&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Scaling is not universal.&lt;br&gt;
Scaling is &lt;strong&gt;hierarchical&lt;/strong&gt;, &lt;strong&gt;order-dependent&lt;/strong&gt;, and &lt;strong&gt;context-dependent&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;“Apply Scale (Ctrl+A)” solves nearly nothing reliably across a full production pipeline.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;5-why-apply-all-transforms-is-a-pipeline-trap&quot;&gt;&lt;strong&gt;5. Why &quot;Apply All Transforms&quot; Is a Pipeline Trap&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Applying rotation &amp;amp; scale at the object level seems tempting—but it is destructive:&lt;/p&gt;
&lt;h4 id=&quot;it-breaks-&quot;&gt;It breaks:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Animation tracks&lt;/li&gt;
&lt;li&gt;Rig rest pose data&lt;/li&gt;
&lt;li&gt;IK constraints&lt;/li&gt;
&lt;li&gt;Bone hierarchy matrices&lt;/li&gt;
&lt;li&gt;Driver-based rigs&lt;/li&gt;
&lt;li&gt;Constraints that assume world vs local transforms&lt;/li&gt;
&lt;li&gt;Any rig authored for Blender’s Z-up world&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Studios often apply transforms to fix one asset, but create inconsistencies with others.&lt;/p&gt;
&lt;p&gt;This leads to &lt;strong&gt;asset drift&lt;/strong&gt;, where each mesh slowly becomes different from others in the pipeline.&lt;/p&gt;
&lt;p&gt;This is how productions collapse under their own asset inconsistency.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;6-the-correct-manual-approach-if-you-must-do-it-manually-&quot;&gt;&lt;strong&gt;6. The Correct Manual Approach (If You Must Do It Manually)&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;step-1-choose-a-pipeline-convention&quot;&gt;Step 1 — Choose a Pipeline Convention&lt;/h4&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unity&lt;/strong&gt;: Y-up, meters, 1:1 scale&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unity (Maya-style)&lt;/strong&gt;: centimeters, 0.01 scale&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;glTF&lt;/strong&gt;: meters, Z-up → Y-up conversion&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;step-2-standardize-blender-scene&quot;&gt;Step 2 — Standardize Blender Scene&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;World's unit scale&lt;/li&gt;
&lt;li&gt;Scene orientation&lt;/li&gt;
&lt;li&gt;Grid scale&lt;/li&gt;
&lt;li&gt;Import scale adjustments&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;step-3-fix-object-transforms-without-breaking-rigs&quot;&gt;Step 3 — Fix Object Transforms Without Breaking Rigs&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Convert orientation using &lt;em&gt;matrix math&lt;/em&gt;, not rotations&lt;/li&gt;
&lt;li&gt;Rebuild bone rolls in correct order&lt;/li&gt;
&lt;li&gt;Resample animation curves&lt;/li&gt;
&lt;li&gt;Normalize scale hierarchies&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;step-4-validate&quot;&gt;Step 4 — Validate&lt;/h4&gt;
&lt;p&gt;Every object must be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scale: &lt;code&gt;(1,1,1)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Rotation: correct forward/up axes&lt;/li&gt;
&lt;li&gt;Location: zeroed or pipeline-safe&lt;/li&gt;
&lt;li&gt;Bone rest pose: consistent&lt;/li&gt;
&lt;li&gt;Animations: stable after conversion&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is why studios use specialized tools—&lt;br&gt;
because doing this manually for hundreds of assets is not feasible.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;7-why-you-need-an-automated-system-not-a-manual-workflow-&quot;&gt;&lt;strong&gt;7. Why You Need an Automated System (Not a Manual Workflow)&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A studio pipeline must guarantee:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Every asset is export-safe&lt;/li&gt;
&lt;li&gt;Every file uses identical conventions&lt;/li&gt;
&lt;li&gt;Transforms are mathematically correct&lt;/li&gt;
&lt;li&gt;Rigs are preserved&lt;/li&gt;
&lt;li&gt;No artist “accidentally breaks scale”&lt;/li&gt;
&lt;li&gt;No asset slowly deviates from conventions over time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the reason tools like &lt;strong&gt;Unit &amp;amp; Scale Doctor Pro&lt;/strong&gt; exist—&lt;br&gt;
to solve a problem that is mathematically deterministic but tedious and error-prone for humans.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;8-unit-amp-scale-doctor-pro-what-it-actually-does&quot;&gt;&lt;strong&gt;8. Unit &amp;amp; Scale Doctor Pro — What It Actually Does&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=17114841354550508258&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Based on the README and source files in your package, the tool provides:&lt;/p&gt;
&lt;h4 id=&quot;-multi-engine-profile-system&quot;&gt;✔ &lt;strong&gt;Multi-Engine Profile System&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Switch an entire Blender scene to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unity (meters / centimeters / millimeters workflows)&lt;/li&gt;
&lt;li&gt;Unreal&lt;/li&gt;
&lt;li&gt;glTF&lt;/li&gt;
&lt;li&gt;CAD pipelines&lt;/li&gt;
&lt;li&gt;Custom studio conventions&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-object-mesh-and-armature-correction&quot;&gt;✔ &lt;strong&gt;Object, Mesh, and Armature Correction&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;It rewrites:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Object matrices&lt;/li&gt;
&lt;li&gt;Mesh local → world conversions&lt;/li&gt;
&lt;li&gt;Armature rest pose matrices&lt;/li&gt;
&lt;li&gt;Bone roll normalization&lt;/li&gt;
&lt;li&gt;Animation data curve remapping&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-non-destructive-fixing&quot;&gt;✔ &lt;strong&gt;Non-Destructive Fixing&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;The tool ensures:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No rig is lost&lt;/li&gt;
&lt;li&gt;No animation is destroyed&lt;/li&gt;
&lt;li&gt;No mesh is warped&lt;/li&gt;
&lt;li&gt;No parenting hierarchy breaks&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-a-full-validation-system&quot;&gt;✔ &lt;strong&gt;A Full Validation System&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;It detects inconsistencies such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wrong scale&lt;/li&gt;
&lt;li&gt;Hidden object scale offsets&lt;/li&gt;
&lt;li&gt;Negative scaling&lt;/li&gt;
&lt;li&gt;Axis flips&lt;/li&gt;
&lt;li&gt;Bone roll inconsistencies&lt;/li&gt;
&lt;li&gt;Meshes containing multiple transform spaces&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-one-click-scene-standardization&quot;&gt;✔ &lt;strong&gt;One-Click Scene Standardization&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;A complete “reset” that makes the entire project engine-ready.&lt;/p&gt;
&lt;p&gt;This is exactly what large studios build internally—&lt;br&gt;
but you have it packaged and production-ready.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;9-how-it-fixes-everything-automatically&quot;&gt;&lt;strong&gt;9. How It Fixes Everything Automatically&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Here’s what a typical Unit &amp;amp; Scale Doctor Pro pipeline does under the hood:&lt;/p&gt;
&lt;h4 id=&quot;step-a-scene-fingerprinting&quot;&gt;Step A — Scene Fingerprinting&lt;/h4&gt;
&lt;p&gt;It scans every object:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Type&lt;/li&gt;
&lt;li&gt;Transform&lt;/li&gt;
&lt;li&gt;Parent hierarchy&lt;/li&gt;
&lt;li&gt;Mesh data&lt;/li&gt;
&lt;li&gt;Armature bind poses&lt;/li&gt;
&lt;li&gt;Animation data&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;step-b-determine-required-conversions&quot;&gt;Step B — Determine Required Conversions&lt;/h4&gt;
&lt;p&gt;Using the selected &lt;em&gt;profile&lt;/em&gt;, it derives:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Required world up axis&lt;/li&gt;
&lt;li&gt;Forward direction&lt;/li&gt;
&lt;li&gt;Unit scale multiplier&lt;/li&gt;
&lt;li&gt;Mesh shrinkwrap conversions&lt;/li&gt;
&lt;li&gt;Armature remapping rules&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;step-c-apply-matrix-level-transform-fixes&quot;&gt;Step C — Apply Matrix-Level Transform Fixes&lt;/h4&gt;
&lt;p&gt;It rewrites transforms directly in matrix form:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;M_corrected = ConversionMatrix * M_original
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This preserves:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bone rest pose&lt;/li&gt;
&lt;li&gt;Animation curves&lt;/li&gt;
&lt;li&gt;Rig constraints&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;step-d-clean-bake-normalize&quot;&gt;Step D — Clean / Bake / Normalize&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Zero object scales&lt;/li&gt;
&lt;li&gt;Fix bone rolls deterministically&lt;/li&gt;
&lt;li&gt;Rebuild animation curves&lt;/li&gt;
&lt;li&gt;Validate length units&lt;/li&gt;
&lt;li&gt;Normalize mesh normals&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;step-e-pipeline-safe-export&quot;&gt;Step E — Pipeline Safe Export&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;FBX-safe rotation&lt;/li&gt;
&lt;li&gt;glTF-safe unit scale&lt;/li&gt;
&lt;li&gt;Unity-ready hierarchy&lt;/li&gt;
&lt;li&gt;Unreal-ready orientation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The entire process becomes deterministic and repeatable.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;10-practical-example-blender-to-unity-correct-workflow-&quot;&gt;&lt;strong&gt;10. Practical Example — Blender to Unity (Correct Workflow)&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;without-unit-amp-scale-doctor-pro&quot;&gt;&lt;strong&gt;Without Unit &amp;amp; Scale Doctor Pro&lt;/strong&gt;&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Export FBX&lt;/li&gt;
&lt;li&gt;Import into Unity&lt;/li&gt;
&lt;li&gt;Fix rotation manually&lt;/li&gt;
&lt;li&gt;Fix scale manually&lt;/li&gt;
&lt;li&gt;Fix animation drift&lt;/li&gt;
&lt;li&gt;Fix rig orientations&lt;/li&gt;
&lt;li&gt;Re-export when something breaks&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Every asset becomes a small crisis.&lt;/p&gt;
&lt;h4 id=&quot;with-unit-amp-scale-doctor-pro&quot;&gt;&lt;strong&gt;With Unit &amp;amp; Scale Doctor Pro&lt;/strong&gt;&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Choose &lt;strong&gt;Unity&lt;/strong&gt; profile&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Fix Scene&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Export FBX normally&lt;/li&gt;
&lt;li&gt;Import into Unity and it “just works”&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This eliminates rotational offsets, scale mismatches, and animation distortions.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;11-receipts-for-technical-artists-why-this-matters&quot;&gt;&lt;strong&gt;11. Receipts for Technical Artists — Why This Matters&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A good TA knows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scale drift kills animation pipelines&lt;/li&gt;
&lt;li&gt;Hand-authored fixes destroy determinism&lt;/li&gt;
&lt;li&gt;Rig rest poses must be mathematically preserved&lt;/li&gt;
&lt;li&gt;Axis conversion is &lt;em&gt;matrix math&lt;/em&gt;, not rotation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unit &amp;amp; Scale Doctor Pro fills the gap Blender never will:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A consistent, safe, automated transformation pipeline.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;12-conclusion-the-right-way-to-handle-axis-amp-scale-forever&quot;&gt;&lt;strong&gt;12. Conclusion — The Right Way to Handle Axis &amp;amp; Scale Forever&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The Blender ↔ Unity scale/axis mismatch is unavoidable.&lt;br&gt;
But the chaos surrounding it is optional.&lt;/p&gt;
&lt;h4 id=&quot;at-a-high-level-&quot;&gt;At a high level:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Blender uses Z-up&lt;/li&gt;
&lt;li&gt;Unity uses Y-up&lt;/li&gt;
&lt;li&gt;Scale semantics are inconsistent&lt;/li&gt;
&lt;li&gt;Animations and rigs magnify errors&lt;/li&gt;
&lt;li&gt;Manual fixes are destructive&lt;/li&gt;
&lt;li&gt;Studio pipelines require determinism&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;the-fix-&quot;&gt;The fix:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Understand the math&lt;/li&gt;
&lt;li&gt;Fix transforms non-destructively&lt;/li&gt;
&lt;li&gt;Use deterministic conversion methods&lt;/li&gt;
&lt;li&gt;Rely on a tool built specifically for this problem&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is exactly what &lt;strong&gt;Unit &amp;amp; Scale Doctor Pro&lt;/strong&gt; provides:&lt;br&gt;
A complete, automated, studio-safe solution to a 20-year-old industry headache.&lt;/p&gt;
&lt;p&gt;Get it on Superhive Marketplace via this link: &lt;a rel=&quot;nofollow&quot; href=&quot;https://superhivemarket.com/products/unit--scale-doctor&quot;&gt;https://superhivemarket.com/products/unit--scale-doctor&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
</description>
<category>Automation Tools</category>
<guid isPermaLink="true">https://coderlegion.com/8146/the-blender-unity-axis-scale-problem-a-complete-technical-guide</guid>
<pubDate>Wed, 03 Dec 2025 21:45:56 +0000</pubDate>
</item>
</channel>
</rss>