Skip to content

Instantly share code, notes, and snippets.

@Swordslayer
Last active March 3, 2022 15:46
Show Gist options
  • Save Swordslayer/990adcd091cf08b115e29241b7b4c1eb to your computer and use it in GitHub Desktop.
Save Swordslayer/990adcd091cf08b115e29241b7b4c1eb to your computer and use it in GitHub Desktop.
Select edges across vertices with multiple explicit normals. For imported CAD geometry, these usually correspond to the original iso lines.
(
local compilerParams = dotNetObject "System.CodeDom.Compiler.CompilerParameters" #(
getDir #maxRoot + "\bin\assemblies\Autodesk.Max.Wrappers.dll",
getDir #maxRoot + "Autodesk.Max.dll")
compilerParams.GenerateInMemory = true
local compilerResults = (dotNetObject "Microsoft.CSharp.CSharpCodeProvider").CompileAssemblyFromSource compilerParams #(
"using System;
using Autodesk.Max;
using Wrappers = Autodesk.Max.Wrappers;
public class MeshNormals {
private static readonly uint UNDEFINED = 0xffffffff;
private static readonly IGlobal Global = Autodesk.Max.GlobalInterface.Instance;
public static void GetNormalsBorderEdges(IntPtr emesh, IntPtr bitarray_pointer, bool includeOpenEdges) {
var mesh = ((ITriObject)Wrappers.CustomMarshalerTriObject.GetInstance(string.Empty).MarshalNativeToManaged(emesh)).Mesh;
var edges = (IBitArray)Wrappers.CustomMarshalerBitArray.GetInstance(string.Empty).MarshalNativeToManaged(bitarray_pointer);
var edgeList = Global.AdjEdgeList.Create(mesh);
var normals = mesh.SpecifiedNormals;
if (includeOpenEdges) mesh.FindOpenEdges(edges);
else edges.SetSize(mesh.NumFaces * 3, 0);
for(int e = 0; e < edgeList.Edges.Count; e++) {
var edge = edgeList.Edges[e];
if (edge.F[0] != UNDEFINED && edge.F[1] != UNDEFINED) {
int E = (int)mesh.Faces[(int)edge.F[0]].GetEdgeIndex(edge.V[0], edge.V[1]);
int reverseE = (int)mesh.Faces[(int)edge.F[1]].GetEdgeIndex(edge.V[1], edge.V[0]);
if ((normals.GetNormalIndex((int)edge.F[0], E) != normals.GetNormalIndex((int)edge.F[1], (reverseE + 1) % 3)) &&
(normals.GetNormalIndex((int)edge.F[0], (E + 1) % 3) != normals.GetNormalIndex((int)edge.F[1], reverseE))) {
edges.Set((int)edge.F[0] * 3 + E, 1);
edges.Set((int)edge.F[1] * 3 + reverseE, 1);
}
}
}
}
}"
)
local meshNormals = compilerResults.CompiledAssembly.CreateInstance "MeshNormals"
fn selectNormalsBorderEdges obj includeOpenEdges:off = if isKindOf obj Editable_mesh do
(
local edges = #{}
meshNormals.GetNormalsBorderEdges (refs.getAddr obj.baseObject) edges includeOpenEdges
setEdgeSelection obj edges
OK
)
selectNormalsBorderEdges $ includeOpenEdges:on
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment