# DomC

Member

542

1. ## PEMB (Pre-Engineered Metal Building) Bent

Hi I think this object is between 2-40 hours to create. So I post without taking the order. It depends on which level of Detail you really need (Material Thickness , drillings for screws etc.) I can give you or somebody else a start-assist and a possible workflow. A sketch, what pitch, height, span, base size exactly means were nice because it is a big part of the work to specificate exactly which values should be variable. It is about the work of 3 hours (but always the first 60% from something are done very fast. It would be enough if you do not need any screws and if the material thickness on all edges would be the same and if you need just the hull of the material not the single parts and how they exactly cutted in raw form (miter etc)). Once more I ask myself, how it is possible to create exact Elements by using the non-metric-unit-system (just a gloss a place whenever I have the chance :-) BENT_v1.vwx
2. ## Wrapper to Object Node Problem

Hi Marionette has his own function to deside (and with that if it should use a 3D Move, 3D Rotate or 2D Move, 2D Rotate etc.) if an object is planar or not. This concept has some limitations. If you edit the code to this, the rotate node will work inside the PIO. Double click the node and delete the first line, then you can edit the code. #planar = Marionette.Is2DObject(obj) cx = center[0] - offset[0] cy = center[1] - offset[1] cz = center[2] - offset[2] #if planar: vs.HRotate(obj, (cx, cy), r[2]) #else: # vs.Set3DRot(obj, r[0], r[1], r[2], cx, cy, cz) In this case, the Rotate-Node deside, that it wants to use the vs.Set3DRot() command to the symbol. which seems to work, if the symbols are on the layer. Inside the PIO it does not work. But this will not work, if the symbols are on screen plan. Inside the PIO the symbols are placed on a screen-plane like place (top plan view). I think it is related to the different plane- and container-concepts that makes it very frittered and hard for one node to handle.
3. ## SpacesfromList.vwx

Hi Have you tried update on SP2 or SP3? Even if the "Data Mapper" runs without any data and connection it should show an error message.
4. ## Scripting Massing Models

Hello Does it maybe work if you do something like this: try: vs.SetRField(h2,'Massing Model','2Ddisplay','Roof') #your code except: pass #or do someting like taggging the object as "too complexe" or do another function Alternatively you can put something heavy on your enter key, while script is running.
5. ## Standard Rooms

Version 1.0.0

This Script it made for users which have an Vectorworks Architecture but have not the core business to draw walls, slabs and roofs to make a presentation ambient for their designs. It helps to create room situations very fast and especially very easy. 1. Concept It pulls Symbols out of a Symbol folder which are Room-Presets. As Presets Rooms can exist, that have a rectangular shape and inner dimension of exact 2 meters. Slabs are supported also (No extrudes etc.) and roofs. Best Practice maybe is to keep existing presets and just change classes as example. If we are working with presets we can "save" a lot of parameters in the Object-Info-Palette which makes it faster and easier to use. 2. Workflow Copy Symbolfolder and PlugIn in your project and you can use it immediately. If you want to change details you can ungroup (cmd/ctrl. U) the objects into Walls and slabs. So you are able to insert Windows, Doors or changing other Details. 3. Known Limitations/Details - Rectangular Room presets only - Switch on/off ceiling with classes - Texturize by classes - Changing classes by editing preset Symbols and attach other classes/attributes - You can Mirror the Room to get left/right rooms
6. ## Create Symbol node

Hello Chris solved his situation with putting the top/plan component on screen-plane and use set parent to move it into the symbol. In the meantime I made an node for SetPlanar Ref. The includes Command (vs.Set2DComponentGroup) needs a group of screen-plane objects to work. So use the Set Planar Boolean and the group node for your geometry. For a hybrid symbol with 3D and top/plan the SetComponentGroup is not necessary. SetComponentGroup would need to set front, left, section views etc. Script Set2DComponentGroup.vwx
7. ## VR panorama brighter than rendered image

Hello Same Issue here. It seems as soon as we have light from a HDRI this light is intensified by exporting a Panorama. I think most of users just exports the panorama without choosing the same Render-Style as the use in Vectorworks. Then the Result is Standard-RenderWorks with maybe no HDRI light attached and looks not too bright.
8. ## Import Symbol from Workgroup Libraries

