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!

  1. macroScript SuperSmartCreate
  2. category:"Pedro Scripts"
  3. toolTip:"Super Smart Create"
  4.  
  5. (
  6. local curObj = modPanel.getCurrentObject()
  7. Case (classOf curObj) of
  8. (
  9. Edit_Poly:
  10. (Case subobjectlevel of
  11. (
  12. 1: ($.modifiers[#Edit_Poly].ButtonOp #ConnectVertices)
  13.  
  14. 2: (if (((curObj.getSelection #edge) as array).count == 0) then
  15. (
  16. messagebox "Put the create face code here."
  17. )
  18.  
  19. local doBridgeConnect = false
  20. Edgs = curObj.GetSelection #edge as array
  21. case (Edgs.count) of
  22. (
  23. 1: (
  24. --Inserts a vertex in the selected edge
  25. curObj.divideEdge (Edgs[1]) 0.5
  26. curObj.commit()
  27. subobjectLevel = 1
  28. )
  29. 2: (
  30. (
  31. EdgA = curObj.GetSelection #edge Edgs[1]
  32. EdgB = curObj.GetSelection #edge Edgs[2]
  33.  
  34. if (EdgA[2]==EdgB[1]) then
  35. (
  36. curObj.CreateFace #(EdgA[1],EdgA[2],EdgB[2])
  37. )
  38. else if (EdgB[2] == EdgA[1]) then
  39. (
  40. curObj.CreateFace #(EdgB[1],EdgB[2],EdgA[2])
  41. )
  42. else
  43. (
  44. doBridgeConnect = true
  45. )
  46. )
  47. )
  48. default: ( doBridgeConnect = true )
  49. )
  50. if doBridgeConnect then
  51. (
  52. curObj.bridgeSelected = 1
  53. if not (curObj.EditablePoly.Bridge()) then
  54. (
  55. curObj.connectEdgeSegments = 1
  56. $.modifiers[#Edit_Poly].ButtonOp #ConnectEdges
  57. )
  58. )
  59. )
  60.  
  61. 3: ($.modifiers[#Edit_Poly].ButtonOp #Cap)
  62.  
  63. 4: (
  64. if (((curObj.getSelection #face) as array).count < 2) then
  65. messagebox "Put the create face code here."
  66. else
  67. (
  68. $.modifiers[#Edit_Poly].ButtonOp #BridgePolygon
  69. )
  70. )
  71.  
  72. 5: ()
  73. )
  74. )
  75.  
  76.  
  77.  
  78.  
  79. Editable_poly:
  80. (Case subobjectlevel of
  81. (
  82. 1: (curObj.EditablePoly.ConnectVertices ())
  83.  
  84. 2: (if (((polyop.getEdgeSelection $.baseobject) as array).count == 0) then
  85. (
  86. macros.run "Editable Polygon Object" "EPoly_ECreate"
  87. )
  88. local doBridgeConnect = false
  89. Edgs = polyop.GetEdgeSelection $ as array
  90. case (Edgs.count) of
  91. (
  92. 1: (
  93. --Inserts a vertex in the selected edge
  94. curObj.EditablePoly.divideEdge (Edgs[1]) 0.5 select:on
  95. subobjectLevel = 1
  96. )
  97. 2: (
  98. (
  99. EdgA = PolyOp.getEdgeVerts curObj Edgs[1]
  100. EdgB = PolyOp.getEdgeVerts curObj Edgs[2]
  101. if (EdgA[2]==EdgB[1]) then
  102. (
  103. curObj.CreateFace #(EdgA[1],EdgA[2],EdgB[2])
  104. ) else
  105. if (EdgB[2] == EdgA[1]) then
  106. (
  107. curObj.CreateFace #(EdgB[1],EdgB[2],EdgA[2])
  108. ) else
  109. (
  110. doBridgeConnect = true
  111. )
  112. )
  113. )
  114. default: ( doBridgeConnect = true )
  115. )
  116. if doBridgeConnect then
  117. (
  118. curObj.bridgeSelected = 1
  119. if not (curObj.EditablePoly.Bridge()) then
  120. (
  121. curObj.connectEdgeSegments = 1
  122. curObj.EditablePoly.ConnectEdges ()
  123. )
  124. )
  125. )
  126.  
  127. 3: (curObj.EditablePoly.capHoles #Edge)
  128.  
  129. 4: (if ((($.GetSelection #Face) as array).count < 2) then
  130. macros.run "Editable Polygon Object" "EPoly_Create"
  131. else
  132. (
  133. $.bridgeSelected = 1
  134. $.EditablePoly.Bridge ()
  135. )
  136. )
  137.  
  138. 5: ()
  139. )
  140. )
  141.  
  142.  
  143.  
  144. unwrap_uvw:
  145. (Case SubobjectLevel of
  146. (
  147. 1: ()
  148. 2: ()
  149. 3: ()
  150. )
  151. )
  152. )
  153. )

Replies

  • tynew
    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
    hehe, yeah, it works for Editable Poly, but i'm still looking for help in making it work on Edit Poly modifier.
  • Mark Dygert
    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
    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
    1. 2: (if (((curObj.getSelection #edge) as array).count == 0) then
    2. (
    3. messagebox "Put the create face code here."
    4. )
    5.  
    6. local doBridgeConnect = false
    7. Edgs = curObj.GetSelection #edge as array
    8. case (Edgs.count) of
    9. (
    10. 1: (
    11. --Inserts a vertex in the selected edge
    12. curObj.divideEdge (Edgs[1]) 0.5
    13. curObj.commit()
    14. subobjectLevel = 1
    15. )
    16. 2: (
    17. (
    18. EdgA = curObj.GetSelection #edge Edgs[1]
    19. EdgB = curObj.GetSelection #edge Edgs[2]
    20.  
    21. if (EdgA[2]==EdgB[1]) then
    22. (
    23. curObj.CreateFace #(EdgA[1],EdgA[2],EdgB[2])
    24. )
    25. else if (EdgB[2] == EdgA[1]) then
    26. (
    27. curObj.CreateFace #(EdgB[1],EdgB[2],EdgA[2])
    28. )
    29. else
    30. (
    31. doBridgeConnect = true
    32. )
    33. )
    34. )
    35. default: ( doBridgeConnect = true )
    36. )
    37. if doBridgeConnect then
    38. (
    39. curObj.bridgeSelected = 1
    40. if not (curObj.EditablePoly.Bridge()) then
    41. (
    42. curObj.connectEdgeSegments = 1
    43. $.modifiers[#Edit_Poly].ButtonOp #ConnectEdges
    44. )
    45. )
    46. )




    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
    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:
    1. EdgA = curObj.GetSelection #edge Edgs[1]
    2. EdgB = curObj.GetSelection #edge Edgs[2]

    To this:
    1. EdgA = #(EditPolyMod.GetEdgeVertex curObj Edgs[1] 1,EditPolyMod.GetEdgeVertex curObj Edgs[1] 2)
    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.
    1. --BEFORE
    2. curObj.divideEdge (Edgs[1]) 0.5
    3. --AFTER
    4. EditPolyMod.divideEdge curObj (Edgs[1]) 0.5
    5.  
    6. --BEFORE
    7. $.modifiers[#Edit_Poly].ButtonOp #ConnectEdges
    8. --AFTER
    9. EditPolyMod.ButtonOp curObj #ConnectEdges
  • monster
    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
    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
    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 >
    1. if not (curObj.EditablePoly.Bridge()) then



    When I try to connect edges i get an error on the same line.
    1. if doBridgeConnect then
    2. (
    3. curObj.bridgeSelected = 1
    4. if not (curObj.EditablePoly.Bridge()) then
    5. (
    6. curObj.connectEdgeSegments = 1
    7. EditPolyMod.ButtonOp curObj #ConnectEdges
    8. )
    9. )
    10. )

    i'm most likely using the wrong syntax.
  • monster
    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.
    1. (
    2. local curObj = modPanel.getCurrentObject()
    3. --STORE GET SELECTION METHOD FOR BETTER PERF
    4. getSelection = EditPolyMod.GetSelection
    5. Edgs = (getSelection curObj #edge) as array
    6. case (Edgs.count) of
    7. (
    8. 1: (
    9. --INSERTS A VERTEX IN THE SELECTED EDGE
    10. EditPolyMod.divideEdge curObj (Edgs[1]) 0.5
    11. subobjectLevel = 1
    12. )
    13. 2: (
    14. --TRY TO CONNECT, IF SUCCESSFUL EDGE SELECTION WILL CHANGE TO 1
    15. EditPolyMod.ButtonOp curObj #ConnectEdges
    16. --IF EDGE SELECTION DIDN'T CHANGE THEN BRIDGE
    17. if ((getSelection curObj #edge) as array).count != 1 do
    18. (
    19. EditPolyMod.BridgeEdges curObj Edgs[1] Edgs[2]
    20. )
    21. )
    22. )
    23. )
  • Pedro Amorim
    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
    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:
    1. --STORE GET SELECTION METHOD FOR BETTER PERF
    2. getSelection = EditPolyMod.GetSelection
    3. Edgs = (getSelection curObj #edge) as array
    4. case (Edgs.count) of
    5. (
    6. 1: (
    7. --INSERTS A VERTEX IN THE SELECTED EDGE
    8. EditPolyMod.divideEdge curObj (Edgs[1]) 0.5
    9. subobjectLevel = 1
    10. )
    11. default: (
    12. if ( Edge.count > 0 ) do
    13. (
    14. --TRY TO CONNECT, IF SUCCESSFUL EDGE SELECTION WILL CHANGE
    15. EditPolyMod.ButtonOp curObj #ConnectEdges
    16. --IF EDGE SELECTION DIDN'T CHANGE THEN TRY "BRIDGE"
    17. if ((getSelection curObj #edge) as array).count == Edgs.count do
    18. (
    19. EditPolyMod.CreateFace ( ( getSelection curObj #vertex ) as array ) curObj
    20. )
    21. )
    22. )
    23. )
    24. )
    You need to test if CreateFace has a similar behaviour to Bridge from polyOp.
  • Pedro Amorim
    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
    Offline / Send Message
    monster polycounter
    Add "do" to the end of line 45. :)
  • Pedro Amorim
    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
    Offline / Send Message
    tynew polycounter lvl 9
    Yes please Pedro sir :)
Sign In or Register to comment.