Hey, i am back with another maxscript issue im facing.
in Maxscript for sw 3D Studio Max 2016
I am currently trying to build a series of functions to among other things get loop/ring edge "spans" between edge selections or specific edges.
The first step in such a function is reliably getting the next edge in the loop/ring from an edge.
I have explored a few methods underlined below:
Method 1:
Using the functions setRingshift/setLoopShift from the editablepoly interface,
and getting edge selection wont work for me for two reasons.
1: They do not have an equivalent function in edit_poly
( Editpoly has the RingSelect/LoopSelect functions.
But they both rely on +- edgesteps from each time you enter an editpoly,
which is a pain to get around*Test it out* ).
I could use PolytoolsSelect.GrowRing/Loop() ( Which grows in both directions ).
But then ill also have to also sort through the new edge selection for the edge i want to get
2: It seems horribly inefficient to set + use function to set + get selections to get an edge index, each time you want a new edge.
I ideally want to use a function that can do this without selecting.
Method 2:
Using conversion to get the 1 or 2 closest ring/loop edges ( In both directions )
Step 1:
GetFacesUsingEdge to get the ( 1 or 2 ) Connecting faces from the first edge.
Then GetEdgesUsingFace ( I had to do a custom function for editpoly for this )
To get the edges from those faces ( faceEdges )
Step 2:
GetVertsUsingEdge to get the verts from the first edge.
Then GetEdgesUsingVert to get the connecting edges from those verts(vertEdges)
Step 3:
To get the next 1 or 2 ring edges remove the vertEdges from the faceEdges.
To get the next 1 or 2 loop edges remove the faceEdges from the vertEdges.
The issue with this method is that it has a few problems with different topologies(Poles etc.). As well as i cant figure out the rule of how to get or figure out a certain direction(loop up/down ring left/right).
Is it the edge index order that determines the direction perhaps?
Method 3:
I have not really tested this but im putting it in here just for reference.
Setting the first edge as selection and doing a whole loop/ring selection.
Getting the new selection and getting the 1 closest -+ edge index to the first edge in the resulting BitArray.
This has the same second issue as method 1 as well probably not working in many(all) cases.
I am not sure how to sort out direction here either.
My question is how do i do this in a good way? Am i far off?
I know i probably need to do much more situation handling in the second method.
But how do i catch these situations?
I know border edges can be determined my if the edge has only 1 face connected.
But the others like poles etc. I have no idea.
I am probably also not catching other topology things that i havent thought of yet.
The Miauu scriptpack nr2 ( I think ) has a loop/ring step between that works for > 2 edges.
And IllusionCatalyst Ic.shape ( Selectspan ) Has a loop/ring step/spanning method that works for 2 edges.
But i cant figure out the inner workings of these functions from just looking at the code.
And for miauus pack i cant because it is encrypted.
I am also aware of PolytoolsSelect.StepLoop that selects the loop edges between two edges. that i could impliment as a set+set+get function for getting loop spans.
But this has the same issue as issue 2 in method 1. As well as not allowing for more control over the selection.
And also for some reason it does not have a similar StepRing function. And this is the most important functionality im after.
I really hope someone more experienced than me can answer.
I would be eternally grateful as iwe already spent almost a week on just this problem.
Edit: Fixed up the post fomatting and punctuation ( Hopefully ) . English is not my primary language
Replies
2. Lack of punctuation and capitalization makes this difficult to read.
3. Subject should mention this is Maxscript, to pull in the right people.
Otherwise the post seems well written. If I could help I would. Fixing the above will get you answers faster.
- Get polys from a single current edge (e.g. in ring)
- For each poly, get edges - if it has 4 edges, then it's a quad
- For each quad, get edges, and get verts from each edge
- Check the edges from the quad and only keep the edge where both the verts were not found in your original edge - this will be the edge on the "other side" of the quad (i.e. next ring up/down)
No idea how slow/fast this would be in script but at least it wouldn't involve any selection/converting through built-in commands as that will definitely be slower than doing it all internally.To be honest I haven't done much geometry work in maxscript but it seems like something you could do with all the internal "getBlahByBlah" functions and some appropriate sorting/checking.
Edit: SyncViewS (the guy who wrote the IllusionCatalyst tools) is actually a fairly regular Polycounter so it's possible he might be able to help you out here too, he's a smart and helpful guy
Also, considering English is not your first language, all your writing is excellent!
grabbed from edge straighten from Christoph Kubisch:
fn bitarray2array bitarray_ =
(
local outgoing = for BA in bitarray_ collect BA
)
-- Written by Laszlo Sebo (MeshTools 2.5)
fn findnewedges_poly obj this_edge = -- finds the edges that are going from this edge onto edgeloops
(
local nextedge = #()
local exclude_edges = #()
local localverts = polyop.getedgeverts obj this_edge
local edge_faces = polyop.getedgefaces obj this_edge
for nf in edge_faces do join exclude_edges (polyop.getfaceedges obj nf)
local nextedges = polyop.getedgesusingvert obj localverts[1] --check one end of the edge
if ((bitarray2array nextedges).count <= 4) do
nextedge = bitarray2array (nextedges - (exclude_edges as bitarray) * nextedges)
local nextedges = polyop.getedgesusingvert obj localverts[2] --check one other of the edge
if ((bitarray2array nextedges).count <= 4) do
join nextedge (bitarray2array (nextedges - (exclude_edges as bitarray) * nextedges))
nextedge
)
For reference this the current code i am testing inside max by using the script editor
(tried to put it in some kind of code block) (edit: made it blue as it was hard to see with the grey text on gray bg, also fixed a bitarray assignement)
To test it:
Copy paste it into a new file in the script editor.
Do an evaluate all
Then create a primitive cylinder etc. in the scene
Put an Edit_Poly on top or collapse to editable_poly
Go into the edge subobject(2) and select an edge
Open the listener(F11) .
Type in a new line "testGNRL()" (without the quotes). Press enter
The listener window will output some info about the process. As well as the candidate edges will be selected in the viewport
For now this appears to work well for normal quad grid topology and borders atleast. But for edges in or around corners, poles, ngons and tris it gets a bit "confused"