[Closed] Super simple, how to create splines from selection (in array)?
Here is what I’m trying to do, in english.
I have an object selected.
- Go into Border sub-object mode.
- Ctrl+A to select all open borders.
- Make Shape from selection.
- Delete original object, leaving only the new spline object.
I have the following code.
local sel = selection as array
setCommandPanelTaskMode #modify
for obj in sel do
(
subobjectLevel = 3
actionMan.executeAction 0 "40021"
obj.EditablePoly.createShape "Shape132" off obj
subobjectLevel = 0
delete obj
)
This is actually working great on a single object, but the problem is if I select two or more objects, it doesn’t work. And in fact, it deletes the objects I had selected, deletes the splines from them, and then selects everything in my whole scene. I’ve done stuff with arrays before and never had this problem. And ideas? I have to do this to like a dozen objects, and I would like to be able to do it in a single click.
The following code should work with multiple selections.
(
for obj in (selection as array) do
(
openedges = polyop.getopenedges obj
polyop.createshape obj openedges smooth:false name:("shape_"+obj.name)
delete obj
)
)
fn extractBorderEdges = if (object = getcurrentselection()) != #() do
(
openedges = polyop.getopenedges ; shape = polyop.createshape
delete (for i = object.count to 1 by -1 where isKindOf object[i] Editable_Poly collect
(
shape object[i] (openedges object[i]) smooth:off name:("shape_#"+i as string) ; object[i]
)) ; select $'shape_#*'
)
extractBorderEdges()
When I use phone and walk, I write code like that.:surprised
fn extractBorderEdges = if (object = getcurrentselection()) != #() do
(
openedges = polyop.getopenedges
shape = polyop.createshape
delete
(
for e = object.count to 1 by -1 where isKindOf object[e] Editable_Poly collect
(
shape object[e] (openedges object[e]) smooth:off name:("shape_#"+e as string)
object[e]
)
)
select $'shape_#*'
)
extractBorderEdges()
I really appreciate all the help and humor here. Thanks for the help guys, and not only does it work on multiple objects, it’s faster even on a single object.
One more version
I added two arguments:
“shapeName” – you can add custom name for newley created shapes
“deleteAllEPloy” – if true (on) then all Editable Poly object in selection will be deleted
or if false (off) then EPoly objects which have open edges will be deleted.
fn extractBorderEdges shapeName: deleteAllEPloy:on = if (object = getcurrentselection()) != #() do
(
name = if shapeName != unsupplied then shapeName else "Shape_#"
openedges = polyop.getopenedges
shape = polyop.createshape
with redraw off
(
array = for e = object.count to 1 by -1 where isKindOf object[e] Editable_Poly collect
(
if (edge = openedges object[e]).isEmpty then (if deleteAllEPloy then object[e] else dontCollect) else
(
shape object[e] edge smooth:off name:(name + e as string)
object[e]
)
)
delete array
execute ("select $'"+name+"*'")
)
)
extractBorderEdges shapeName:"OpenShape" deleteAllEPloy:off
it might be improved.
first:
execute ("select $....")
this is not a good solution… also it’s possible to make a function that will work with PolyMeshObject as well. and of course we don’t need to select nodes. and mapped function is better in this case
mapped fn makeShapeFromBorder node name: wirecolor: smooth:off deleteIt:off newshapes:#() =
(
if (ep = iskindof node Editable_Poly) or iskindof node PolyMeshObject do
(
local sp
if name == unsupplied do name = node.name + "_border"
local base = if ep then node else node.baseobject
local edges = polyop.getopenedges base
local num = objects.count
polyop.createshape base edges smooth:smooth name:name node:node
if (sp = if objects.count > num do objects[objects.count]) != undefined do
(
sp.wirecolor = if wirecolor == unsupplied then (node.wirecolor*0.5) else wirecolor
append newshapes sp
)
if deleteit do delete node
sp
)
)
/*
delete objects
converttopoly (plane pos:[0,0,10])
addmodifier (converttopoly (plane())) (edit_normals())
(
sps = #()
makeShapeFromBorder (objects as array) newshapes:sps --deleteit:on
sps
)
*/
Ok. But “edit_normals” not make sense to me.
Also I think is better to use “geometry” instead of “objects” in this case.
One more thing
You showed us several times that is not good to call interface fn’s from “loop” and that
is better do delete or select nodes at once and not one by one.
That’s why I used for-loop (backward method)
i add edit_normals modifier just to show that function works with polymeshobject as well as with editable_poly
interface (and structure) functions uses less memory when you use them from a variable. in this case system doesn’t create an instance of this interface(class) for ever call. so it makes sense to do this trick in long loops (iterating subobject, particles, or a lot of nodes).
in our case it’s very unlikely that we will do it for tons of objects.
the similar logic for deleting. but i’ve expected your doubts about this matter. and in the function i show how to collect shapes. the same way i would collect source poly nodes.
i told many times that every optimization makes sense usually for specific cases only. if you know that some function will never be used in extreme situation it’s much better to keep it clear than complicate the code by unnecessary tricks.
mapped function allows you work with list of nodes as well as with a single node.
ps. i’ve used (objects as array) just only because the word ‘objects’ is one letter less than ‘geometry’
You always have good reason
This is very useful info for sure.
For this solution we will need to consiter at least two more cases:
#1 when user assigne Edit_Poly/Mesh modifier and make some topology changes at this level.
(by removing verts, edges or faces) .
#2 if object have “Sub-Selection” modifier like Vol_select, Poly Select etc. and add on the top Delete Mesh modifier.
In 1st case class of object can be PolyMeshObject or Editable_Mesh and for 2nd just Editable_Mesh.
great script people hehehehe ahahahahaha
btw why doesn’t denis’ script work? Gazybara’s script worked well for me.
such an awesome idea.