Jump to content

Select a random assortment of objects?


Recommended Posts

Say for example I have an audience layout that consists of 300 chair symbols (laid out manually, not with the seating layout tool). Inside the 3D component of the chair symbol I have a 3D figure sitting on the chair, since I'll be doing renderings in this document.

 

It looks weird to have an army of 300 identical people in an audience, so I'd like to mix it up between three different chair symbols, each having the same chair but a different 3D figure. All I need to do is utilize the "Replace Symbol" function, but my current workflow involves first having to manually select 100 of the chairs via individual clicking. Then after Replacing Symbol I have to select another hundred. This is very slow.

 

Is there any way, perhaps with a script, to select a third or a half of the objects on the screen randomly? @Pat Stanford

 

 

Screen_Shot_2018-04-05_at_10_41.44_AM.thumb.png.3ceb265380e4f3786e99d544b5ee5a67.png

Rough idea of result

Link to comment

Why do you always ask the interesting questions when I am swamped?  ;-)

 

The short answer is yes. I will need a few days to actually make time to write it.

 

Select a set of symbols. Select "empty" symbol. Enter percentage to change. If # of empty is less than percentage then change all empty to a different symbol. If # empty is greater than percentage than step through and change (on a random basis) from empty  to a different symbol.

 

Sound like what you need?

Link to comment
15 minutes ago, Pat Stanford said:

Why do you always ask the interesting questions when I am swamped?  ;-)

 

Just to drive you a little bit more crazy ;)

 

In all honesty, thank you a ton for even being willing to take on these little challenges! No rush on this one; it's a task I do at least once or twice a week, so it will always be useful. I wish I knew the slightest but of scripting otherwise I'd try myself. It's on the list of things to learn!

 

17 minutes ago, Pat Stanford said:

Select a set of symbols. Select "empty" symbol. Enter percentage to change. If # of empty is less than percentage then change all empty to a different symbol. If # empty is greater than percentage than step through and change (on a random basis) from empty  to a different symbol.

 

Sound like what you need?

 

I'm not sure what's meant by "empty" symbol, but it sounds like that's along the right track? A bit over my head :D

 

I've attached a file with a chunk of seating on the left that's my "starting point" and the same chunk on the right that would be the hypothetical result.

 

5ac674b0572d9_ScreenShot2018-04-05at12_10_12PM.thumb.png.b6b97a496c5b460e3487d1f1e1f2e9e9.png

 

Audiences.vwx

 

Link to comment

BTW- the script wouldn't necessarily have to do any of the actual replacing of symbols. If it just selects the random assortment, I'd still manually do the Replace Symbol command which is fine.

 

Actually, that could make the script useful in other scenarios as well, such as giving different colors or textures to a random selection of objects. 

 

Perfection, symmetry, and identicalness are all so easy to achieve in CAD programs. Variation, imperfection, and randomness are a bit more difficult, but can help add realism to renderings. Anything to help automate that is very useful. For example, I use the "Rotate Each Object Randomly" script you wrote all the time :)

  • Like 1
Link to comment
21 hours ago, Andy Broomell said:

Perfection, symmetry, and identicalness are all so easy to achieve in CAD programs. Variation, imperfection, and randomness are a bit more difficult, but can help add realism to renderings

Tell me about it. I’ve just spent the afternoon modelling peeling wallpaper!

  • Like 2
Link to comment

OK a couple more questions (for everyone) before I start on this:

 

Scenario 1:  You start with 100 symbols, all the same. You select all the symbols and run the script telling it 33.3%  Do you want to have 33 seats selected at the end of the script or 67?

 

Scenario 2: You started with 100 symbols all the same. You ran the script and got a selection of 33 which you then changed to symbol 2. You now select all 100 symbols again. When you run the script what do you want it to do?  Randomly select from all 100? Ignore the ones that have already been changed and give a selection of 33 (1/2) of the 67 that are the original symbol?   If you randomly select from all 100, you will likely end up with a bias toward the original symbol and a smaller number of Symbol 2 as some of the Symbol 2 instances will be changed to Symbol 3.

 

Tell me more about how you think you would actually use this so I can make it as useful as possible the first time around. I don't want this to end up an ongoing project with a new "if it only did THIS too" every day.

 

Deselecting to leave a random percentage of a selection is easy. Having to know what you already did to ensure equal random percentages is harder, but still doable. But it will require more input from the user to get the right answer.

Link to comment

You ask all the good questions! I think avoiding the bias towards one symbol, as you describe, should be avoided if possible. And I hadn't even thought about selecting vs deselecting.

 

4 hours ago, Pat Stanford said:

Deselecting to leave a random percentage of a selection is easy. Having to know what you already did to ensure equal random percentages is harder, but still doable. But it will require more input from the user to get the right answer.

 

If pop-ups are possible, I think input from the user might be the best approach, and would allow for the greatest flexibility.

 

Here's one way I can envision it via deselecting:

  • Select 100 symbols, all Symbol A.
  • Run script.
  • A pop-up asks what percentage to deselect.
  • Type in 33%.
  • I'm left with 66 symbols which I change to Symbol B.
  • Run script again, still with those 66 symbols selected.
  • Type in 50%.
  • I'm left with 33 symbols which I change to Symbol C.

This allows you to get roughly even numbers of each symbol (doesn't need to be exactly equal of course).

 

Another variation via selecting:

  • Have 100 instances of Symbol A but none are selected.
  • Run script.
  • A pop-up asks what percentage to select.
  • Type in 33%.
  • 33 symbols are selected which I change to Symbol B.
  • Edit<Invert Selection to switch selection to the remaining 67.
  • Group those 67 then enter the group. Make sure nothing is selected.
  • Run script again.
  • Type in 50%.
  • Change the 34 that become selected to Symbol C.
  • Exit group and ungroup.

I'm not sure which approach is more advantageous, aside from the first one being simpler since it doesn't require grouping.

I'm sure a wiser mind than mine can think of an even better method :)

Link to comment

What do you (or anyone) think of an idea of the script running an creating Groups the first time through. Then you can have the multiple selections stable for whatever you want to do next.

 

Select 100 instances.

Set the script to divide into 3 (mostly) equal random groups.

Script runs and gives three groups each with (approximately) 33 symbols.

 

This would be much easier to do, especially when you are get into higher numbers of divisions (say 10).

  • Like 1
Link to comment
23 minutes ago, Pat Stanford said:

What do you (or anyone) think of an idea of the script running an creating Groups the first time through. Then you can have the multiple selections stable for whatever you want to do next.

 

Select 100 instances.

Set the script to divide into 3 (mostly) equal random groups.

Script runs and gives three groups each with (approximately) 33 symbols.

 

This would be much easier to do, especially when you are get into higher numbers of divisions (say 10).

 

That sounds perfect. I wasn't lying when I said "I'm sure a wiser mind than mine can think of an even better method." :D

Link to comment
9 hours ago, Andrew Davies said:

having this many 3D figures in your drawing - can I ask if the file is nice and responsive still?

 

The figures are low-poly (about 1500 each), so it's not too bad. OpenGL works totally fine. Wireframe is actually a bit slower, but I tend to turn off the figures' class as I'm working on other geometry. The figures class is only visible in the render viewports and in any OpenGL+Perspective saved views, which I use to fly around my design layer with the SpaceMouse.

Link to comment
  • 3 weeks later...

OK, I am ready for some beta testing.

 

Download the attached file. Save it into your User Folder/Plug-Ins folder. On my Mac the path is:

 

Pat/Libraries/Application Support/Vectorworks/2018/Plug-Ins.

 

I can never remember if you have to restart VW after adding a plug-in.

 

Edit your workspace and add the Random Group command to whatever menu you desire. It should show up in the Miscellaneous column on the left pane.

 

Select multiple objects on the active layer (the script only handles objects on the active layer) and run the script and you should get a number of groups. Each group should have close to 1/(Number of groups) objects randomly assigned to each group.

 

If you hold down the OPTION (ALT) key while choosing Random Groups from the menu, you should get a dialog box that will let you set the number of groups to divide the objects into. This will also be set as the new default so you don't have to do this every time.

 

The object and script are unlocked and licenses under the Lesser General Public License for free use. You can see the script by going to Tools:Plug-ins:Plug-In Manager and looking under the Custom Plug-ins or Third Party Plug-ins categories, selecting Random Group and clicking the Edit Script button.

 

This is very lightly tested, with no warranty expressed or implied. See the source code for all the disclaimers.

 

There is not a lot of error checking. If you get error messages, please screen shot them for me so I can see what I can do to eliminate the errors.

 

Let me know what you think.

 

Random Group.vsm

  • Like 2
Link to comment

Thanks again a billion for working on this, Pat! (btw, I was hoping to attend the user group yesterday, but ended up being stuck in Hollywood too late in the afternoon 😔).

 

Playing around with the script now... It seems to work excellently with "3" groups. However, when I try it with more than that, let's say "7", I end up with 7 groups, but only 3 of them contain objects. The other 4 apparently exist, since the OIP says '7 Groups' when I Select All, but I can't see or individually select the other 4. And the three groups don't contain equal numbers of objects. (When I run it with "3" the distribution is great.)

 

As I play around more, there seems to always be 3 actual groups in the end, and one group tends to contain quite a few more objects than the rest.

 

589173952_ScreenShot2018-04-29at9_28_02PM.thumb.png.baea2c80f28e6fcbe84184fc9a7bb31d.png

 

 

Coincidentally I tend to just use 3 different figures in my audiences, so this script will be immediately useful. 😃

Let me know if there's further testing I can do. Thanks again!!

Link to comment

@Andy BroomellHi, this networks creates seating layouts based on a polygon and places seating within at desired spacing and with a little assistance from Marissa we have placed random symbols in the seats. Symbols 1000 to 1004, if you choose a number lower or higher in the network you will get vacant seats.

Will look to make it a little more user friendly if needed. 

Seating_Test_On_Poly_001_v2018_MFarrell.vwx

Capture.PNG

Edited by Alan Woodwell
Link to comment

Hi so added the people models and colour to show variants. Right click on the bottom one and change control geometry this will change the seating perimeter.

Play with the variables to get a low seating audience.

The top ones are just there to test out seating options. You can change the seat symbol type.

Play with the seating grid also.

Maybe just another way to do the seating.

Seating_Test_On_Poly_002_v2018_MFarrell.vwx

Capture.PNG

Link to comment
10 hours ago, Alan Woodwell said:

Hi so added the people models and colour to show variants. Right click on the bottom one and change control geometry this will change the seating perimeter.

Play with the variables to get a low seating audience.

The top ones are just there to test out seating options. You can change the seat symbol type.

Play with the seating grid also.

Maybe just another way to do the seating.

Seating_Test_On_Poly_002_v2018_MFarrell.vwx

 

Thanks Alan - I'll have to take a closer look at this, but it looks quite promising for when seating (or whatever) can be defined by a polygonal boundary. This is maybe 20% of the time though, as the seating layouts in many of our files are bespoke to a set or to a platform layout such that they have to be placed manually. In those cases I'll continue to use Pat's script, but it's great to have both of these approaches in my toolset. Thanks!

Link to comment

Maybe it’s my computer it’s a big level gaming machine with good graphics card. Will look at it to simplify it. I can place them on seating plats of adjustable heights and widths by that is slow even on mine. Will play more.

Link to comment
On 5/2/2018 at 4:12 PM, Andy Broomell said:

@Pat Stanford - it seems as though running the command with all of your objects already inside a group causes Vectorworks to stall indefinitely. Is there any way around this, sans ungrouping beforehand?

It could be fixed, but as written, it starts with the first selected object on the active layer. If you are inside a group, it is quite possible that the first selected object is outside the group.

 

If this is important I might be convinced to take a look. Or maybe I will just tell you it is WAD (Working as Designed) which was to have the objects on the active layer.

 

That it the problem with writing scripts is that the specifications always seem to change after you get it working. 😉

Link to comment
  • 5 months later...

 

@Pat Stanford Thank you for this awesome script, super helpful!

 

I tried using this in VW2017, but it does not show up in the Plugin Manager or the Workspace Editor (so for anyone who wants to use this, looks like 2018 is minimum version).

 

When I tried using this in VW2019 on Windows, VW would stall and never recover. I saw in your description...

 

On 4/29/2018 at 4:12 PM, Pat Stanford said:

If you hold down the OPTION (ALT) key while choosing Random Groups from the menu, you should get a dialog box that will let you set the number of groups to divide the objects into.

 

Windows immediately closes any open menus when pressing ALT, and won't let me open a menu while it's held. Thinking that may be the problem, I tried commenting out line 51 in your script...

If Not AUTOKEY(L1) AND OPTION then

and now the Plugin is working for me! The only change is now you get a dialog every time the plugin is run, but personally I prefer this (as I'll probably forget about the hotkey if I haven't used this tool in months).

 

I've attached the modified version for any Windows users that run into the same issue. Thanks again for the great script Pat!

Random Group.vsm

 

Edited by LJ TMS
Link to comment

Here is the script from my last version. You can use this to create a PIO in an earlier version.

 

Create a new PIO of type Command.  It needs a single parameter named NumGroups of Type Integer and my default value of 3.  Copy and Paste the script below into the Script of the command. and then add the command to your workspace.

Procedure RandomGroups;

{April 29, 2018}
{© 2018 Patrick Stanford pat@coviana.com}
{Licensed under the GNU Lesser General Public License}
{No warranty expessed or implied. Use at your own risk.}

{Backup your data prior to use. Do not use on your only copy of a file.}
{Test thoroughly to ensure suitability to your purpose.}
{Do not sit in the passenger seat while driving your Tesla while}
{Running this script. May cause drowsiness. Do not operate heavy equipment}
{or drive a vehical or bicycle while using this script. Use of this script}
{with alcohol, prescription, or other drugs may cause unpredictable}
{results and dangerous side effects. If you develop a rash of purple spots}
{with cartreuse centers develops, immediately discontinue use and seek}
{medical attention.}

{Plugin Menu Item to assign selected objects on the active layer randomly to different groups}
{The number of groups can be changed by holding hte OPTION key when the menu item is selected.}
{The original intent was to provide a way to take a selection of symbols and provide}
{a way to change a random selection of those objects to other symbols. This can be accomplished}
{by entering each group produced and replace the contained objects. When the groups are ungrouped}
{you can have a mixture of different symbols in the array. May be useful for things like}
{plants, trees, people in theater seats}


Type	RandomStruct = Structure
			Hand		:Handle;
			Rand		:Real;
			GroupNum	:Integer;
		End;

Var		A1			:Array[1..3822] of Handle;
		GroupArray	:Array[1..11] of Handle;
		ObjArray	:DynArray of RandomStruct;
		NumObjects	:Integer;
		NumGroups	:Integer;
		N1, N2, N3	:Integer;
		H1			:Handle;
		R1,R2		:Real;
		B1			:Boolean;
		ObjName		:String;
		RecHand		:Handle;
		L1			:LongInt;


Begin
	NumGroups:=pNumGroups;  {Set parameter for number of groups to a variable so it can be changed during run}

	{If Option key held down at menu selection then ask for number of groups}	
	If Not AUTOKEY(L1) AND OPTION then 
		Begin
			N3:=IntDialog('Enter Number of Groups (Max. 10)',Num2Str(0,NumGroups));
			NumGroups:=Min(N3,10);
		End;
	
	{If the number of groups has changed, save that back to the parameter for the next run}
	If NumGroups <> pNumGroups then
		Begin
			B1:=GetPlugInInfo(ObjName, RecHand);
			SetRField(GetObject(ObjName), GetName(RecHand), 'NumGroups', Num2Str(0, NumGroups));
		End;
		
		
	H1:=FSActLayer;  {Get a Handle to the first selected object on the active layer}
	NumObjects := NumSObj(ActLayer); {Get the total number of selected objects on the active layer}
	Allocate ObjArray[1..NumObjects]; {Set the array size to handle the number of objects}
	R1:= 1/NumGroups; {Caclulate the percentage of objects to be in each group}
	
	{Store a handle to each selected object, a random number, and a group based on the random number into the object array}
	For N1:=1 to NumObjects do
		Begin
			ObjArray[N1].Hand:=H1;
			ObjArray[N1].Rand:=Random;
			ObjArray[N1].GroupNum:=(1+Trunc(ObjArray[N1].Rand/R1));
			If ObjArray[N1].GroupNum > NumGroups then ObjArray[N1].GroupNum:=NumGroups;{Special case of random = 1}
			H1:=NextSObj(H1); {Move to next selected object}
		End;
		
	{Create groups and store the handle to each group in the group array}
	For N2:=1 to NumGroups do
		Begin
			BeginGroup;
				Locus(0,0); {Since a group can't be empty put a locus as a placeholder. Delete later}
			EndGroup;
			GroupArray[N2]:=LNewObj;
		End;
		
	{Iterate through groups	to add objects to proper group}
	For N2:= 1 to NumGroups do
		Begin
			{If an object's group number matches the group array index, add that object into the group}
			For N1:=1 to NumObjects do
				Begin
					{SetParent is used to set the parent of the object as the group with the proper group index}
					If ObjArray[N1].GroupNum = N2 then B1:=SetParent(ObjArray[N1].Hand,GroupArray[N2]);
				End;
		End;
		
	{Iterate trhough groups to remove placeholder loci}
	For N2:= 1 to NumGroups do
		Begin
			If GetType(FInGroup(GroupArray[N2]))=17 then
					Begin
						DelObject(FinGroup(GroupArray[N2]));
					End;
			ResetBBox(GroupArray[N2]); {Reset the bounding box that was set to only the loci to put handles correctly for all contained objects}
		End;

	RedrawAll; {Force a redraw of the screen to properly display the new groups}
End;

Run(RandomGroups);
	
			

Per @LJ TMS above, the Option Key trick (probably ALT on Windows) might not work on something other than a Mac, but that is all I have to test on. Thanks for the fix.

  • Like 2
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...