Jump to content
Developer Wiki and Function Reference Links ×

Random assign Z values to 3d symbols


Recommended Posts

It would be a pretty easy script to write.  Essentially select your 300 symbols, run the script, enter a high and low value, then just loop through the symbols assigning a random value between the two numbers to the Z height of the symbols.  Don't have time to write it at this moment, but might be able to tomorrow.

Link to comment

I think I might have figured out a way to do this.  Unfortunately, the Vectorscript Random function is super limited and doesn't have a way to select a random number from a range (though I suppose someone smarter than me can write up a function using the existing Random function).  But luckily for us, Python does have a method of doing just that.  So with a little help from our friend PythonExecute to use python code in a Vectorscript.

 

The script below will open a dialog box allowing the user to specify the minimum and maximum value in document units (so if you are in feet and inches, type in inches.  Don't do something like 2'6", because the Python code won't really know what to do with that), then generates a new height using the Python random.uniform method and then applies that new height to a given object using a ForEachObject call.  The code as written will execute on all selected objects on the currently active layer.

 

The code has been very lightly tested in metric and freedom units and should work on symbols as well as Plug-in Objects.

 

PROCEDURE RandomizeHeights;

{*	Randomizes heights of all selected objects on the active layer
	Developed by: Jesse Cogswell
	Date: 7/27/2023
	Revisions:
*}

VAR

	dialog,layoutDialog:LONGINT;
	minValue,maxValue:REAL;

FUNCTION RandRange(rMin,rMax:REAL) : REAL;

{Uses Python Uniform Random method to generate a random number between given range}

	VAR
	
		output:REAL;

	BEGIN
		PythonBeginContext;
			PythonExecute('import random');
			PythonExecute('import vs');
			PythonExecute('min = vs.GetVSVar("minValue")');
			PythonExecute('max = vs.GetVSVar("maxValue")');
			PythonExecute('output = random.uniform(min,max)');
			PythonExecute('vs.SetVSVar("output",output)');
		PythonEndContext;
		
		RandRange:=output;
	END;
	
PROCEDURE RandoHeight(h:HANDLE);

{Randomizes height of given object}

	VAR
	
		newHeight:REAL;
		symbolLoc:POINT3D;

	BEGIN
		GetSymLoc3D(h,symbolLoc.x,symbolLoc.y,symbolLoc.z);
		
		newHeight:=RandRange(minValue,maxValue);
		
		Move3DObj(h,0,0,0 - symbolLoc.z);
		Move3DObj(h,0,0,newHeight);
		
		ResetObject(h);
	END;

FUNCTION DrawDialog(sDiaName:STRING) : LONGINT;

{Creates dialog box and returns dialog ID}

	CONST
	
		kStaticLength = 14;
		kEditLength = 10;

	VAR
	
		dia:LONGINT;
	
	BEGIN
		dia:=CreateLayout(sDiaName,FALSE,'OK','Cancel');
		
		CreateStaticText(dia,11,'Min. Height:',kStaticLength);
		CreateStaticText(dia,12,'Max Height:',kStaticLength);
		
		CreateEditReal(dia,21,1,0,kEditLength);
		CreateEditReal(dia,22,1,0,kEditLength);
		
		SetFirstLayoutItem(dia,11);
		SetRightItem(dia,11,21,0,0);
		SetBelowItem(dia,11,12,0,0);
		SetRightItem(dia,12,22,0,0);
		
		DrawDialog:=dia;
	END;

PROCEDURE DialogHandler(VAR item,data:LONGINT);

{Handles dialog box}

	VAR
	
		BSB:BOOLEAN;
		currentLayer:STRING;

	BEGIN
		CASE item OF
			SetupDialogC:
				BEGIN
				END;
			1: {OK}
				BEGIN
					currentLayer:=GetLName(ActLayer);
					
					BSB:=GetEditReal(dialog,21,3,minValue);
					BSB:=GetEditReal(dialog,22,3,maxValue);
					
					ForEachObject(RandoHeight,((SEL) & (L=currentLayer)));
				END;
			2: {Cancel}
				BEGIN
				END;
		END;
	END;

BEGIN
	dialog:=DrawDialog('Enter Range');
	layoutDialog:=RunLayoutDialog(dialog,DialogHandler);
END;

Run(RandomizeHeights);
Link to comment

I had a thought about looking into the Marionette Random node to see how they did it and have revised the code to work without the Python bits.  The advantage to this code is that you can now totally input a range in whatever set of units you want (like 6'3" for example).

 

PROCEDURE RandomizeHeights;

{*	Randomizes heights of all selected objects on the active layer
	Developed by: Jesse Cogswell
	Date: 7/27/2023
	Revisions:	7/27/2023	Removed Python code
*}

VAR

	dialog,layoutDialog:LONGINT;
	minValue,maxValue:REAL;

PROCEDURE RandoHeight(h:HANDLE);

{Randomizes height of given object}

	VAR
	
		newHeight:REAL;
		symbolLoc:POINT3D;

	BEGIN
		GetSymLoc3D(h,symbolLoc.x,symbolLoc.y,symbolLoc.z);
		
		newHeight:=(Random * (maxValue - minValue)) + minValue;
		
		Move3DObj(h,0,0,0 - symbolLoc.z);
		Move3DObj(h,0,0,newHeight);
		
		ResetObject(h);
	END;

FUNCTION DrawDialog(sDiaName:STRING) : LONGINT;

{Creates dialog box and returns dialog ID}

	CONST
	
		kStaticLength = 14;
		kEditLength = 10;

	VAR
	
		dia:LONGINT;
	
	BEGIN
		dia:=CreateLayout(sDiaName,FALSE,'OK','Cancel');
		
		CreateStaticText(dia,11,'Min. Height:',kStaticLength);
		CreateStaticText(dia,12,'Max Height:',kStaticLength);
		
		CreateEditReal(dia,21,1,3,kEditLength);
		CreateEditReal(dia,22,1,3,kEditLength);
		
		SetFirstLayoutItem(dia,11);
		SetRightItem(dia,11,21,0,0);
		SetBelowItem(dia,11,12,0,0);
		SetRightItem(dia,12,22,0,0);
		
		DrawDialog:=dia;
	END;

PROCEDURE DialogHandler(VAR item,data:LONGINT);

{Handles dialog box}

	VAR
	
		BSB:BOOLEAN;
		currentLayer:STRING;

	BEGIN
		CASE item OF
			SetupDialogC:
				BEGIN
				END;
			1: {OK}
				BEGIN
					currentLayer:=GetLName(ActLayer);
					
					BSB:=GetEditReal(dialog,21,3,minValue);
					BSB:=GetEditReal(dialog,22,3,maxValue);
					
					ForEachObject(RandoHeight,((SEL) & (L=currentLayer)));
				END;
			2: {Cancel}
				BEGIN
				END;
		END;
	END;

BEGIN
	dialog:=DrawDialog('Enter Range');
	layoutDialog:=RunLayoutDialog(dialog,DialogHandler);
END;

Run(RandomizeHeights);

 

  • Like 1
Link to comment
11 hours ago, Jesse Cogswell said:

I think I might have figured out a way to do this.  Unfortunately, the Vectorscript Random function is super limited and doesn't have a way to select a random number from a range (though I suppose someone smarter than me can write up a function using the existing Random function). 

 

What I've done in this case is figure out the range, multiply that by the random number, and add it to the low number.

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...