CGTalk > Software > Autodesk 3ds max > 3dsMax SDK and MaxScript
Login register
Thread Closed share thread « Previous Thread | Next Thread »  
 
Thread Tools Search this Thread Display Modes
Old 10-15-2010, 04:02 AM   #1
Malkalypse
Jack of All Trades
 
Malkalypse's Avatar
Kevin Mackey
Arlington Hts, USA
 
Join Date: Nov 2005
Posts: 1,295
Send a message via MSN to Malkalypse
Need help with a while loop in a subselection related tool

I'm currently working on a script to make it easier to divide an edit-poly object into sub-selections. The basic idea is that you click on an edge and it selects the entire edge loop UNTIL it reaches the point where it intersects with an existing selected edge loop. The tricky part is that I also want to be able to click on a selected edge loop, and UNSELECT the selected edge loop section by doing so.

I have this script almost worked out, but there is one small section I am having trouble with and can't seem to get past. Basically it has to do with the while loop that builds the array of edges to either add or subtract to the selection. I've tried 2 different variants on the condition for the loop, but each one has its own problem.

I have the problematic lines below, followed by the entirety of the script with the problem area labeled. Feel free to play around with the script if you see other things that can be improved!

Problem area isolated:
Code:
--while hotEdges.numberSet != oldEdges.numberSet do while (hotEdges - oldEdges).numberSet != 0 do /***********************************************/ -- EXPLANATION: -- -- FIRST CONDITION WORKS FINE UNTIL A -- SINGLE-EDGED LOOP IS CLICKED, THEN IT STOPS -- SELECTING MORE THAN ONE EDGE AT A TIME -- UNTIL THE SCRIPT IS RESTARTED -- -- THE SECOND CONDITION WORKS FINE UNLESS -- THE SAME EDGE LOOP IS CLICKED TWICE IN A ROW -- (I.E. SELECTED THEN UNSELECTED), IN WHICH -- CASE, ONLY A SINGLE EDGE WILL BE UNSELECTED /***********************************************/ ( oldEdges = #{}; for s in hotEdges do append oldEdges s findExtants hotEdges for v in xVerts do extendLoop v )


The script in its entirety:
Code:
global xVerts, xEdges, hotEdges global restartTool = false global initSel = false allEdges = #{} -- all edges of the selected object selEdges = #{} -- selected edges hotEdges = #{} -- specified edges oldEdges = #{} -- previously specified edges -------------------------------------------------------------- -- Function to find the extant edges of a specified edge array -- edges: specified edges -------------------------------------------------------------- fn findExtants edges = ( xVerts = #{} -- i.e. "extant vertices" xEdges = #{} -- i.e. "extend edges" edgeVerts = polyOp.getVertsUsingEdge $ edges -- vertices of all specified edges for v in (edgeVerts as array) do -- for all vertices in edgeVerts array ( nEdges = polyOp.getEdgesUsingVert $ v -- edges adjoining vertex v nEdges -= (nEdges - edges - selEdges) -- keep only edges that are specified or selected nEdges = nEdges as array -- Declare extant vertices and edges if initSel == false then (if nEdges.count == 1 do (append xVerts v; append xEdges nEdges[1])) else (if nEdges.count == 2 do (append xVerts v; append xEdges nEdges[1])) ) -- end v loop ) -- end function (findExtants) ------------------------------- -------------------------------------------------- -- Function to extend the loop of hot edges by one -- v: extant vertex to use as starting point -------------------------------------------------- fn extendLoop v = ( vertEdges = polyOp.getEdgesUsingVert $ v -- edges adjoining vertex v xEdge = vertEdges - (allEdges - hotEdges) -- i.e. "extant edge" xEdgeFaces = (polyOp.getFacesUsingEdge $ xEdge) as array -- faces of extant edge -- Add vertex edge(s) that share(s) no faces with extant edge to hot edges for s in vertEdges do ( ff = (polyOp.getFacesUsingEdge $ s) as array if (findItem xEdgeFaces ff[1] == 0) and (findItem xEdgeFaces ff[2] == 0) do append hotEdges s ) -- end s loop ) -- end function (extendLoop) ------------------------------ ----------------------------------------------------------------------------------- -- Function to select an edge loop up to its intersection with other selected loops ----------------------------------------------------------------------------------- fn loopToIntersect = ( if (hotEdges - selEdges).numberSet == 0 then initSel = true else initSel = false /***********************************************/ -- PROBLEM CODE: /***********************************************/ --while hotEdges.numberSet != oldEdges.numberSet do while (hotEdges - oldEdges).numberSet != 0 do /***********************************************/ ( oldEdges = #{}; for s in hotEdges do append oldEdges s findExtants hotEdges for v in xVerts do extendLoop v ) if initSel == false then selEdges += hotEdges -- add hot edges to edge selection else selEdges -= hotEdges -- remove hot edges from edge selection polyOp.setEdgeSelection $ selEdges; update $ ) -- end function (loopToIntersect) ---------------------------------------------- ---------------------------------------------------------------- -- Function to determine the distance between a point and a line -- Special thanks to prettyPixel ---------------------------------------------------------------- fn pointLineDist pA pB pC = ( local vAB = pB - pA local vAC = pC - pA (length (cross vAB vAC)) / (length vAB) ) -- end function (pointLineDist) ------------------------------- ------------------------------------------------------ -- Function to determine the edge closest to the mouse ------------------------------------------------------ fn getMouseEdge = ( vertCount = polyop.getNumVerts $.baseobject backVerts = (polyop.getVertsByFlag $.baseobject 8) okVerts = (#{1..vertCount} - backVerts - (polyop.getHiddenVerts $.baseobject)) as array if vertCount != 0 do ( mp = mouse.pos -- Find non-hidden, front facing vertex closest to the mouse ------------------------------------------------------------ vertDistArray = #(#(),#()) for v in okVerts do ( m = gw.wTranspoint (polyop.getVert $.baseobject v node:$) append vertDistArray[1] v append vertDistArray[2] (distance mp [m.x, m.y]) ) minIndex = findItem vertDistArray[2] (aMin vertDistArray[2]) minVert = vertDistArray[1][minIndex] ------------------------------------------------------------ -- Find closest neighboring vertex ----------------------------------------------------------------------- vertEdges = polyOp.getEdgesUsingVert $ minVert nVerts = ((polyOp.getVertsUsingEdge $ vertEdges) - #{minVert}) as array nDistArray = #(#(), #()) for v in nVerts do ( m = gw.wTranspoint (polyop.getVert $.baseobject v node:$) append nDistArray[1] v append nDistArray[2] (distance mp [m.x, m.y]) ) nMinIndex = findItem nDistArray[2] (aMin nDistArray[2]) nMinVert = nDistArray[1][nminIndex] ----------------------------------------------------------------------- nVertEdges = polyOp.getEdgesUsingVert $ nMinVert hotEdges = (vertEdges - (vertEdges - nVertEdges)) ) -- end if (vertCount != 0) completeredraw() gw.setcolor #line (yellow) gw.polyLine #(polyOp.getVert $ minVert, polyOp.getVert $ nMinVert) false gw.enlargeUpdateRect #whole gw.updateScreen() ) -- end function (getMouseEdge) -------------------------------- tool getLoopToIntersect ( on freeMove do getMouseEdge() on mousePoint clickno do ( allEdges = #{1..(polyOp.getNumEdges $)} -- all edges of the selected object selEdges = polyOp.getEdgeSelection $ -- selected edges getMouseEdge() -- find edge closest to the mouse loopToIntersect() restartTool = true; #stop ) -- Restart mouse tool unless aborted on mouseAbort clickno do (restartTool = false) on stop do (if restartTool == true do startTool getLoopToIntersect) ) if $ != undefined do startTool getLoopToIntersect
 
Old 10-17-2010, 10:30 PM   #2
Malkalypse
Jack of All Trades
 
Malkalypse's Avatar
Kevin Mackey
Arlington Hts, USA
 
Join Date: Nov 2005
Posts: 1,295
Send a message via MSN to Malkalypse
I'm sure someone here must be able to figure out what I'm doing wrong...?
 
Old 10-18-2010, 02:02 AM   #3
Malkalypse
Jack of All Trades
 
Malkalypse's Avatar
Kevin Mackey
Arlington Hts, USA
 
Join Date: Nov 2005
Posts: 1,295
Send a message via MSN to Malkalypse
And it looks like the one to figure it out was me.

If anyone is interested, I just needed to clear the "oldEdges" bitarray in the loopToIntersect function BEFORE the while loop (while still leaving one inside the loop as well), and then use the first condition for the loop statement.
 
Old 10-18-2010, 02:02 AM   #4
CGTalk Moderation
Lord of the posts
CGTalk Forum Leader
 
Join Date: Sep 2003
Posts: 1,066,480
Thread automatically closed

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
__________________
CGTalk Policy/Legalities
Note that as CGTalk Members, you agree to the terms and conditions of using this website.
 
Thread Closed share thread


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 01:50 PM.


Powered by vBulletin
Copyright ©2000 - 2016, Jelsoft Enterprises Ltd.