Forum Groups
  All forums
    Help & Feedback
      Questions
      Work in progress
      Finished Art
      Non-Max related
    Community
      Offtopic
      News
    Hardware
    Photography



Maxunderground news unavailable

 
First page  Go to the previous page   [01]  [02]  Go to the next page  Last page
 
More script issues. translating single functions to multiple selections?
show user profile  Dave
I know... I know, I'm sorry.

I've been going back through previous scripts where I do this, but to no avail. I have ripped some script from another script and chopped it all down so it does exactly what I want. (gets bounding box of an object and turns that bounding box into an actual box)

Problem is, I can only get it to work on one object at a time, whereas I need to run this through multiple objects. I thought I had it with things like "for obj = 1 to selection.count do", "for obj in selection" and whatever else... but it's just not working, likely due to my lack of fundamental understanding. Here's the script:

rollout tester "bounding box"
(
pickbutton bbox "Pick Object"
on bbox picked sel do

(
select sel

--Reset Pivot to Center of Object
CenterPivot $

--Set Bounding Box Coords
BoundX = sel.max.x - sel.min.x
BoundY = sel.max.y - sel.min.y
BoundZ = sel.max.z - sel.min.z

--Build Box--
PoSvariableX = $.pos.x
PoSvariableY = $.pos.y
PoSvariableZ = $.min.z

macros.run "Objects Primitives" "box"
Box lengthsegs:1 widthsegs:1 heightsegs:1 length:BoundY width:BoundX height:BoundZ mapcoords:on pos:[PoSvariableX, PoSvariableY, PoSvariableZ] isSelected:on
)

)

createDialog tester



My first issue was this dude is using a pickbutton, whereas I need a regular button. I tried that though. I'm pretty much out of options here, I'm going to have a look at what Nik did in the last script he wrote for me, with this array stuff:

mySel = #()
mySel = selection as array

and see if I have any other luck with that, but I need to take a few painkillers and have a little break before I go insane. So I thought I might as well reach out to the masses at the same time.


"I flew over Egypt once"

read 472 times
11/27/2014 7:55:37 PM (last edit: 11/27/2014 7:56:23 PM)
show user profile  Dave
Well shit on my balls, I got it working.

for obj in selection do
(
--Reset Pivot to Center of Object
CenterPivot $

--Set Bounding Box Coords
BoundX = obj.max.x - obj.min.x
BoundY = obj.max.y - obj.min.y
BoundZ = obj.max.z - obj.min.z

--Build Box--
PoSvariableX = obj.pos.x
PoSvariableY = obj.pos.y
PoSvariableZ = obj.min.z

Box lengthsegs:1 widthsegs:1 heightsegs:1 length:BoundY width:BoundX height:BoundZ mapcoords:on pos:[PoSvariableX, PoSvariableY, PoSvariableZ]
)


I also started doing another version but have it create cylinders instead of boxes. It would determine the orientation of the cylinder based on the longest distance between min and max axis'.. axeses? axises. Whatever.

So, it only works if you're converting long cylindrical objects... not so good with the short stumpy ones.



"I flew over Egypt once"

read 460 times
11/27/2014 11:46:13 PM (last edit: 11/27/2014 11:46:13 PM)
show user profile  Dave
If anyone wants the bounding box to cylinder "converter", here it is:


for obj in selection do

(
--Reset Pivot to Center of Object
CenterPivot $

--Set Bounding Box Coords
BoundX = obj.max.x - obj.min.x
BoundY = obj.max.y - obj.min.y
BoundZ = obj.max.z - obj.min.z
BoundX2 = BoundX *= 0.5
BoundY2 = BoundY *= 0.5
BoundZ2 = BoundZ *= 0.5
BoundX3 = BoundX * 2
BoundY3 = BoundY * 2
BoundZ3 = BoundZ * 2

--Build Cylinder--
UpPoSvariableX = obj.pos.x
UpPoSvariableY = obj.pos.y
UpPoSvariableZ = obj.min.z

SiPoSvariableX = obj.pos.x
SiPoSvariableY = obj.max.y
SiPoSvariableZ = obj.pos.z

FrPoSvariableX = obj.min.x
FrPoSvariableY = obj.pos.y
FrPoSvariableZ = obj.pos.z

if BoundZ >= BoundX then
Cylinder smooth:on heightsegs:1 capsegs:1 sides:6 height:BoundZ3 radius:BoundY2 mapcoords:on pos:[UpPoSvariableX, UpPoSvariableY, UpPoSvariableZ]
else
if BoundY >= BoundX then
Cylinder smooth:on heightsegs:1 capsegs:1 sides:6 height:BoundY3 radius:BoundX2 mapcoords:on transform:(matrix3 [1,0,0] [0,0,1] [0,-1,0] [SiPoSvariableX, SiPoSvariableY, SiPoSvariableZ])
else
if BoundX >= BoundY then
Cylinder smooth:on heightsegs:1 capsegs:1 sides:6 height:BoundX3 radius:BoundY2 mapcoords:on transform:(matrix3 [0,1,0] [0,0,1] [1,0,0] [FrPoSvariableX, FrPoSvariableY, FrPoSvariableZ])
)