Just read the initial post. "Workgroup folder" OK, now it is getting interesting. It depends on platform you work and workgroup folder is stored in the system I think (plist or registry). But I would not use this it is digging deep and it may not work anymore with newer versions etc. maybe hard to get it to work again. Also I did not checked if this is still working. #Windows import getpass import shutil HSFPath = vs.GetFPathName() vs.AlrtDialog(HSFPath) #Application 1 #User App Data 12 target = 'Users/dominiquecorpataux/Desktop' from winreg import * aReg = ConnectRegistry(None,HKEY_CURRENT_USER) aKey = OpenKey(aReg, r"Software\Nemetschek\Vectorworks 24\General") WGF_Path = QueryValueEx(aKey, "Workgroup Folder 0") #vs.Message(WGF_Path[0]) target = WGF_Path[0] vs.AlrtDialog(str(target)) #on mac import plistlib #MacFile = 'Users/dominiquecorpataux/Library/Preferences/net.nemetschek.vectorworks.2019.plist' pl = {} with open(file, 'rb') as fp: pl = plistlib.load(fp) vs.AlrtDialog(str(pl.get("NNA Workgroup Folders"))) vs.AlrtDialog(pl["NNA Workgroup Folders"])
9. ## Import Symbol from Workgroup Libraries

It should work with something like this: (Not tested but should work) import os res_file = "Path/to/your/file.vwx" if os.path.isfile(res_file) == False: vs.AlrtDialog('Path error') else: listID, symDefNum = vs.BuildResourceListN( 16, res_file ) for index in range(1, symDefNum+1): vs.ImportResourceToCurrentFile(listID, index) To grab several res files in a folder and his sub-folders: import unicodedata import os def get_res_files(folder): file_list = [] for path, subdirs, files in os.walk(folder): path = unicodedata.normalize('NFC', path) ## Valid values for form are ‘NFC’, ‘NFKC’, ‘NFD’, and ‘NFKD’. for name in files: filename, file_extension = os.path.splitext(name) if file_extension == '.vwx': fullpath = os.path.join(path, name) fullpath_string = unicodedata.normalize('NFC', fullpath) file_list.append(fullpath_string) return file_list Then you could loop through several res files: res_file_list = get_res_files('Folder/to/Libraries') for res_file in res_file_list: listID, symDefNum = vs.BuildResourceListN( 16, res_file ) for index in range(1, symDefNum+1): vs.ImportResourceToCurrentFile(listID, index) If you have issues with the path, maybe try: from pathlib import Path home = str(Path.home()) filepath = home+'/google/yourpath/yourfile.vwx' #to be cross-platform always use something like this: filepath = os.path.join(folder,folder,folder,file)
10. ## Creating ChainDimension from Single Dimension

The Function I use CreateChainDimension: def create_chain_dim_vertical(intersection_points_sorted, x, offset, vp_scale): #standardly im text is left if there is no place between threshold_2_dimension, dimoff1, dimoff2, dimoff3 = create_globals(vp_scale , layer_scale , units) start = intersection_points_sorted[0] h1 = None; h_first = None prior_segment_length = 0 prior_shifted_leftright = False; prior_shifted_up = False for i in range(len(intersection_points_sorted)-1): # startPt is always last endPt end = intersection_points_sorted[i + 1] segment_length = abs(end - start) if segment_length > epsilon: vs.LinearDim((x,start), (x,end), offset, 4, 769, True, 0.1) if data['b_debug_dim_color']: vs.SetPenFore(vs.LNewObj(), (65000,0,65000)); color = (65000,0,65000) if i > 0: h2 = vs.LNewObj() if not vs.GetObjectVariableBoolean(h2,30): #Text hatte kein Platz if i < len(intersection_points_sorted)-2: #not last dimension start_next = intersection_points_sorted[i+1] #=endPt end_next = intersection_points_sorted[i+2] next_segment_length = abs(end_next - start_next) if prior_segment_length < threshold_2_dimension and next_segment_length > threshold_2_dimension: vs.SetObjectVariableBoolean(h2,29,False)#unlock Text position vs.SetObjectVariableReal(h2,44,-0.1)#text shift vs.SetObjectVariableBoolean(h2,29,True)#calculate dim text color = (65000,0,0); prior_shifted_up = False elif prior_segment_length < threshold_2_dimension and next_segment_length < threshold_2_dimension and prior_shifted_leftright == False: vs.SetObjectVariableBoolean(h2,29,False)#unlock Text position vs.SetObjectVariableBoolean(h2,30,True)#Text inside vs.SetObjectVariableReal(h2,44,-0)#text shift color = (0,30000,30000); prior_shifted_up = False elif prior_segment_length < threshold_2_dimension and next_segment_length < threshold_2_dimension and prior_shifted_leftright == True: vs.SetObjectVariableBoolean(h2,29,False)#unlock Text position vs.SetObjectVariableBoolean(h2,30,True)#Text inside if not prior_shifted_up: vs.SetObjectVariableReal(h2,43,offset_up); prior_shifted_up = True; color = (0,65000,0) vs.SetObjectVariableReal(h2,44,-0); color = (0,0,65000) else: vs.SetObjectVariableBoolean(h2,29,False)#unlock Text position vs.SetObjectVariableReal(h2,44,-0.1)#text shift vs.SetObjectVariableBoolean(h2,29,True)#calculate dim text prior_shifted_leftright = True else: prior_shifted_leftright = False #prior_segment_unshifted = vs.GetObjectVariableBoolean(h2,30) #debug if data['b_debug_dim_color']: vs.SetPenFore(h2, color) vs.ResetObject(h2); #vs.SetPenFore(h2, (65000,0,0)) vs.ResetObject(h1) h1 = vs.CreateChainDimension(h1, h2) else: #first dimension > move to left h1 = vs.LNewObj()#;vs.SetPenFore(h1, (65000,0,0)) if not vs.GetObjectVariableBoolean(h1,30): #Text hatte keinen Platz vs.SetObjectVariableBoolean(h1,29,False)#unlock Text position vs.SetObjectVariableReal(h1,44,0); if data['b_debug_dim_color']: vs.SetPenFore(h1, (30000,0,30000)) #vs.AlrtDialog(str(h1)) prior_segment_length = abs(end - start) start = end chain_dims.append(h1)
11. ## Creating ChainDimension from Single Dimension

