Jump to content

Letti R

Member
  • Posts

    75
  • Joined

Reputation

56 Excellent

4 Followers

Personal Information

  • Location
    Germany

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Hello, a workaround i really like is to write the Python code for the object directly into one (or more) Marionette nodes. Because than you can easily add control options like sliders and buttons to the OIP of the Marionette node and you can easily convert the self written node into an object (like you did with Marionette networks), while having more control over the script in comparison to creating a Marionette Network. However this workflow might have some downsides that i am not aware of. Regards, Letti
  2. Hello, I found this "weird" behaviour of the "Objs by Crit" node: If i create the criteria via the "Objs by Crit" node to search for all objects where the name is equal to an empty string, i get the hint in the criteria configuration menu, that no such objects were found (as expected). However if i run the node i get all objects that do not have names. By the way, the "Name" node does not return any obejcts when given an empty string. Regards, Letti
  3. Hello, maybe the data is stored in another record that is also attached to the object. If i want an overview of all the records (as far as i know) that are attached to an object i use the function below (im not sure if this function works with "ForEachObject", but i think you are going to modify this code anyways): def get_all_record_fields(object_handle) -> list: number_of_records_attached_to_object = vs.NumRecords(object_handle) all_record_fields = [] for i in range(number_of_records_attached_to_object): temp_record_handle = vs.GetRecord(object_handle, i + 1) temp_record_name = vs.GetName(temp_record_handle) temp_number_of_fields_in_record = vs.NumFields(temp_record_handle) for j in range(temp_number_of_fields_in_record): temp_field_name = vs.GetFldName(temp_record_handle, j + 1) temp_field_accuracy = vs.GetFldFlag(temp_record_handle, j + 1) temp_field_type = vs.GetFldType(temp_record_handle, j + 1) temp_is_field_empty, temp_is_data_linked = vs.GetRFieldOpt(object_handle, temp_record_name, temp_field_name) temp_field_value = vs.GetRField(object_handle, temp_record_name, temp_field_name) temp_record_field_dict = { "object_handle" : object_handle, "record_name" : temp_record_name, "record_handle" : temp_record_handle, "field_name" : temp_field_name, "field_accuracy" : temp_field_accuracy, "field_type" : temp_field_type, "is_field_empty" : temp_is_field_empty, "is_data_linked" : temp_is_data_linked, "field_value" : temp_field_value } all_record_fields.append(temp_record_field_dict) return(all_record_fields) Regards, Letti
  4. Hello, Thank you for confirming and reporting the bug @MullinRJ. Unfortunately i am dealing with nested folder structures of variable sizes and depths, so i think i am going to just wait for the fix. Just out of curiosity, what ist the normal way of accessing the first "folder" (it is not of type folder, which ist 92 i guess) of the ressource manager? I just cant figure out how it is supposed to be done. Regards, Letti
  5. Hello, i want to put one ressource folder into another ressource folder of the same ressource type. In VW 2023 i just can use vs.SetParent(folder_1, folder_2) In VW 2024 however VW crashes if i do the same thing. Putting objects into ressource folders works fine in VW 2024, it seems like its just folders that crash VW. Is this a known issue, or am i missing something. I am aware that there is most likely a workarround to this by moving all the contents of the folders to a temporary folder and than creating the folders with nested vs.BeginFolderN and than putting the contents back into the folders, since there is no problem with that, but i would realy like to avoid that. Regards, Letti
  6. Hello, there is a type mismatch at the inputs "sRecName" and "sFildName". There the node "Get Record Field" expects to get data of type "string" (aka. text) but what you are giving with the "Name" nodes are objects (data of type handle) that are named "zahl" and "z-wert". These objects dont exist, so there is nothing put into the "Get Record Field" node at these two inputs. I guess what you wanted to do is to use the "String" node instead of the "Name" nodes. By the way, the expected data types of the input or ourput ports of a node is normaly hinted in the name of said port. For example: "hObj" -> is a handle to an object (it can be treated like an object) "sRecName" -> is a string (text) "nX" -> is a number and so on To cut a long story short, here is a corrected version of your Marionette: punkt_schieben_Marionette.vwx Regards, Letti
  7. Hello, unfortunately i cant share the file. This is my workarround, however i think it is not a good one: I wrote a script that copies a duplicate of the object to another layer and rotates it, so that its edges are parallel to x, y, z. Then i read the bbox values and put them into a data record and attached it to the original object. I think that this is a bad idea (in general) because the values in the records dont change automatically if the object changes, but in this case the objects dont get changed. Interestingly this script only takes some seconds to run and does not have memory issues at all, even if run multiple times. I wonder why the worksheet script takes so much longer, even if it does the same thing (or even less). Regards, Letti
  8. Hello, thank you for your reply @Tobias Kern. Unfortunately this does not work, because DEPTH gives wrong values. For example, lets say the object has x, y, z of 1, 2, 3. If WIDTH, HEIGHT, DEPTH would give scrambled values like, 2, 3, 1, this would be no problem because i can sort the values for example the way you pointed out. However i get results like 2, 3, 3 or 1, 2, 2 where one value (the value i get from DEPTH) is just wrong. Interestingly the VS function vs.Get3DInfo(obj) seems to always give the correct values. Regards, Letti
  9. Hello, i have a file with thousands of 3d ifc objects that are rotated in all kind of ways in 3d space. Now i want to sort them by their width, depth and height, so that i can sum them up. I tried to use the =WIDTH, = HEIGHT and =DEPTH functions in a worksheet, however the =DEPTH function gives wrong results when the objects are rotated in a specific way. But because i know that in this case the objects dimensions follow this rule x >= y >= z, i wrote a simple WS scipt that uses vs.Get3DInfo(obj) , which gives me the right results for the dimensions and simply sort them by their value. The problem is (apart from the ws beeing very slow, what was expected), that the script uses a lot of ram and even if the script is finished the used ram number of vw wont drop by much until i restart vw and if i run the script again it just adds to the previously used ram. See below the WS Script that im using. def get_xyz(): # infos obj = vs.WSScript_GetObject() choice = vs.WSScript_GetPrmStr(0) if isinstance(choice, str): choice = choice.lower() # script nHeight, nWidth, nDepth = vs.Get3DInfo(obj) # choice if choice == "h": vs.WSScript_SetResReal(nHeight) elif choice == "w": vs.WSScript_SetResReal(nWidth) elif choice == "d": vs.WSScript_SetResReal(nDepth) else: vs.WSScript_SetResStr("Choice error!") # run get_xyz() I think that the best solution would be to try to export the ifc objects (if possible) in a different way, so that the needed values are already attached to some record, but i am wondering if i am doing something wrong regarding the WS script? Regards, Letti
  10. Hello, if you have a simple solid object (e.g. a cube or an extrusion) this could be done by "extracting" the top or the bottom of the solid. But if your solid object gets just a little bit more complicated, for example two different sized cubes that are added together, this is not as straight forward anymore and there would be different ways, that would give different results. You could for example: want to have the bottom of the solid or just the top or the polygon of a section at a given height or all faces that you can see from the top all faces that you can see from the bottom and maybe more... Maybe you can provide us with an example file where you show some solids that you have, aswell as the expected results. Regards, Letti
  11. Hello, Computerworks already wrote a node to convert Symbols into Groups. You can download it here. Regards, Letti
  12. Hello, i think i struggle to undestrand what exactly you want to acchieve, because i think that width and height of the rectangle cant be choosen independently from spacing if the dircles need to fit into the corners like its drawn in the second screenshot. However this is how i would do a Marionette that distributes loci (a point) along a "line" that follows the x direction, when also the number of points that should be on this line are given: And the same Marionette but for the y direction: And a Marionette that combines the x and y direction into a grid (you have to set the "Mix" node to "Cross Reference" in the OIP of the node): Regards, Letti
  13. Hello, Have a Look at this Marionette, maybe this ist what you are looking for. Regards, Letti
  14. Hello, thank you for your reply. This is definitely an error i did not see. Luckily it should be an easy fix. And i am still hoping that someone has a better solution than this. Here is the code for the updated node: @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( 'n inches to string feet and inches' ) this.SetDescription( 'n inches to string feet and inches' ) #Input Ports n_inches_input = Marionette.PortIn( 0, 'n inches' ) n_inches_input.SetDescription( 'n inches' ) i_round_input = Marionette.PortIn( 9, 'i round inches to' ) i_round_input.SetDescription( "i round inches to" ) #OIP Controls b_zero_input = Marionette.OIPControl( 'ZERO.X -> .X', Marionette.WidgetType.Bool, True) b_zero_input.SetDescription('ZERO.X -> .X') b_half_input = Marionette.OIPControl( '.5 -> 1/2', Marionette.WidgetType.Bool, True) b_half_input.SetDescription('.5 -> 1/2') b_quarter_input = Marionette.OIPControl( '.25 -> 1/4', Marionette.WidgetType.Bool, True) b_quarter_input.SetDescription('.25 -> 1/4') #Output Ports s_output = Marionette.PortOut('s feet and inches (rounded)') s_output.SetDescription( 's feet and inches (rounded)' ) #BEHAVIOR def RunNode(self): #inputs n_inches = self.Params.n_inches_input.value i_round = int(self.Params.i_round_input.value) b_zero = self.Params.b_zero_input.value b_half = self.Params.b_half_input.value b_quarter = self.Params.b_quarter_input.value # script temp_feet_num = int(n_inches // 12) temp_inches_num = round(n_inches % 12, i_round) temp_feet = str(temp_feet_num) temp_inches = str(temp_inches_num) temp_inches = temp_inches.rstrip(".0") if b_zero: temp_inches = temp_inches.lstrip("0") if b_half: if temp_inches[-2:] == ".5": temp_inches = temp_inches[:-2] + " 1/2" if b_quarter: if temp_inches[-3:] == ".25": temp_inches = temp_inches[:-3] + " 1/4" elif temp_inches[-3:] == ".75": temp_inches = temp_inches[:-3] + " 3/4" temp_feet = temp_feet + "'" temp_inches = temp_inches + '"' temp_output = temp_feet + temp_inches if temp_inches_num == 0: temp_output = temp_feet if temp_feet_num == 0: temp_output = temp_inches temp_output = temp_output.strip() #outputs self.Params.s_output.value = temp_output Please note that i also set the default value of "i round inches to" to 9 decimal places. This should eliminate most errors that occur due to floating point inaccuracies whilst beeing precise enough. But you can ofcourse set the value to what you need. Also please note that i only tested this node while the document units were set to "feet and inches". If you use some other setting like "feet" the return value of the node will be wrong because the input will most likely not be in inches (the input number has to be in inches). Ofcourse i could write the node so that i checks the current unit settings of the document and converts what ever the input is into feet and inches, but i hope that i can avoid that for it would take some time. Regards, Letti
  15. Hello, i had a bit of fun with this problem and wrote a custom node that converts a number that is given in inches to a string that is in feet and inches. Because i dont know anything about imperial units i just tried to replicate what is shown in the OIP of the "Dim" node. But you can chose if you want to display .5" as 1/2" or as .5" (same with .25" and .75") in the OIP of the custom node via two checkboxes. I realy hope that this custom node is not necessary and that someone will show an easier (built-in) way, but until then this node should be a good workarround. To create the node just go into any node and replace the whole code with the code provided below. Please test the node and make sure that it works as intended! @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( 'n inches to string feet and inches' ) this.SetDescription( 'n inches to string feet and inches' ) #Input Ports n_inches_input = Marionette.PortIn( 0, 'n inches' ) n_inches_input.SetDescription( 'n inches' ) i_round_input = Marionette.PortIn( 0, 'i round inches to' ) i_round_input.SetDescription( "i round inches to" ) #OIP Controls b_zero_input = Marionette.OIPControl( 'ZERO.X -> .X', Marionette.WidgetType.Bool, True) b_zero_input.SetDescription('ZERO.X -> .X') b_half_input = Marionette.OIPControl( '.5 -> 1/2', Marionette.WidgetType.Bool, True) b_half_input.SetDescription('.5 -> 1/2') b_quarter_input = Marionette.OIPControl( '.25 -> 1/4', Marionette.WidgetType.Bool, True) b_quarter_input.SetDescription('.25 -> 1/4') #Output Ports s_output = Marionette.PortOut('s feet and inches (rounded)') s_output.SetDescription( 's feet and inches (rounded)' ) #BEHAVIOR def RunNode(self): #inputs n_inches = self.Params.n_inches_input.value i_round = int(self.Params.i_round_input.value) b_zero = self.Params.b_zero_input.value b_half = self.Params.b_half_input.value b_quarter = self.Params.b_quarter_input.value # script temp_feet = str(int(n_inches // 12)) temp_inches = str(round(n_inches % 12, i_round)) temp_inches = temp_inches.rstrip(".0") if b_zero: temp_inches = temp_inches.lstrip("0") if b_half: if temp_inches[-2:] == ".5": temp_inches = temp_inches[:-2] + " 1/2" if b_quarter: if temp_inches[-3:] == ".25": temp_inches = temp_inches[:-3] + " 1/4" elif temp_inches[-3:] == ".75": temp_inches = temp_inches[:-3] + " 3/4" temp_output = temp_feet + "'" + temp_inches + '"' if temp_feet == "0": temp_output = temp_inches + '"' temp_output = temp_output.strip() #outputs self.Params.s_output.value = temp_output Regards, Letti
×
×
  • Create New...