Home Technical Talk

Maxscript help ya'll

Hey all,
So, i have this script that I use a lot, which was originally done by perna.

It works perfectly in Editable Poly, but I decided to update it to work in Edit Poly modifier as well. But since some things don't work the same way, I'm having a tough time making it work :)

So, basically what the script does is..

You select 2 verts and they get connected.

You select one edge and it gets divided with one vert in the middle.

You select 2 edges and if there is a face inbetween, it connects the 2 edges..

If there isn't any face it bridges the 2 or more edges.

if you select caps, it will cap them.

If you select 2 polies it will bridge them.

also, when you select 2 edges and they are next to each other, for example like this.. |_ there will be a face conected to them, so it creates a tri.



So, like I said, It works in Editable Poly, now I just need to make it work In Edit Poly.

Thanks!

macroScript SuperSmartCreate
category:"Pedro Scripts"
toolTip:"Super Smart Create"

(
	local curObj = modPanel.getCurrentObject()
	Case (classOf curObj) of
	(
		Edit_Poly:
		(Case subobjectlevel of
			(
			 1: ($.modifiers[#Edit_Poly].ButtonOp #ConnectVertices)

			 2:	(if (((curObj.getSelection #edge) as array).count == 0) then
				 (
					messagebox "Put the create face code here."
				 )

				 local doBridgeConnect = false
				 Edgs = curObj.GetSelection #edge as array
				 case (Edgs.count) of
				 (
					1: (
						--Inserts a vertex in the selected edge
						curObj.divideEdge (Edgs[1]) 0.5
						curObj.commit()
						subobjectLevel = 1
					)
					2: (
						(
							EdgA = curObj.GetSelection #edge  Edgs[1]
							EdgB = curObj.GetSelection #edge  Edgs[2]

							if (EdgA[2]==EdgB[1]) then
							(
								curObj.CreateFace #(EdgA[1],EdgA[2],EdgB[2])
							)
							else if (EdgB[2] == EdgA[1]) then
							(
								curObj.CreateFace #(EdgB[1],EdgB[2],EdgA[2])
							)
							else
							(
								doBridgeConnect = true
							)
						)
					)
					default: ( doBridgeConnect = true )
				 )
				 if doBridgeConnect then
				 (
					curObj.bridgeSelected = 1
					if not (curObj.EditablePoly.Bridge()) then
					(
						curObj.connectEdgeSegments = 1
						$.modifiers[#Edit_Poly].ButtonOp #ConnectEdges
					)
				 )
			)

			3:	($.modifiers[#Edit_Poly].ButtonOp #Cap)

			4:	(
				if (((curObj.getSelection #face) as array).count < 2) then
					messagebox "Put the create face code here."
				else
					(
						$.modifiers[#Edit_Poly].ButtonOp #BridgePolygon
					)
				)

			 5:	()
			)
		)




		Editable_poly:
		(Case subobjectlevel of
			(
			 1: (curObj.EditablePoly.ConnectVertices ())

			 2:	(if (((polyop.getEdgeSelection $.baseobject) as array).count == 0) then
				 (
					 macros.run "Editable Polygon Object" "EPoly_ECreate"
				 )
				 local doBridgeConnect = false
				 Edgs = polyop.GetEdgeSelection $ as array
				 case (Edgs.count) of
				 (
					1: (
						--Inserts a vertex in the selected edge
						curObj.EditablePoly.divideEdge (Edgs[1]) 0.5 select:on
						subobjectLevel = 1
					)
					2: (
						(
							EdgA = PolyOp.getEdgeVerts  curObj Edgs[1]
							EdgB = PolyOp.getEdgeVerts  curObj Edgs[2]
							if (EdgA[2]==EdgB[1]) then
							(
								curObj.CreateFace #(EdgA[1],EdgA[2],EdgB[2])
							) else
							if (EdgB[2] == EdgA[1]) then
							(
								curObj.CreateFace #(EdgB[1],EdgB[2],EdgA[2])
							) else
							  (
								  doBridgeConnect = true
							  )
						)
					)
					default: ( doBridgeConnect = true )
				 )
				 if doBridgeConnect then
				 (
					 curObj.bridgeSelected = 1
					 if not (curObj.EditablePoly.Bridge()) then
					 (
						 curObj.connectEdgeSegments = 1
						 curObj.EditablePoly.ConnectEdges ()
					 )
				 )
			 )

			 3:	(curObj.EditablePoly.capHoles #Edge)

			 4:	(if ((($.GetSelection #Face) as array).count < 2) then
					 macros.run "Editable Polygon Object" "EPoly_Create"
                 else
					(
						$.bridgeSelected = 1
						$.EditablePoly.Bridge ()
					)
                )

			 5:	()
			)
		)



		unwrap_uvw:
		(Case SubobjectLevel of
			(
			1:  ()
			2: 	()
			3: 	()
			)
		)
	)
)

Replies

  • tynew
    Options
    Offline / Send Message
    tynew polycounter lvl 9
    Thank you! This is SUPER useful, all in a single hotkey! It just freed up a bunch of perna style keyboard shortcuts I've been using :)
  • Pedro Amorim
    Options
    Offline / Send Message
    hehe, yeah, it works for Editable Poly, but i'm still looking for help in making it work on Edit Poly modifier.
  • Mark Dygert
    Options
    Offline / Send Message
    I don't think there is a simple answer to this one because of how max treats editable poly and edit poly as two separate things. They behave similarly but under the hood use different commands.

    I think what you'll have to do is double up the script. You'll have a check at the beginning that detects which mode you're in and uses whatever code is appropriate.

    That means sitting down and rewriting this script with whatever edit poly commands happen to work closest... that's a lot of effort and one of the reasons a lot of people say "screw it" and stick to one or the other. Most people don't like maintaining two sets of code for the same task.
  • RN
    Options
    Offline / Send Message
    RN sublime tool
    Could you please say more about how it's not working?
    Is it giving some error? Is it not doing anything? Is it doing some of the commands but not others?

    Isn't a call to Commit() necessary after the Edit_Poly case, to commit the edits? I'm using this as reference: http://docs.autodesk.com/3DSMAX/15/ENU/MAXScript-Help/index.html?url=files/GUID-B40F84EA-5F19-45B6-AA7C-0ADC77708BBE.htm,topicNumber=d30e388783
  • Pedro Amorim
    Options
    Offline / Send Message
    2:	(if (((curObj.getSelection #edge) as array).count == 0) then
    				 (
    					messagebox "Put the create face code here."
    				 )
    
    				 local doBridgeConnect = false
    				 Edgs = curObj.GetSelection #edge as array
    				 case (Edgs.count) of
    				 (
    					1: (
    						--Inserts a vertex in the selected edge
    						curObj.divideEdge (Edgs[1]) 0.5
    						curObj.commit()
    						subobjectLevel = 1
    					)
    					2: (
    						(
    							EdgA = curObj.GetSelection #edge  Edgs[1]
    							EdgB = curObj.GetSelection #edge  Edgs[2]
    
    							if (EdgA[2]==EdgB[1]) then
    							(
    								curObj.CreateFace #(EdgA[1],EdgA[2],EdgB[2])
    							)
    							else if (EdgB[2] == EdgA[1]) then
    							(
    								curObj.CreateFace #(EdgB[1],EdgB[2],EdgA[2])
    							)
    							else
    							(
    								doBridgeConnect = true
    							)
    						)
    					)
    					default: ( doBridgeConnect = true )
    				 )
    				 if doBridgeConnect then
    				 (
    					curObj.bridgeSelected = 1
    					if not (curObj.EditablePoly.Bridge()) then
    					(
    						curObj.connectEdgeSegments = 1
    						$.modifiers[#Edit_Poly].ButtonOp #ConnectEdges
    					)
    				 )
    			)
    




    This is basically the part that isn't working.


    this code right here is working. it's dividing the edge in 2. puts a vert in the middle.

    --Inserts a vertex in the selected edge
    curObj.divideEdge (Edgs[1]) 0.5
    curObj.commit()
    subobjectLevel = 1



    The main issue is when i have more than 2 edges selected.
    If i have 2 edges it firsts see's if they are connected by a vert, if they are then it creates a face with those 3 verts.

    When i have 2 or more edges that arent connected with a face it bridges them.
    And when there is a face inbetween the edges it should conect the faces with an edge.

    Except the code is only working for spliting the edge and putting the vert in the middle.
    I fixed that part yesterday, and it is like you said, needs a commit function.

    I think the main issue is the GetSelection method.
  • monster
    Options
    Offline / Send Message
    monster polycounter
    GetSelection returns the #named subobject selection, it doesn't convert it to verts. You need to use GetEdgeVertex. Since (unlike PolyOp) there is no GetEdgeVerts you need to call it twice.

    Change this:
    EdgA = curObj.GetSelection #edge  Edgs[1]
    EdgB = curObj.GetSelection #edge  Edgs[2]
    

    To this:
    EdgA = #(EditPolyMod.GetEdgeVertex curObj Edgs[1] 1,EditPolyMod.GetEdgeVertex curObj Edgs[1] 2)
    EdgB = #(EditPolyMod.GetEdgeVertex curObj Edgs[2] 1,EditPolyMod.GetEdgeVertex curObj Edgs[2] 2)
    

    Also, consider using the EditPolyMod interface instead of curObj.Operation() and $.modifiers[#Edit_Poly].Operation(). Your script will run a bit faster, and the code will be a little cleaner.
    --BEFORE
    curObj.divideEdge (Edgs[1]) 0.5
    --AFTER
    EditPolyMod.divideEdge curObj (Edgs[1]) 0.5
    
    --BEFORE
    $.modifiers[#Edit_Poly].ButtonOp #ConnectEdges
    --AFTER
    EditPolyMod.ButtonOp curObj #ConnectEdges
    
  • monster
    Options
    Offline / Send Message
    monster polycounter
    Couple more things.

    You don't need the commit command unless you script uses EditPolyMod.PopUpDialog to bring up a caddie.

    Unlike Editable Poly the EPoly modifier lets you bridge adjacent edges. So you can simplify case 2 of Edit_Poly to just always bridge.
  • RN
    Options
    Offline / Send Message
    RN sublime tool
    I'm not the original poster, but that was enlightening. Thank you for the information.

    Just for clarification, he can use that 'EditPolyMod' interface (called a "standalone interface" I believe) but then he has to specify the object that it will act on. It seems to be faster (reference).
  • Pedro Amorim
    Options
    Offline / Send Message
    Thanks Juan.
    The adjacent edges work now.

    There are a couple issues yet.

    WHen I try to bridge edges i get this error.

    d7f4a69cb5.png

    On this line >
    if not (curObj.EditablePoly.Bridge()) then
    



    When I try to connect edges i get an error on the same line.
    				 if doBridgeConnect then
    				 (
    					curObj.bridgeSelected = 1
    					if not (curObj.EditablePoly.Bridge()) then
    					(
    						curObj.connectEdgeSegments = 1
    						EditPolyMod.ButtonOp curObj #ConnectEdges
    					)
    				 )
    			)
    

    i'm most likely using the wrong syntax.
  • monster
    Options
    Offline / Send Message
    monster polycounter
    I think the Case 2: can be simplified quite a bit. The main problem there is no bridge() operation for the modifier, and the correct bridge command doesn't return true/false. Below I'm just reversing the operation so that if the Connect is not successful then bridge will happen. Finally, we don't need to use CreateFace because bridge will work in all cases.

    I'm short on time right now, but you can probably squeeze this into your full script and see if it works.
    (
    	local curObj = modPanel.getCurrentObject()
    	
    	
    	--STORE GET SELECTION METHOD FOR BETTER PERF
    	getSelection = EditPolyMod.GetSelection
    	
    	Edgs = (getSelection curObj #edge) as array
    	
    	 case (Edgs.count) of
    	 (
    		1: (
    			--INSERTS A VERTEX IN THE SELECTED EDGE
    			EditPolyMod.divideEdge curObj (Edgs[1]) 0.5
    			subobjectLevel = 1
    		)
    		2: (
    			--TRY TO CONNECT, IF SUCCESSFUL EDGE SELECTION WILL CHANGE TO 1
    			EditPolyMod.ButtonOp curObj #ConnectEdges
    			
    			--IF EDGE SELECTION DIDN'T CHANGE THEN BRIDGE
    			if ((getSelection curObj #edge) as array).count != 1 do
    			(
    				EditPolyMod.BridgeEdges curObj Edgs[1] Edgs[2]
    			)
    		)
    	)
     )
    
  • Pedro Amorim
    Options
    Offline / Send Message
    It's working nicely. The problem is that it doesnt work when i have more than 2 edges selected.

    How would I go about changing that?

    I guess there needs a default case as well>
    ?
  • RN
    Options
    Offline / Send Message
    RN sublime tool
    If that tool is supposed to either bridge or connect the current edge selection, but never do these two operations at the same time, then you can do the following:

    - If only one edge in the selection, split it in the middle.

    - If two or more edges are in the selection, try to connect. If the selection changed (the connect operation was partially or fully successful) then stop.
    If the selection did not change (nothing was connected), then bridge the edges.

    Is this adequate?

    The problem is that EditPolyMod \ Edit_Poly can only bridge two edges at a time. It cannot bridge a full selection together.
    What you can do, however, is create a face between those edges like the following:
    --STORE GET SELECTION METHOD FOR BETTER PERF
        getSelection = EditPolyMod.GetSelection
        
        Edgs = (getSelection curObj #edge) as array
        
         case (Edgs.count) of
         (
            1: (
                --INSERTS A VERTEX IN THE SELECTED EDGE
                EditPolyMod.divideEdge curObj (Edgs[1]) 0.5
                subobjectLevel = 1
            )
            default: ( 
                       if ( Edge.count > 0 ) do
                       (
                           --TRY TO CONNECT, IF SUCCESSFUL EDGE SELECTION WILL CHANGE
                           EditPolyMod.ButtonOp curObj #ConnectEdges
                
                           --IF EDGE SELECTION DIDN'T CHANGE THEN TRY "BRIDGE"
                           if ((getSelection curObj #edge) as array).count == Edgs.count do
                           (
                               EditPolyMod.CreateFace ( ( getSelection curObj #vertex ) as array ) curObj
                           )
                        )
                    )
            )
        )
    
    You need to test if CreateFace has a similar behaviour to Bridge from polyOp.
  • Pedro Amorim
    Options
    Offline / Send Message
    I Just added the code for default
    628e58958d.png

    but i'm getting an error

    -- Error occurred in anonymous codeblock; filename: C:\Max2012\3DSclean\scripts_evaluated\Pedro Scripts-SuperSmartCreate.mcr; position: 1209; line: 45
    -- Syntax error: at (, expected "then" or "do"
    -- In line: (
  • monster
    Options
    Offline / Send Message
    monster polycounter
    Add "do" to the end of line 45. :)
  • Pedro Amorim
    Options
    Offline / Send Message
    I got this script working perfectly with the help of Miauu (http://miauumaxscript.blogspot.pt/)

    I will post it in a new thread along with other scripts that i use.

    Cheers guys!
  • tynew
    Options
    Offline / Send Message
    tynew polycounter lvl 9
    Yes please Pedro sir :)
Sign In or Register to comment.