Thanks for Feedback I will try with a DomMenuTextByName as a workaround, thanks The complete Script has 800 lines (it reaches the limit of maximum size of a script), take a look here 🙂 An incredible powerful Auto-Dimension Script The Second Script iterates through the length of dimensions. If I have the minimum of Objects (2) then length is 2 The loop starts with 0 and ends with 2-1 (1). If the loop would go till i == 1 i had an index of range with i+1. Different ways to do that with python.
12. ## Creating ChainDimension from Single Dimension

Hi there I want to join single dimensions in one chain dimension. So far it works but I have an undo issue. If I undo the script my single dimensions are deleted and I also get an undo alert in the log file. My simple test with two dimensions: h1 = vs.FSActLayer() h2 = vs.NextSObj(h1) hnew = vs.CreateChainDimension(h1, h2) My function to join n-Numbers of single dimensions dimensions = [] def getObj(h): dimensions.append(h) vs.ForEachObject(getObj, "(NOTINDLVP & NOTINREFDLVP & (SEL=TRUE))") h1 = dimensions[0] for i in range(len(dimensions)-1): h1 = vs.CreateChainDimension(h1, dimensions[i+1]) The Scripts are working on selected objects for that test. The Undo Alert I get: "ALERT: Invalid undo primitive detected: Imminent crash is possible. Object 0x7ff725723440 is being inserted after it has been modified or deleted.","type":"INFO"} Also really it is an undo issue because Unto after script deletes my dimensions. Have I to handle the undo events in a Vector Script?
13. ## Marionette OIP Popup from Worksheet

@corbinhand Have you already checked this out?
14. ## Worksheet based Popup, push Button

Version 1.0.0

Generally: Popups significantly raises usability of Marionette Scripts. Also for advanced marionette scripters often it is hard to search and enter the values. Situation Now: 1. The Popup values has to be written in an input node or the params class of the node, which do just execute if node is edited. 2. Popups are not dynamically unless the values are calculated by the script and then the Popup will popup every time the script is running. What does that Node improve: 1. The popup values can be directly pulled from a worksheet. 2. The provided node filters one popup with another popup, which is very efficient for fast filtering and combine choices Worksheet Popup.mp4
15. ## Marionette OIP Popup from Worksheet

Like I told, you need to run the network, which pulls the values from the table. then you have to deselect and reselect the node. And then the popup is there. but not on the wrapper or a Marionette PIO, because this Node has an input and nodes with an connected Input will not shown on the wrapper or a Marionette PlugIn. Thats why option #2 is the only proper solution. The posted example is option #1.
16. ## Record Popups

Version 1.0.1