Like I said though, it gets the orientation based on the longest axis. So this won't work as desired on cylinders where the height is lower than its radius.

Edit
Whoops, it had a segment value that references a spinner (which isn't included) so I've just set that to 6

Double Edit
Ah... and it seems to create some with the normals flipped. Fucking... whatever. It'll do!

Triple Edit
Fixed!

"I flew over Egypt once"

read 455 times
11/28/2014 12:19:55 AM (last edit: 11/28/2014 12:31:35 AM)
show user profile  Garp
Dave, just a few things , if you don't mind.

centerPivot() is a mapped function. If you pass it a collection of objects, it operates on each in turn. It just saves you writing a loop, really.
Your code right now centers the pivots of all selected objects each time through the loop. Either move centerPivot $ before the loop or change it to centerPivot obj.

If you don't care about recentering the original pivots (otherwise skip this) and use centerPivot() just to compute the positions of the bounding boxes' centers, obj.center does just that. It's equal to (obj.min + obj.max) / 2.

You might want to change BoundX2 = BoundX *= 0.5 to BoundX2 = BoundX * 0.5. Then use BoundX for the height or BoundX2 for the radius. Compound operators like *= assign the result back to their first operand. That is, BoundX *= 0.5 halves the value in BoundX, which you later double to get the original extent back.

I'm not following the logic in your if clauses. If BoundZ >= BoundX is indeed true but BoundY is greater than both, you're still aligning the cylinder to the Z axis. Probably not what you meant.

Finally, a tip. Nodes have a .dir property that defines the direction of their Z axis. It's simpler to use than tranform matrices, e.g. cylinder dir:[1,0,0] will create a default cylinder aligned to the X axis.
Also, mxs conveniently provides the predefined variables x_axis, y_axis and z_axis, set to [1,0,0], [0,1,0] and [0,0,1], respectively. So the above can be rewritten as cylinder dir:x_axis. It looks almost like plain english :)




read 434 times
11/28/2014 7:41:48 AM (last edit: 11/28/2014 8:03:38 AM)
show user profile  Dave
Ah cheers Garp. Good tips!

Yeah... the halving thing. It really confused me. Everything was working as expected until I added a secondary cylinder to be built, and then all of a sudden it started creating them at half the height, so I created the "Bound-3" variables to compensate. I'll look into it though.

Not completely following you on the BoundZ >= BoundX thing, in that particular line I do want the cylinder created on the Z, and I don't know how BoundY is greater than both?

I'll definitely see if I can do this .dir stuff, that sounds a lot simpler... though I'd still have to give it the same Bound >= Bound thing right? Maybe it's not doing what I think it's doing but the idea is basically just to say "On the original object, if the height is larger than its radius, create a cylinder in this direction"

"I flew over Egypt once"

read 426 times
11/28/2014 10:38:45 AM (last edit: 11/28/2014 10:38:45 AM)
show user profile  Garp
> Not completely following you on the BoundZ >= BoundX thing

Say you have a box of XYZ dimensions 10x50x20. Your code checks that 20>=10 (BoundZ >= BoundX) and then happily proceeds building the cylinder along the Z axis. Is it what you want?




read 423 times
11/28/2014 11:08:43 AM (last edit: 11/28/2014 11:08:43 AM)
show user profile  Dave
Err, yes. I think. Well... I mean those are some strange dimensions for a cylinder. I just thought of a possibly neater way to do it... by saying "if two bounds are the same, the cylinder's "up" direction will be the third"

All I know is I've got high poly cylinders going off in every direction (still straight though) and it works fine. I have just put in your cylinder dir stuff, and taken out the Bound-3 variables. Everything is perfect except the cylinders on being drawn on the Y are going in the opposite direction (still Y, just the wrong Y) and the normals are flipped. Looking into it now!

Edit
Ah poop, it seems the objects I'm converting are sometimes not exact cylinders. So there goes my "if bound == other bound" idea.

Double Edit
Can I put in a threshold at all? To say "if bound is "close" to other bound"?

"I flew over Egypt once"

read 420 times
11/28/2014 11:28:42 AM (last edit: 11/28/2014 11:37:50 AM)
show user profile  Dave
So here's a visual representation of what I'm doing!

Top = before, bottom = after:

Which is fine, I'm 100% okay with that.... buut, there are also lots of little stumpy cylinders where the "cylinder direction" isn't the highest value (nor are the other two values always exactly equal). So.. naturally, my script just assumes the highest value is the direction I want and I end up with stuff like this:


"I flew over Egypt once"

read 406 times
11/28/2014 12:10:24 PM (last edit: 11/28/2014 12:10:24 PM)
show user profile  Garp
Oh I see now! I was wondering what all that feckin around with cylinders was about.

I guess you better forget about the largest extent giving the height axis and instead look for the two extents that are closest. No threshold necessary. That wouldn't work well if you have all 3 extents the same but I suppose you don't have too many of those.

You want a hand or rather figure it out by yourself?




read 402 times
11/28/2014 12:37:14 PM (last edit: 11/28/2014 12:37:14 PM)
show user profile  Dave
I will very likely need a hand, but I'll give it a crack.

"I flew over Egypt once"

read 394 times
11/28/2014 1:41:15 PM (last edit: 11/28/2014 1:41:15 PM)
show user profile  reeves1984
Nice way to go about remodelling that :)

--
Simon Reeves


www.simonreeves.com - VFX Artist & Blog
twitter


www.analogstudio.co.uk <-- I work here

read 391 times
11/28/2014 2:31:04 PM (last edit: 11/28/2014 2:31:04 PM)
show user profile  Dave
Aye I thought so!

It's got things like 500+ little bolts/screws too.... hence my initial need of just wanting to turn it all into boxes. It's amazing, I turned about 233k tri's into 7k.

It's been a pretty good day.

"I flew over Egypt once"

read 388 times
11/28/2014 3:31:27 PM (last edit: 11/28/2014 3:31:27 PM)
show user profile  Dave
I think I'm understanding the theory... maybe.

I've already got my variables which will equal my three values, so all I need to do is put those into an array... and then sort them. Then grab the first two (or last two, depending on how it sorts?) and those will always be the two closest values?

So then I'd have a variable which was the output of those two values.

Then I'd say if the outcome was that, do this. x3

yeah?

I mean, there might very well be a scenario where all 3 values are close and it ends up doing what I don't intend... but, this is the best my brain can do, and it's not even possible for me to do it in a practical sense just yet.

"I flew over Egypt once"

read 378 times
11/28/2014 9:10:34 PM (last edit: 11/28/2014 9:10:34 PM)
show user profile  Garp
The theory sounds good enough for practical purposes. More and you'd need to start doing mesh analysis :'/

Did you know that Point3 values (and others) can also be indexed? Intead of p.x, p.y and p.z, you can use p[1], p[2] and p[3]. Same thing. Sometimes it can be handy to loop through the dimensions instead of explicitely going through them one by one.




read 369 times
11/28/2014 11:31:52 PM (last edit: 11/28/2014 11:46:22 PM)
show user profile  Dave
I had a tinker for a few hours, mostly reading, testing and failing. The closest I've gotten so far is:


vals = #(BoundX, BoundY, BoundZ)
sort vals
vals.count


Now, this does what I want (I think).. in that it grabs the three values, and then sorts them. The first problem is I have no idea what to do with them after they've been sorted, and the second issue is after I've performed this action on a single object, it will always return the same result, regardless of what object I run the script on afterwards.

I've got a few pages open, that I keep reading over and over. I know the answers are there, I'm just not smart enough to realise it:

http://stackoverflow.com/questions/10412697/retrieving-2-closest-numbers-among-3
http://davewortley.wordpress.com/2013/07/12/lesson-12-qsort/
http://www.cgplusplus.com/online-reference/maxscript-reference/source/array_values.htm

Edit
Typos fixed. I need more coffee.

"I flew over Egypt once"

read 322 times
12/1/2014 3:51:26 PM (last edit: 12/1/2014 4:12:33 PM)
 
First page  Go to the previous page   [01]  [02]  Go to the next page  Last page
 
#Maxforums IRC
Open chat window


Support Maxforums.org