Auto Structural Mapping
Use Automated Structural Mapping to segment a triangulated mesh (TIN) into coherent planar patches by growing regions of similar orientation over the mesh's triangle adjacency. The tool writes per‑triangle attributes and can create one orientation object per patch for downstream analysis (stereonets, DFN statistics, set assignment).
It is the original, orientation‑driven patch decomposer. A newer tool, Grow Planar Patches, fits planes as it grows, derives its own parameters from the mesh, clusters the patches into sets and can extract a single set; it is the one to start with. Both write the same‑named attribute layers, so you can run either on a mesh and compare them on one colour map. Grow Planar Patches or Auto Structural Mapping? sets out how the two differ.
Prerequisites
- A selected
TriangulatedMeshin the Project Tree. - Optional triangle attribute layers:
DipandAzimuth(degrees) — the per‑vertex tensor poles used to build each triangle's orientation. When either is missing the tool uses the mesh's own face normals instead and says so in the messages panel.CoPlanarity— used to order the seeds (flattest triangles first) and for the optional coplanarity filter. When missing, seeds are taken in triangle order and the filter is ignored.
The Tensor Analysis tool produces all three layers. The tensor poles are smoothed over a search radius, which helps on rough meshes but blurs them near creases; face normals are sharp at creases but noisier.
Launch
- Project Tree: select a triangulated mesh, then Extract → Decompose Into Patches (opens “Automated Structural Mapping”).
- Buttons: Apply runs without closing; OK runs and closes.
The triangle adjacency is checked with a quick sample and rebuilt only when it does not look valid, so repeated runs do not pay the multi‑second linkage sort again.
Dialog Fields
Attributes
- Coplanarity: the layer used to order seeds and, optionally, to filter triangles.
- Use Coplanarity Filter: when on, triangles with any vertex outside the coplanarity layer's filter window are excluded entirely (not seeds, not members), and seeds are limited to the window.
- Dip / Azimuth: the layers used to build each triangle's pole. Leave them unselected to grow on face normals.
Settings
- Minimum Patch size: minimum number of triangles for a patch to be accepted.
- Tolerance Angle: angular tolerance in degrees between a candidate triangle's pole and the reference (seed, current triangle or running mean).
- Relative Variation: compare each neighbour to the current triangle's pole instead of the seed's. Lets a patch follow gentle curvature, at the risk of drift.
- Fill Holes and Fill holes up to: after growth, absorb unassigned islands that are enclosed on every side by one patch and have at most this many triangles. Islands touching the mesh boundary, a hidden triangle or a second patch are left alone.
- Create Objects: create a per‑patch orientation object named
Auto_<ID> (count)in a “Patch Decomposition” group. - Dispersion (0..1): acceptance control when RMin is not used. A patch is accepted if the area‑weighted mean axial angle of its triangles to the patch mean is ≤
Dispersion × Tolerance Angle. Default 0.75. - Use Mean Reference: grow against the running area‑weighted mean pole of the patch rather than the seed or current triangle. More coherent patches, less drift.
- RMin (0..1): minimum area‑weighted mean resultant length
Rfor acceptance. If > 0 it supersedes Dispersion. Typical values: 0.7–0.9 for tight sets, 0.5–0.7 for looser ones. - Max Distance: largest distance, in model units, from any vertex of a candidate triangle to the plane through the patch's running centroid with its mean pole. 0 disables the test and growth is angle‑only. This is what stops two parallel surfaces offset by a step from joining through a low‑angle path.
- Min Area: smallest patch area accepted, in squared model units. 0 disables. On decimated or photogrammetric meshes triangle sizes vary widely, so an area limit is a more physical size than a triangle count.
- Merge Co‑planar Patches: after growth, merge adjacent accepted patches whose mean poles agree within the tolerance angle (and whose centroids lie within Max Distance of each other's plane, when that is set).
Filter
- Dip / Azimuth: enable and set
[min, max]in degrees. A seed's own pole and the finished patch's mean pole must fall inside the window. Azimuth wrap‑around is supported:350–10accepts angles ≥ 350 or ≤ 10. - Get From Selected: fills the windows from the selected orientation objects, expanded by the +/- margin.
What It Writes
Triangle attribute layers, 0 on unassigned triangles except where noted:
- Patches (int): patch id, largest patch first. Consecutive ids are not spatial neighbours, so a linear colour ramp still reads as patches rather than as the mesh's triangle order.
- Patch Colour (float): the id scrambled onto the ramp so neighbouring patches take contrasting colours. This is the layer left active after a run.
- Patch Size (int): triangles in the patch.
- Patch Area (float): patch area in squared model units.
- Patch Difference (float, degrees): axial angle between the triangle's pole and the patch's area‑weighted mean pole.
- Patch Similarity (float):
|dot(pole, mean)|in 0..1, the cosine of Patch Difference. - Patch CoPlanarity (float): Fernandez's M for the patch as a whole — one plane fitted through the patch's distinct nodes. On the same scale as the per‑vertex CoPlanarity attribute. Patches of fewer than four distinct nodes are left at 0.
- Patch RMS Residual (float): RMS distance of the patch's nodes to its fitted plane, in model units.
- Patch Length / Patch Width (float): in‑plane extents of the fitted plane, from its two in‑plane eigenvalues (
sqrt(12 λ / n), the side length for a uniformly sampled rectangle). - Patch Dip / Patch Azimuth (float, degrees): of the fitted plane; azimuth is the dip direction. Unassigned triangles have no value in these two, rather than a 0 that would read as a horizontal plane. With them the patches plot on a stereonet as Grow Planar Patches' do — see Patches on the Stereonet.
These are the layers Grow Planar Patches writes, less Patch Set, which only its set clustering produces. Each run replaces them all, and removes a Patch Set left by an earlier Grow Planar Patches run, since its set numbers described that run's patches; the messages panel says so.
Optional objects: one strike/dip orientation object per patch, built from an even sample of at most 256 of the patch's nodes, so a large patch does not drag thousands of vertices into the project. The object's dip, azimuth, error and quality ratios come from a plane fitted through that sample.
Prefer Patch CoPlanarity and Patch RMS Residual when you want to know how planar a surface is. The per‑vertex CoPlanarity attribute measures a sphere of points around each vertex, so near the edge of a face that sphere spills onto the neighbouring facet and coplanarity dips all round the rim of a surface that is genuinely flat. A patch is one surface by construction and carries no rim effect.
Picking a Patch as an Orientation Measurement
With a Patches layer on the mesh, the ribbon's Dip / azimuth → Attributes tool creates an orientation from any patch you click: an object named Patch_<id> in the active orientation group, its plane fitted through the patch's nodes. Clicking an unassigned triangle creates nothing; on a mesh without a Patches layer the tool falls back to the Dip and Azimuth vertex attributes at the clicked point. See Grow Planar Patches for the details.
How It Works (Summary)
Implementation: CAutoStructureMappingDlg drives CTINPatchDecomposer; the merge, hole‑fill and plane‑fit steps are shared with Grow Planar Patches through PlaneGrowerCore.h.
- Poles. Each triangle gets the axial average of its three vertex poles from the Dip/Azimuth layers, or its face normal when those are not selected.
- Seeds. Triangles are ordered by average coplanarity (flattest first) when a layer is selected, otherwise by index. Hidden and deleted triangles are excluded throughout. So are filtered ones while the mesh's Use Attribute Filters is on: those filtered by an attribute with Use Filter ticked, other than the patch layers this run replaces.
- Growth. Best‑first: candidates come off a priority queue in order of fit, so the running mean is at its most reliable by the time borderline triangles are tested. A candidate must be within the tolerance angle of the reference and, when Max Distance is set, have every vertex within that distance of the patch's running plane.
- Acceptance. Minimum size and area, the dip/azimuth window on the mean pole, and the dispersion or RMin test, all area‑weighted. A rejected region's triangles are retired rather than regrown from each of them in turn (with a relative or mean reference the region is seed‑independent, so nothing is lost; with a seed reference a region rejected only for size stays available, since a neighbour with a better pole can still grow a full patch there).
- Post‑processing. Optional merge of adjacent co‑planar patches, optional hole fill up to the size limit, renumbering largest first, plane fit per patch and attribute writing, including the removal of a stale Patch Set.
Tips For Best Results
- Start with Tolerance Angle 10–20° and Use Mean Reference on. If patches fragment, raise the angle or enable Merge Co‑planar Patches.
- Set Max Distance to a few times the mesh's vertex noise (a fraction of a triangle edge) when parallel surfaces are being joined across steps.
- Use RMin (e.g. 0.8) when you want patches of uniform orientation independent of the tolerance.
- Target known sets with the Dip/Azimuth filters, e.g. bedding or a dominant fracture set.
- Try Apply without Create Objects first; objects are heavier on large meshes.
- If you do not have the tensor layers, or the mesh is clean, grow on face normals: leave Dip and Azimuth unselected.
Troubleshooting
- No patches, or far too few: raise the tolerance angle, lower the minimum size, disable the dip/azimuth filters, or relax Dispersion / lower RMin.
- Patches too large or indistinct: lower the tolerance angle, set Max Distance, raise RMin, or turn Merge off.
- The colour map looks like a smooth gradient rather than patches: display Patch Colour rather than Patches.
- Nothing changes on screen after Apply: the layers are refreshed in place and the view should re‑bake; if an older build shows stale colours, toggle the layer in the tree.
- Azimuth window behaves oddly: check wrap‑around; use
350–10for values straddling 0°.
Reference: Parameter Mapping
- Minimum Patch size →
MinTriangles - Tolerance Angle →
MaxAng - Relative Variation →
IsRelative - Fill Holes / Fill holes up to →
bFixHoles/SetMaxHoleTriangles - Create Objects →
bSaveData - Dip/Azimuth filters →
SetDipFilter,SetAzimuthFilter - Use Coplanarity Filter →
SetAttributes(..., UseCoplanarityFilter) - Dispersion →
SetDispersionFraction - Use Mean Reference →
UseMeanReference - RMin →
SetResultantMin - Max Distance →
SetMaxDistance - Min Area →
SetMinArea - Merge Co‑planar Patches →
SetMergePatches
See also: the internal notes in VRGS2020/CTINPatchDecomposer.md, and Grow Planar Patches.