Generally: In everyday life job is very often reading and writing record fields of user record formats and PlugIn objects. Situation Now: 1. Marionette users have to know the record name and need a lot of knowledge to get the universal name of PIOs 2. Marionette users needs to manually find and transfer the field names into string nodes and also have to know a workflow to find the universal field names of PlugIns. 3. copy/paste of the names or writing the values is stressful and often results in type errors. What does this Nodes improve: 1. Quick access to record formats, PIO records and field names 2. See the localized and universal names (if exists) of the fields, returns universal names to the script automatically 3. Can also be used in combination with "print debug" to show names for editing existing networks without using directly the node Record Popup.mp4
17. ## Name Popup

Version 1.0.1

About This File This Node is similar like the Name-Node. Instead of writing the Name in the Node Infos, you can select the Name from a Popup, wich maybe is a little bit more comfortable. Using the Name input is often used by myself for quick testing, debugging or Stand-alone Scripts. This node helps eliminating errors like writing the name on the wrong field or copy/paste the name on wrong place etc. A new innovation implemented, is a visual feedback of the node, which zooms the named object while choosing it in the popup. Which is a very interesting advance to improve user friendliness of Marionette nodes. Ideas for further improvements: 1. Checkbox if zoom or not (not sure, because to many checkboxes decreases usability) 2. A Pick option to pick an object and auto-naming and inputting with this picked object (Not implemented, because I have not got it to work, that a pick callback runs inside of a Marionette script) Name Popup.mp4
18. ## Remove choices from popup in Dialog

Hello Solved by searching the Forum. Seems we need backward indexing to delete the choices. Here the working popup Dialog. choices1 = ['choice1', 'choice2', 'choice3', 'choice4'] choices2 = ['choiceA', 'choiceB'] def CreateMyDialog(): vs.dialogid = vs.CreateLayout('Dialog Name', 0, 'OK', 'Cancel') dialogID = vs.dialogid vs.CreateStaticText(dialogID, 10, 'Popup', 60 ) vs.CreatePullDownMenu(dialogID, 11, 40) vs.CreateCheckBox(dialogID, 12, 'Change Popup') vs.SetFirstLayoutItem(dialogID, 10) vs.SetBelowItem(dialogID, 10, 11, 0, 1) vs.SetBelowItem(dialogID, 11, 12, 0, 1) return vs.RunLayoutDialogN(dialogID, Dialog_Handler, 0) def Dialog_Handler(item, data): dialogID = vs.dialogid if item == 12255: # enter Dialog 12255 -> 12256 exit dialog for i in range(len(choices1)): vs.AddChoice(dialogID, 11, choices1[i], i) if item == 12: #checkbox num_choices = vs.GetChoiceCount(dialogID, 11) for i in range(num_choices, -1, -1): vs.RemoveChoice(dialogID, 11, i) if data: #checkbox True for i in range(len(choices2)): vs.AddChoice(dialogID, 11, choices2[i], i) if not data: #checkbox False for i in range(len(choices1)): vs.AddChoice(dialogID, 11, choices1[i], i) result = CreateMyDialog()
19. ## Clearing Dialog pull down menu

Hi Thanks @Julian. seems we need backward indexing for deleting the choices.
20. ## Remove choices from popup in Dialog

edit: Found something in the Forum here. I will try to check this.
21. ## Remove choices from popup in Dialog

Hello Would be great if anybody could help me. At the end result I want to be able to exchange a popup's choices. What I am trying to do is, that I delete the items with vs.RemoveChoice() and build it new with a loop through my choices. I think I make something wrong by indexing with "AddChoice" or "RemoveChoice" just remove the string not shorten the Choice Numbers. My script: choices1 = ['choice1', 'choice2', 'choice3', 'choice4'] choices2 = ['choiceA', 'choiceB'] def CreateMyDialog(): vs.dialogid = vs.CreateLayout('Dialog Name', 0, 'OK', 'Cancel') dialogID = vs.dialogid vs.CreateStaticText(dialogID, 10, 'Popup', 60 ) vs.CreatePullDownMenu(dialogID, 11, 40) vs.CreateCheckBox(dialogID, 12, 'Change Popup') vs.SetFirstLayoutItem(dialogID, 10) vs.SetBelowItem(dialogID, 10, 11, 0, 1) vs.SetBelowItem(dialogID, 11, 12, 0, 1) return vs.RunLayoutDialogN(dialogID, Dialog_Handler, 0) def Dialog_Handler(item, data): dialogID = vs.dialogid if item == 12255: # enter Dialog 12255 -> 12256 exit dialog for i in range(len(choices1)): vs.AddChoice(dialogID, 11, choices1[i], i) if item == 12: #checkbox if data: #checkbox True num_choices = vs.GetChoiceCount(dialogID, 11) for i in range(num_choices): vs.RemoveChoice(dialogID, 11, i) for i in range(len(choices2)): vs.AddChoice(dialogID, 11, choices2[i], i) if not data: #checkbox False num_choices = vs.GetChoiceCount(dialogID, 11) for i in range(num_choices): vs.RemoveChoice(dialogID, 11, i) for i in range(len(choices1)): vs.AddChoice(dialogID, 11, choices1[i], i) result = CreateMyDialog()
22. ## Marionette OIP Popup from Worksheet

