Need help with a while loop in a subselection related tool

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
Old 10 October 2010   #1
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:
	--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:
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 October 2010   #2
I'm sure someone here must be able to figure out what I'm doing wrong...?
 
Old 10 October 2010   #3
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 October 2010   #4
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



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 08:21 AM.


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