[Closed] Coplanar Edge Removal?
Hi,
how do i remove coplanar edges in a poly object? I want to remove all the coplanar edges/triangles in my object and create a n-gon.
What i usually did was to delete the triangles and cap the hole by hand. in this case, ive hundreds of faces and i need to integrate the code into my existing script.
Ive found that this feature in implemented in a few plug-ins, like Proboolean and other commercial plug-ins, but is there some piece of code for free or is there a easy method to script it myself ? i actually dont want to handle with trimeshes and stuff like that…
Thanks
Hi Björn,
here is a function to do the job. It removes every edge from an editable poly whose adjacent faces are coplanar, cleans unneeded verts too. Maybe it’s not super optimized, but I guess you can polish it a bit when integrate it into your script.
function remCopEdges =
(
-- get input object
local oTest = selection[1]
-- check input object
if ((oTest != undefined) and (classOf oTest.baseObject == Editable_Poly)) then
(
undo on
(
-- get Edit Poly Edges
local iNumEdges = polyop.getNumEdges oTest.baseObject
local baEdges = #{1..iNumEdges}
-- remove Edit Poly Border Edges from calculation
local baOpenEdges = polyop.getOpenEdges oTest.baseObject
local baInnerEdges = baEdges - baOpenEdges
-- get Verts from inner Edges
local baInnerVerts = polyOp.getVertsUsingEdge oTest.baseObject baInnerEdges
local iFlag32 = bit.set 0 32 true
-- Face normals check cycle
for iEdge in baInnerEdges do
(
-- for each inner Edge
-- get Faces adjacent to Edge
local iFace01 = oTest.baseObject.getEdgeFace iEdge 1
local iFace02 = oTest.baseObject.getEdgeFace iEdge 2
-- get adjacent Faces normal vector
local p3FaceNorm01 = polyop.getFaceNormal oTest.baseObject iFace01
local p3FaceNorm02 = polyop.getFaceNormal oTest.baseObject iFace02
-- get angle between Faces normal vectors
local fNormAngle = (acos(dot p3FaceNorm01 p3FaceNorm02))
-- if the angle is less than 0.05 degrees, faces are coplanar,
-- set a Flag on the shared Edge
if (fNormAngle < 0.05) then
(
polyOp.setEdgeFlags oTest.baseObject iEdge iFlag32 undoable:true
)
-- Normals are not checked as vectors because of precision issues,
-- setting the angle between vectors equal to 0, doesn't select
-- all coplanar Faces. 0.05 is quite fair. A thresold value could
-- be implemented here.
)
-- get Edges to remove
local baEdgesToRemove = polyOp.getEdgesByFlag oTest.baseObject iFlag32 mask:iFlag32
-- get Edges to keep as difference
local baInnerEdgesToKeep = baInnerEdges - baEdgesToRemove
-- get Verts from Edges to keep
local baInnerVertsToKeep = polyOp.getVertsUsingEdge oTest.baseObject baInnerEdgesToKeep
-- get Verts to remove as difference and set a Flag on them
local baInnerVertsToRemove = baInnerVerts - baInnerVertsToKeep
polyOp.setVertFlags oTest.baseObject baInnerVertsToRemove iFlag32 undoable:true
-- remove Verts (and Edges)
-- the cycle is needed because sometimes some Verts are not removed
-- by the first pass
do
(
oTest.baseObject.remove selLevel:#Vertex flag:iFlag32
)
while ((polyOp.getVertsByFlag oTest.baseObject 1).isEmpty == false)
-- remove Edges not sharing a Vert removed
oTest.baseObject.remove selLevel:#Edge flag:iFlag32
-- remove isolated Verts. Not really needed but doesn't hurt.
polyop.deleteIsoVerts oTest.baseObject
)
)
else
(
messageBox "Please select a single Editable Poly object"
)
)
- Enrico
Your function really does the job, except for a few faces, but thats because my script didn’t construct the faces correct in the first place.
Thanks very much!
— Problem solved
Why doesn’t this work for me? I get:
[b]– Syntax error: at ), expected <factor>
– In line: )
[/b]thanks.
Hi Adam,
I cannot figure out what’s wrong, so I’ll go with a short tutorial. The script works with Editable Poly objects only.
- In 3ds Max go to menu MaxScript > New Script
- Copy the whole script to the new “Untitled – MaxScript” window
- From the menu of that window select File > Evaluate All
- There should be a blue “OK” as last message in the MaxScript Listener
- Select a single Editable Poly in the scene
- Write remCopEdges() in the listener and press enter from the numeric keypad, it should work
I know I’ve been a little tedious, but just to help comprehension
- Enrico