Like I told I do not work on that node, just a proof of concept and you had to edit the node code to make it usable. I think I want to provide a useful node maybe but not now. However, the popup delivers an index and this index corresponding to the lines in the popup and the lines in the worksheet. You could do this to return the value of popup instead of index. self.Params.output.value = j['data'][0]['popupChoices'][input]['text'] Or this, to return the line from the worksheet (which is the better option) self.Params.output.value = lines[input] input is the popup index.
23. ## Marionette OIP Popup from Worksheet

Hello The Custom Popup Widget from the Nodes, are generated by editing the Nodes. There are some special Popups which are handled by the Marionette core itself. As example the class popup. If you add classes the popup will contain that new class. You can generate the popup items with a script from a worksheet. No question. Lets say, you can say the popup the have those items from the worksheet by script. You have to run the script to deliver the items of the popup. If you click on a popup with items generated like this and you do not run the network your popup has no data because no script was executet. So what can be done without manipulationg the core too much: 1. Create a node with a popup, which takes items from the input. You have to run the network bevor the items are activated. (Example Attached) 2. Create a dialog push Button or a Dialog which runs when the script runs. 3. Dis Dialog has his own popup and can be generated with every functionality of script engine. 4. Having a seperate script (as example in the worksheet), which will push the worksheet changes to the node popups widgets. probably it could be possible to manipulate or generate the popup in the Marionette class but it is not something I grabbed before and I guess I would not provide public. So the best option in my opinion is #2, where we have a push button with the popup. The popup will always be up to date. Maybe an issue, if the push-button is nested too deep in wrappers and Object Nodes. So if you do something, always check if it works in your final product. But also this could be an issue with the other variants. Here the example, how to overwrite the node-popup from outside. Also this technique is provided a long time ago in the gallery. The Node is just a proof of concept, you cant use it without edit the node code for your own usage. I try to make an Example in the Gallery, which takes a worksheet input and have a push button for choosing the popup. Because this sounds for me very useful for many Marionette users and developpers. the interesting think is, that there will be two popup. The first popup will allow to filter the items of the second popup. I think this is not a big thing but as I can remember last Time i made a popup with changing items, i did not known how to eliminate the vestige of deleted popup items. Dynamic Popup.mp4 PopupfromWorksheet.vwx
24. ## SpacesfromList.vwx

Hello This Script ist Cross-Plattform and also works on my windows computer. However, the following could go wrong: 1. Did you picked the file? with the PickFile Node Button? 2. Maybe Browser or Antivirus etc. change the downloaded Text file. Check out Text encoding (setting of the import txt v110) latin_1 or cp 1252 should match for windows. Did you opened the textfile with another software like excel or wordpad etc.? Maybe this changed the txt file or the text encoding of the file. 3. Did you used the debug mode and/or the "print debug" to see, which wires have data or not 4. I am using Vectorworks 2022 SP 2.1 on Windows 10. It runs with the downloaded text file and with the Vectorworks File Version 1.0.4. I run with a German Designer Version. Also it works with Architecture or interiorcad Version. I guess not with Landmark or spotlight because there is no space-tool available in this versions. Additional: - The "Split List Absorb" limites the lines to 20 (To not have too look for the first run, if someone have 2500 Spaces in his Textfile) I you would provide your vwx File, I maybe have a chance to find the error in your network.
25. ## SpacesfromList.vwx

Must be the configuration of the column C. In the Example File, here is the area. And this must be returned on the port out1, which goes forward to the area of the space. Maybe you can check my movie I attached. Try to follow my stepts (picking your textfile, setup the Area-Column to out1)? I downloaded Version 1.0.4. and tested with the text file. Import Raumprogramm.mp4
×

• KBASE
• #### MARIONETTE

×
• Create New...