Jump to content
Developer Wiki and Function Reference Links ×

Assigning Objects to Design Layer


Recommended Posts

Hello everybody,

 

i am having a little bit of trouble working myself into the script writing.

 

there a 2 things i want to achive and a cant figure out how to....

 

1st get Layoutviews to a Shortcut, calling by name would be fine to me else by sort number, maybe?

 

2nd move selected objects to a designlayer, also either by name or number(it is always layer#1)

this may sound wierd but i work in a theater where not so rarly the lightdesigner has the idea to again use lights he has used before.

so i move them to a layer where the last until the get back into show. (especially used for the insalled lighting in the house)

 

can anyone help me out?

 

Best Dom

 

Link to comment

I would love to help, but I don't understand what you are trying to do.

 

My best guesses right now are:

 

1. Create a keyboard shortcut that will allow you to go to a specific Sheet Layer (or Viewport)? But I don't understand what you mean by by name or sort number???

 

2. Move objects to a specific Design Layer makes sense. But I again don't understand the by name or number part.

 

This thread links to some manuals I wrote about making a script into a menu command and editing your workspace to add a keyboard shortcut.

 

 

Link to comment

There are a couple of different ways to do a shortcut for views.  Saved Views are the obvious way since they are easily accessed by double-clicking in the Saved Views palette.  If you absolutely need to access them by script, you would use VRestore and pass in the name of the Saved View.

 

Otherwise, if you need to just navigate to a specific layer, you would use the Layer procedure and pass in the name of the layer.  Keep in mind that for Sheet Layers, the layer name is actually the Sheet Number field, the Sheet Title isn't included.

 

In terms of assigning an object to a specific layer, the actual function you are looking for is SetParent, passing in a handle to the object and the handle of the layer (using GetLayerByName to get the handle from the name).

Link to comment

thanks for the reply

 

@ Pat

thx for the examples, i read thoes befor, just didnt get the idea to crate a saved View for the Sheet layer xD

, solved 😉 Thx a lot

btw, by name I ment that it is always the same Layer name that is used

by number i ment that it has always Layout #1

thought that may be easyer to use the listed number than the name

 

 

for moving object to a different layer,

i feel like am just to stupid to get it done... i read the SetParent sheet, i just cant get it to work... it does nothing after all...

 

can somebody give me a working example of the chaning the Layer script?

maybe I can the figure out what I am doing wrong xD

(does it matter that i want to move syboles, light symboles in that case?)

 

best Dom

 

Link to comment

@SoundDoingLight

 

I use these menu commands to move objects to different layers millions of times a day:

 

https://www.verysmallgroup.com/layeruplayerdown

 

It's just using SetParent()

 

As always @Jesse Cogswell has great advice.  If you always want to go to the same layer you just need to get the handle to the layer, the handles to the visibly selected objects (probably a ForEachObject function), and use SetParent.

 

 

Link to comment

Not sure which version of Vectorworks you are running, but attached is an example file in VW2025 format with a document script that will move all selected Lighting Device objects to layer Layer#1.

 

In case you are not able to open the file,  below is the document script in full.  It's pretty simple.

 

PROCEDURE MoveLightFixToLayer1;

CONST

	kTargetLayer = 'Layer#1';

VAR

	currentLayer:STRING;
	moveCounter:INTEGER;

PROCEDURE ExecuteMove(h:HANDLE);

{Moves given object to Layer given in kTargetLayer constant}

	BEGIN
		IF(SetParent(h,GetLayerByName(kTargetLayer))) THEN moveCounter:=moveCounter + 1;
	END;

BEGIN
	currentLayer:=GetLName(ActLayer);

	moveCounter:=0;
	ForEachObject(ExecuteMove,((SEL) & (R IN ['Lighting Device']) & (L = currentLayer)));
	
	AlrtDialog(Concat(moveCounter,' Lighting Fixtures moved to ',kTargetLayer));
END;

Run(MoveLightFixToLayer1);

 

The key here is to use a ForEachObject call to get handles for each selected Lighting Device object to use with the SetParent operation.

Move Fixtures Example.vwx

Link to comment

What do you really want the script to do? You need to be specific and really think through all the implications so we can get it right.

 

Yes it is possible to make a script that would move all lights on all design layers to a specific layer.  But do you really want to do that?  What happens if someone runs the script on an active file and does not notice for a while?

 

Would it be better to just have a script to select all the lights and then use the OIP to set the layer? Are you really doing this often enough that the extra step of changing the layer in the OIP is too difficult?  The Custom Selection tool should be able to write a script for you to select all the lights.

 

@Jesse Cogswell & @michaelk have given you good advice above on HOW to write the script. My points are more about SHOULD you write the script.

 

My $0.02

Link to comment

Hello

 

thanks for the response,

 

i forgot to mention.... unfurtunately i live in VWX23 :( (upgrade to 26 in Feb if IT lets me xD)

 

Pat i understand your worry,

my situation is that usually ther sits a light designer right next to me that is telling me wich lights stay on an wich do not play in the show.

I dont wont to delete them because many times a few days later he comes back and "recalls" some lights he want to use again.

 

for most working enviroments you may be right that there is no need for such a script but i have a lot of mouse moves to do if in 10 min you get told to move 200 lights away and 15 back...

so i want to be quick 😉

the 15 bach then dont need a script xD

 

also I am the only person doing Vectorworks right now so nobody else is about to use that script.

also it should only work for selected objects, so if somebody just runs it on a file with nothing selected nothing should happen...

 

simply moving items up a layer doest help in that case, there may be 20 layers in between,

 

unfortunately the script posted by jesse only works for the active Layer 😞

were are getting closer 😉

 

Best Dom

 

 

Edited by SoundDoingLight
Link to comment

Okay i was to dump to see that there is a Current layer query.... 😞

kicked that out...

it works perfectly!

thanks a Lot! makes my days with light designers way, way better 😉

 

would it be also pissble to get a query for channel?

so if Channel is 401-404 to layer 400 for example

 

i have seen there are a l lot of LDevice commands but non that jumps at me with channel information (MA user would say Fixture ID)

Link to comment

You have to be really careful when using ForEachObject calls on selected objects.  I typically draft with my Layer Options set to Show/Snap. so I can only select things on the active layer.  However, ForEachObject will still act on selected objects even if they're not on the active layer, so I usually add a check to make sure it's only working on selected objects on the active layer.  I've added a check to the script to pull the current Layer Options.  If it's Show/Snap/Modify, it executes without the layer criteria, but with VSEL instead of SEL to get only visible selected objects.

 

To query channel numbers, you will need to use GetRField to pull from the Plug-in Object's parameter record.  This will come in as a string, so you'll need to use Str2Num to convert it to a number.  We need to get the "hundreds" of the channel, so I've purposely left the number as an integer.  That way, we can divide it by 100 and it will shed its 10s and 1s place digits.  We then multiply that number by 100 to get back to the full hundreds place.  This hundreds place is added to a layer prefix (in this case, "Layer ") to dump the fixture in.  If the layer doesn't currently exist, the script will create it.

 

PROCEDURE MoveLightFixToLayer1;

CONST

	kLayerPrefix = 'Layer ';
	kLayer0 = '000';

VAR

	currentLayer:STRING;
	layerOption,moveCounter:INTEGER;

PROCEDURE ExecuteMove(h:HANDLE);

{Moves given object to Layer based on channel number}

	VAR
	
		chan,chanHundreds:INTEGER;
		targetLayer:STRING;

	BEGIN
		chan:=Str2Num(GetRField(h,'Lighting Device','Channel'));
		chanHundreds:=chan / 100;
		chanHundreds:=chanHundreds * 100;
		
		IF(chanHundreds = 0) THEN targetLayer:=Concat(kLayerPrefix,kLayer0)
		ELSE targetLayer:=Concat(kLayerPrefix,chanHundreds);
		
		IF(GetLayerByName(targetLayer) = NIL) THEN Layer(targetLayer);
		
		IF(SetParent(h,GetLayerByName(targetLayer))) THEN moveCounter:=moveCounter + 1;
	END;

BEGIN
	currentLayer:=GetLName(ActLayer);
	layerOption:=GetLayerOptions;

	moveCounter:=0;
	
	IF(layerOption = 5) THEN ForEachObject(ExecuteMove,((VSEL) & (R IN ['Lighting Device'])))
	ELSE ForEachObject(ExecuteMove,((SEL) & (R IN ['Lighting Device']) & (L = currentLayer)));
	
	AlrtDialog(Concat(moveCounter,' Lighting Fixtures moved.'));
	
	Layer(currentLayer);
END;

Run(MoveLightFixToLayer1);

 

I've also attached the test file in VW2023 format.  Pro-tip: Fill out your forum signature with which version of Vectorworks you are using and general information about your computer (primarily which operating system you are on).  It really helps others provide proper files and troubleshooting advice.  The process is simple but may not be where you expect it, @Pat Stanford has detailed instructions in his own signature to help you.

Move Fixtures Example v2023.vwx

Link to comment

And when moving objects between layers, you probably want to add a criteria so that the layer you are moving them to is excluded. Otherwise you could end up in an infinite loop when after moving the object it gets put back in the list of objects to move.

 

Maybe not likely in this use case, but important to note the possibility. I think most of us have been bitten by that at one time.

Link to comment

hey Forum,

 

first of all sorry for replying late, had to acual work xD

2. I need to get more specific in my way of questioning.

 

I just wanted to say Thanks for helping me out.

I managed to get the script working the way i want it to.

the Couter Massage is "deactivated" becaus it anoyes me to click it away xD

PROCEDURE MoveLightToStandardLayer;

VAR

	currentLayer:STRING;
	layerOption,moveCounter,c:INTEGER;
	targetLayer:STRING;

PROCEDURE ExecuteMove(h:HANDLE);

{Moves given object to Layer based on channel number}

	
	BEGIN
		c :=Str2Num(GetRField(h,'Lighting Device','Channel'));
			
		CASE c OF
				
		1..9: targetLayer:=Concat('403_OHZ light_VBZ');
		111..116,121..124,131..136,8057..8060: targetLayer:=Concat('402_OHZ light_portal br top');
		171..178,180..189: targetLayer:=Concat('402_OHZ light_portal br down');
		202,203,207,208,209,211,212,214,215,216,231,232,233,301,302,303,307,308,309,311,312,314,315,316,331,332,333: targetLayer:=Concat('402_OHZ light_portal tow');
		421..430,471..480 : targetLayer:=Concat('401_OHZ light_2.gal');
		417,418,467,468:targetLayer:=Concat('401_OHZ light_side boom');
		541..552,641..652: targetLayer:=Concat('501_PROD light_disccoverys');
		701,702,751,752:targetLayer:=Concat('403_OHZ light_orch seat balc');
		703,704,705,753,754,755:targetLayer:=Concat('403_OHZ light_FOH 1.balc');
		708..719,758..769,790:targetLayer:=Concat('403_OHZ light_FOH 2.balc');
		726,723: targetLayer:=Concat('403_OHZ light_proj cab');
		731..735:targetLayer:=Concat('403_OHZ light_center 2.balc');
		770..780:targetLayer:=Concat('403_OHZ light_medaillons');
		794,795,796,797:targetLayer:=Concat('403_OHZ light_cupola');
		1111..1116,1121..1126,1131..1136,1141..1145,1211..1216,1221..1226,1231..1236,1241..1245,1311..1316,1321..1326,1331..1336,1341..1345 :targetLayer:=Concat('401_OHZ light_OL_batten lights');
		5001..5014,6001..6014: targetLayer:=Concat('401_OHZ light_stage level');
		8511..8517,8611..8617: targetLayer:=Concat('501_OHZ PROD light_side boom');
		10..99: begin targetLayer:=Concat('500_OHZ light');AlrtDialog (Concat(c,' is Production, moved to 500_PROD light')); END;
		1500..4999: begin targetLayer:=Concat('500_OHZ light');AlrtDialog (Concat(c,' is Production, moved to 500_PROD light')); END;
		
		OTHERWISE BEGIN
		
		targetLayer:=Concat('000_doest play');
		AlrtDialog (Concat(c,' has no standard Layer, stays in 000_doest play'));
						
		END;
		
		End;
		
		IF(SetParent(h,GetLayerByName(targetLayer))) THEN moveCounter:=moveCounter + 1;
		
	END;
		
		
	
BEGIN
	currentLayer:=GetLName(ActLayer);
	layerOption:=GetLayerOptions;

	moveCounter:=0;
	
	IF(layerOption = 5) THEN ForEachObject(ExecuteMove,((VSEL) & (R IN ['Lighting Device']) ))
	ELSE ForEachObject(ExecuteMove,((SEL) & (R IN ['Lighting Device']) & (L = currentLayer) ));
	
	{AlrtDialog(Concat(moveCounter,' Lighting Fixtures moved.'));}
		
	Layer(currentLayer);
END;

Run(MoveLightToStandardLayer);

 

the topic with the infinate loop is not logic to me, becaus it does every object only once right?

 

any improvents recomendet?

 

btw used it yesterday... didnt save me 10 min... but a way more calm light designer next to me wich is woth way more than an hour of work :P

 

Link to comment

The quick "improvement" I see, would be to delete most of the CONCAT statements.  

 

If you only have a single string (all of your layer names then:

 

1..9: targetLayer:=Concat('403_OHZ light_VBZ');

is equal to

1..9: targetLayer:='403_OHZ light_VBZ';

 

You only need CONCAT (short for Concatenate, or to combine) when you want to add multiple strings together.

 

But there is nothing wrong with leaving the Concats you have. It may slow down the script by a fraction of a seconds, but it will run fine.

 

The Infinite Loop item was just for information. But it is something to think about when you start moving or renaming items.

 

I think I got bitten by that when I was renaming objects. The name I gave them moved them later in the list that the original, so they ended up getting processed multiple times as the list I was using was dynamic.

 

It does not appear to be an issue with your script.

 

But if you wrote a version that did not exclude the layer you are moving to from the criteria, it is possible that it would have moved the lights to the new layer and then moved them to the same layer again. 

 

Lots of little details you need to consider when programming.

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