Skip to content

Instantly share code, notes, and snippets.

@unitycoder
Created September 8, 2026 12:23
Show Gist options
  • Select an option

  • Save unitycoder/8e2661a737333edc2264d361473f56a8 to your computer and use it in GitHub Desktop.

Select an option

Save unitycoder/8e2661a737333edc2264d361473f56a8 to your computer and use it in GitHub Desktop.
3ds max select similar polygons from current editable poly polygon selection
// chatgpt
(
-- SETTINGS
local tolerance = 0.001
local ignoreSize = false
fn compareFloat a b =
(
if a < b then -1
else if a > b then 1
else 0
)
fn getFaceSignature obj faceIndex ignoreSize =
(
local verts = polyOp.getFaceVerts obj faceIndex
local distances = #()
-- Get every vertex-to-vertex distance.
-- This describes the polygon shape regardless of rotation/orientation.
for i = 1 to (verts.count - 1) do
(
local p1 = polyOp.getVert obj verts[i]
for j = (i + 1) to verts.count do
(
local p2 = polyOp.getVert obj verts[j]
append distances (distance p1 p2)
)
)
qsort distances compareFloat
-- Normalize if we only care about shape and not actual size.
if ignoreSize and distances.count > 0 do
(
local maxDistance = distances[distances.count]
if maxDistance > 0.000001 do
(
for i = 1 to distances.count do
distances[i] /= maxDistance
)
)
#(verts.count, distances)
)
fn signaturesMatch sigA sigB tolerance =
(
-- Different vertex count = different polygon.
if sigA[1] != sigB[1] then
return false
local a = sigA[2]
local b = sigB[2]
if a.count != b.count then
return false
local epsilon = tolerance
if a.count > 0 do
(
epsilon = a[a.count] * tolerance
if epsilon < 0.000001 do
epsilon = 0.000001
)
for i = 1 to a.count do
(
if abs(a[i] - b[i]) > epsilon then
return false
)
true
)
if selection.count != 1 then
(
messageBox "Select one Editable Poly object."
)
else
(
local obj = selection[1]
if classOf obj.baseObject != Editable_Poly then
(
messageBox "The selected object must be an Editable Poly."
)
else
(
local selectedFaces = polyOp.getFaceSelection obj
if selectedFaces.numberSet != 1 then
(
messageBox "Select exactly one polygon first."
)
else
(
local referenceFace = 0
for f in selectedFaces do
referenceFace = f
local referenceSignature =
getFaceSignature obj referenceFace ignoreSize
local result = #{}
local faceCount = polyOp.getNumFaces obj
for f = 1 to faceCount do
(
local sig = getFaceSignature obj f ignoreSize
if signaturesMatch referenceSignature sig tolerance do
result[f] = true
)
polyOp.setFaceSelection obj result
subObjectLevel = 4
redrawViews()
format "Selected % similar polygons.\n" result.numberSet
)
)
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment