Jump to content
Developer Wiki and Function Reference Links ×

Numbering Objects in Order


SamIWas

Recommended Posts

Hi all,

I have been trying to create a script which will take a selection and insert a range of numbers into a record field based on the number of items in the selection. This is so I can more quickly number units on a lighting pipe from one end to the other.

I have gotten the script to work perfectly except for one problem. It always numbers the units in the order in which they were added to the drawing. I want the script to number them from left to right, right to left, bottom to top...whatever.

Here is a copy of the script:

code:

PROCEDURE RenumberLR;

VAR

h : HANDLE;

unitbase : INTEGER;

unitnum : DYNARRAY[] of CHAR;

BEGIN

unitbase:= 1;

h:= FSActLayer;

WHILE (h <> NIL) DO BEGIN

unitnum := Num2Str(0,unitbase);

SetRField(h,'LightInfo','Unit',unitnum);

h:= NextSObj(h);

unitbase:= unitbase+1;

END;

END;

Run(RenumberLR);
[/code]

Can anyone suggest a script line that may help select the units in a visual order rather than time order?

Thanks!

[ 12-11-2004, 03:03 PM: Message edited by: SamIWas ]

Link to comment

Isn't there an existing tool in Spotlight to do this?(I don't own a copy)

I think I can safely say it will require much more than a line or two of code to do this.

You need a sort routine that gets an objects position,compares that to the positions of the other selected objects and numbers accordingly.

You'll probably want a dialogue so you can set the start number and select which sort routine to use....left/right,up/down etc.

If you can get your hands on a copy of V-works 8, you can look at a PIO that does all this....it's about 500 lines of double spaced code and uses a couple include files to boot.

Charles.

Link to comment

PastTenseSam,

This may not be what you want, but if the stacking order of the lighting units on the layer is not important to you, it is easier to reorder them than to reorder the unit numbers.

If you can live with it, here is a quick and dirty Bubble Sort routine that orders the units from Left to Right before you number them. You can modify it for other directional sorting as your needs require.

code:

PROCEDURE RenumberLR;

VAR

h : HANDLE;

unitbase : INTEGER;

procedure SortLtoR;

{ Change the ordering of objects on the layer based on the object's horizontal position }

{ using a short, left to right, bubble sort - can take a while if the list is long. }

Var

swap :BOOLEAN;

X1, X2, Y :REAL;

Begin

swap := True;

while swap do begin { repeat until no more swaps occur }

swap := False;

h:= FSActLayer;

while (NextSObj(h)<>nil) do begin

hCenter(h, X1, Y);

hCenter(NextSObj(h), X2, Y);

if (X1>X2) then begin

hMoveForward(h, false); { swap object stacking order }

swap := True;

end; { if }

h:= NextSObj(h);

end; { while }

end; { while }

End; { SortLtoR }

BEGIN

SortLtoR; { order the units from L to R first, then number them }

unitbase:= 0;

h:= FSActLayer;

WHILE (h <> NIL) DO BEGIN

unitbase:= unitbase+1; { on loop exit, unitbase = number of units }

SetRField(h, 'LightInfo', 'Unit', Num2Str(0, unitbase));

h:= NextSObj(h);

END; { while }

END;

Run(RenumberLR);
[/code]

HTH,

Raymond (aka SamIAint)

[ 12-11-2004, 09:16 PM: Message edited by: MullinRJ ]

Link to comment

Raymond,

THANK YOU! That was exactly what was needed. The stacking order doesn't matter at all to me, as I don't think I ever have two lights on top of each other.

I didn't realize that it was ordering things based on their stacking level, rather than the time in which they were placed into the document (usually the same, but things get moved around).

This works perfectly now, and I can easily take the code from here and modify it for right to left, up to down, etc.

You have saved me hours per week!

Link to comment

If you don't want to change the stacking order you can use something like:

PROCEDURE numberLtoR;

VAR

Hobj,Hobject:HANDLE;

currentX,X,Y:REAL;

numobjects,num:INTEGER;

FUNCTION objCount:INTEGER;

Begin

objCount:=0;

Hobject:=FSActLayer;

WHILE Hobject<>NIL DO

Begin

objCount:=objCount+1;

Hobject:=NextSObj(Hobject);

End;

End;

FUNCTION FindPlace(H:HANDLE):BOOLEAN;

Begin

HCenter(H,X,Y);

IF X>currentX THEN num:= num+1;

End;

BEGIN

Hobj:=FSActLayer;

WHILE Hobj<>NIL DO

Begin

num:=0;

HCenter(Hobj,currentX,Y);

ForEachObjectInLayer(FindPlace,2,0,0);

num:= objCount-num;

SetRField(Hobj,'inf','name',Num2Str(0,num));

Hobj:=NextSObj(Hobj);

End;

END;

run(numberLtoR);

(you'd have to modify for your variables and record names)

Link to comment

quote:

The stacking order doesn't matter at all to me, as I don't think I ever have two lights on top of each other.

Sam,

That is kind of what I was thinking. Glad it worked for you.

Charles script looks like it would work if you ever needed to keep the stacking order intact, but I would put the call to "objCount" outside the while loop and reference it with a variable, since the count won't change during program's execution. It's an easier approach than I originally tried before I decided to shuffle the objects instead of the ID's.

Happy scripting,

Raymond

Link to comment

Hi Ray

Good point on the count.

When I first read his post I was thinking (possible as you did) about reading the x/y stuff into an array,sorting that,matching objects to the array and writing to record based on position in array....hence my warning-like post.

Later that day I saw a different approach and by the time I had a working example you already posted your solution which is cool.I always like it when you can solve a problem by coming up with a simpler strategy.

Thanks for posting

C.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...