Jump to content

Letti R

Member
  • Posts

    70
  • Joined

Everything posted by Letti R

  1. Hello, assuming your Tree is a 3D symbol and not a PIO, these steps might help: Regarding #1.: I think you can get the 3D height of your 3D symbol by subtracting the output "nBotz" from the output "nTopz" of the "Get 3D Info" Node. Unfortunately this Node seemes to be brocken (hopefully only on my computer). If not, here is the code for a custom node that only outputs the 3D height. To create the node, replace the code of any existing node, with the code below. @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( 'get 3D height' ) this.SetDescription( 'get 3D height' ) #Input Ports x = Marionette.PortIn( None, '3D Object' ) x.SetDescription( "3D Object" ) #OIP Controls #Output Ports y = Marionette.PortOut('n') y.SetDescription( "n" ) #BEHAVIOR def RunNode(self): #inputs x = self.Params.x.value #script _, __, n = vs.Get3DInfo(x) #outputs self.Params.y.value = n (please only use this, if the "Get 3D Info" node does not work). Regarding #3.: Given you have drawn the correct arc, you can than turn this into a closed polyline by drawing a line from the center point of the arc to the start point of the arc and another line from the center to the end point of the arc. To create a polyline from that just put the arc and the two lines into the "compose" node. And this is how this Marionette could look like: Regards, Letti
  2. Hello, you may want to use. string.removeprefix("") string.removesuffix("") These functions seem to do what you are searching for. A Marionette node with the functions above could look like this: @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( "remove suffix prefix" ) this.SetDescription('Removes the suffix or the prefix from the full string.') #Input Ports s = Marionette.PortIn( '', 's' ) s.SetDescription('The full string.') s2 = Marionette.PortIn( '', 'sSub') s2.SetDescription('The substring.') #OIP Controls pos = ['left', 'right', 'both'] position = Marionette.OIPControl( 'Position', Marionette.WidgetType.RadioButton, 0, pos) position.SetDescription('an OIP control representing the position options for where the string gets stripped.') #Output Ports outList = Marionette.PortOut('sNew') outList.SetDescription('The stripped string.') #BEHAVIOR def RunNode(self): #inputs s = self.Params.s.value s2 = self.Params.s2.value pos = self.Params.pos position = self.Params.position.value #script if pos[position] == 'left': sNew = s.removeprefix(s2) elif pos[position] == 'right': sNew = s.removesuffix(s2) elif pos[position] == 'both': sNew = s.removeprefix(s2).removesuffix(s2) #outputs self.Params.outList.value = sNew You can create the node by replacing the code of any Marionette node with the code above. Regards, Letti
  3. Hello, to get the "vs.ResetBBox(h)" function within a Marionette node you can write the node with a bit of Python code by replacing the code in any node with the code below. @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( 'vs.ResetBBox(h)' ) this.SetDescription( 'vs.ResetBBox(h)' ) #Input Ports x = Marionette.PortIn( vs.Handle(0), 'h' ) x.SetDescription( "input" ) #OIP Controls #Output Ports y = Marionette.PortOut('h') y.SetDescription( "output" ) #BEHAVIOR #this.SetListAbsorb() def RunNode(self): #inputs x = self.Params.x.value #script vs.ResetBBox(x) #outputs self.Params.y.value = x Another way would be to create your own "node" by using the "function" node within a wrapper. Therefore you have to write the Python function "vs.ResetBBox(x)" into the OIP of the "function" node and wrap a small Marionette that looks like this: You can now use this wrapper like @DomC uses the "ResetBBox" node in his Marionette. Regards, Letti
  4. Hello, thank you for your kind words @ASag . It took me arround 3h to get to that solution. I would not consider that being fast. Also i had to try different things that did not work, i think i had to start over 3 times. I just realized that the steps to the solution you pointed out in your first post were pretty much spot on. Regards, Letti
  5. Hello, for this problem i would recommend solving it with a few lines of Python code inside of a Marionette node. Another thing i would consider is to try to solve this right when the intersection points are created. However if i had to solve this in Marionette i would do it like this (but i hope someone else has a simpler approch and i am just blind to it): If needed rewrite your data so that you can sort it. For example i got the start points of all the lines and rounded each x and y component, to account for imperfections that sometimes occure. Than i put the cooridnates back together in a tuple. Now you can create a list of indices or numbers, where same points get the same number, by removing the duplicates and then getting the index that each point has in this list where you removed the duplicates. I think this last step might not be necessary for sorting, but it also helps us later on so we dont have to check for equality of points. Also i converted the angle vectors of the lines into angles and also rounded them (to the 6th digit). As data i used the handle of the lines, length, angle and the start point Write your data as a list of nested tuples. Cou can create tuples by using the "Point 2D" node. As an Example this is one item from this list written in python syntax: (number of start point, (angle, (length, handle))) (0, (-135.0, (69.59001315942132, E3DB3460))) When you sort your data list now it will be sorted all the way down through all the nested tuples like this: The lines will be sorted by the number of its start point The lines with the same start point will be sorted by their angle The lines with the same angle will be sorted by their length Each line has its handle, so you can identify the line object later on Now you can get your data back with the "Flatten List" node and two "Every Other" node, where one is set to even and the other is set to odd. (There might be a better way to do that) The next step is to pick the right items of the lists with the handles. Here is my logic behind it: We know that the very first item of the list has to be a correct line We know that we want every item of the list right when the number of the start points changes We know that we want every item of the list right when the angle of the line changes This can be done by comparing the values of the lists (numbers of start point and angle) to a rotated version of itselfe. Rotate list by -1 Pop front of the list and the rotated list Check for equality of the remaining lists Append the result to a list with one "False" item in it ("Any" node with [False] written into it via the OIP) (The first "False" value is because we know that the very first item of the list is a correct item) Use the "and" node on the two lists you just created under point 6. Filter the list with the handles in it you created with point 4. Take the False items of the "Filter" node. And here is a .vwx (v22) file with this solution (you dont have to use it, if you realy want to solve this by yourself). BaseGeometryExample v2022.vwx Regards, Letti
  6. Hello, there are some more things you can try. Put a "Delete" node after the two "Copy" nodes. The "Delete" Node deletes the objects only after the whole Marionette script was executed, so this should get rid of all the copied objects that remained because they were not changed. "Remove Duplicates" directly after the "Planar Boolean" node. Filter objects by their handles after the "Planar Boolean" node with the "Is Member" node. "Is Member" checks if the given item is in a given list. This works if you put the output of the "Planar Boolean" node as the "Item" and both "hCopy" outputs of the "Copy" nodes as the "list" input of the "Is Member" node. After that you can just use the "Filter" node. Filter objects with the wrong object type. This might not be of relevance here, but in my case there were some groups in the output of the "Planar Boolean" node for some reason. And this is how i put all of the things mentioned above in a Marionette network: If this does not solve your problem you could also upload a example file, so that we can provide better help. Regards, Letti
  7. Hello, sometimes it can be tricky to manage lists in Marionette networks. Fortunately in this case its an easy fix. Here is how the network could look like: First of all there was an error in your network. The "Sequence" node generated one index too much, so i replaced it with the "Series" node. Apart from that you have to manage the inputs of the "Get 2D Edge" node to make this network run correctly. Here are your inputs to the "Get 2D Edge" node before the fix: As you can see you have a mismatch of handles to a polygon and the indices. So what you get is the first edge of the first polygon, the second edge of the second polygon, the third edge of the third polyogn and the first edge of the fourth polygon. But now you "ran our of polygons" so i think Marionette just repeats the last polygon from the list like this: Thats why one Polyogn (the last one) was done "correctly" (even though some edges were done multiple times). This is easily fixed if we repeat the handle of each polygon by the amount of its vertecies. This can be done with the "Repeat" node. Now the inputs of the "Get 2D Edge" look like this: I hope i could help you a bit. Unfortunately my english reaches its limits when trying to explain things like this. Regards, Letti
  8. Hello, when you reset the user origin, you will get the right coordinates. If you want to keep the user origin it seems like you can do something like this: import vs CR = chr(13) # Carriage Return char def todo(h): tl, br = vs.GetBBox(h) # Unpacking return values o = vs.GetOrigin() # Coordinates of user origin tl_o = (tl[0] + o[0], tl[1] + o[1]) br_o = (br[0] + o[0], br[1] + o[1]) vs.AlrtDialog('BBox for Obj Type: ', vs.GetTypeN(h), CR, 'TL: ', str(tl_o), CR, 'BR: ', str(br_o)) return True vs.ForEachObjectInLayer(todo,2,0,4) # Selected, Shallow, All & Visible layers Regards, Letti
  9. Hello, i just tried it myself and i am amazed, this seems like a good tool to learn from existing code. I wrote a little nonsensical script to test Chat. PROMPT Can you explain this Python script for Vectorworks line by line, considering the information you can find in the documentation (https://developer.vectorworks.net/index.php/VS:Function_Reference): def run(): vs.AlertInform("Error", "Chat", False) vs.CallTool(-201, run) ANSWER Sure! Here's a line-by-line explanation of the script: def run(): vs.AlertInform("Error", "Chat", False) This defines a function called `run` that takes no arguments. Inside the function, it calls the `vs.AlertInform` function from the Vectorworks scripting module `vs`. This function displays an alert dialog which provides the user with information about the result of a command. It offers no user choices¹. The first argument `"Error"` is the text to be displayed in the alert dialog. The second argument `"Chat"` is additional text to be displayed in a smaller font under the main information message. The third argument `False` specifies that this is a major alert (as opposed to a minor alert)¹. vs.CallTool(-201, run) This line calls the `vs.CallTool` function from the Vectorworks scripting module `vs`. This function activates the specified VectorWorks tool for a single use. After the tool has been used, VectorWorks will revert back to the previously active tool⁵. The first argument `-201` specifies the tool ID of the tool to be activated. The second argument `run` is a callback function that will be executed when the tool finishes⁵. I hope this helps! Is there anything else you would like to know? Quelle: Unterhaltung mit Bing, 27.4.2023 (1) VS:AlertInform - Vectorworks Developer. https://developer.vectorworks.net/index.php/VS:AlertInform. (2) VS:CallTool - Vectorworks Developer. https://developer.vectorworks.net/index.php/VS:CallTool. (3) VCOM:VectorWorks:ISDK::AlertInform - Vectorworks Developer. https://developer.vectorworks.net/index.php/VCOM:VectorWorks:ISDK::AlertInform. (4) VS:AlertInformHLinkN - Vectorworks Developer. https://developer.vectorworks.net/index.php/VS:AlertInformHLinkN. (5) VS:AlertInformHLink - Vectorworks Developer. https://developer.vectorworks.net/index.php/VS:AlertInformHLink. (6) vs.CallTool SP3 - Python Scripting - Vectorworks Community Board. https://forum.vectorworks.net/index.php?/topic/95084-vscalltool-sp3/. (7) VS:CallToolByName - Vectorworks Developer. https://developer.vectorworks.net/index.php/VS:CallToolByName. (8) VS:CallToolByIndex - Vectorworks Developer. https://developer.vectorworks.net/index.php/VS:CallToolByIndex. As expected it could not find the information about the argument "-201" even when i pointed it into the right direction. Obviously it "only" provided me with the information it found in the documentation, but that leaves me wondering what it could do if the documentation would be a little more Chat friendly and a bit more complete. Regards, Letti
  10. Hello, there are two ways that i know of to get selected objects with just the nodes that come with vectorworks. The first one is to use the "Criteria Dialog" Node. This is not a good solution for this case as you have to create the criteria by alot of clicking. The second way is to use the "function" Node and than enter the python function "vs.FSActLayer()" as the function into the OIP of the node. Than this node will get you the first selected object on the active layer. If you use this workarround i would recommend combining it with a "If" node to check if the selected object is of the object type that your Marionette needs. This only works if you make your Marionette network into a menu command. For a 3D Locus it could look something like this: The following links provide you with some more information about the python function "vs.FSActLayer()" and about the numbers of the different object types of vectorworks: https://developer.vectorworks.net/index.php/VS:FSActLayer https://developer.vectorworks.net/index.php/VS:Function_Reference_Appendix_D Regards, Letti
  11. Hello, unfortunately i dont understand your screenshot, so i am not 100% sure that this is what you are searching for, but here is a small example network that creates a 3D array of an object (it has to be a 3D object, or it wont be moved in 3D space) by duplicating it and moving the duplicates. I am pretty sure this is not the optimal solution but in my example it works. If you recreate this example please make sure to set the two mix nodes to "Cross Reference" in the OIP. Regards, Letti
  12. Hello, i thought @Wopke wanted the "inner" shadow of a rectangle. Is this also possible with the drop shadow settings? Regards, Letti
  13. Hello, assuming all the rectangles are alligned to the x and y axis the following script should do the trick. # FUNCTIONS def selection_on_active_layer_to_handle(): handles = [] def callback_selection_on_active_layer_to_handle(handle): handles.append(handle) vs.ForEachObject(callback_selection_on_active_layer_to_handle, "(NOTINDLVP & NOTINREFDLVP & ((L='" + vs.GetLName(vs.ActLayer()) + "') & (VSEL=TRUE)))") return(handles) # SCRIPT selection = selection_on_active_layer_to_handle() for item in selection: if vs.GetTypeN(item) == 3: blank = vs.CreateDuplicateObject(item, vs.Handle(0)) tool = vs.CreateDuplicateObject(item, vs.Handle(0)) vs.HMove(tool, -0.5, -0.5) # change "-0.5, -0.5" to the desired offset, depending on the units you use in your drawings vs.SetFPat(blank, 1) vs.SetFillBack(blank, (0, 0, 0)) vs.SetOpacityN(blank, 40, 40) vs.ClipSurfaceN(blank, tool) vs.DelObject(blank) vs.DelObject(tool) vs.SetDSelect(item) You will have to change some values in the script because i dont know which units you use. I kept this script as simple as possible so i dont take care of different document units via the script. I think you maybe want to modify the script even further, because from your post it was unclear: - If the original rectangles should be deleted by the script - If the Shadow has an outline - If so, which opacity - etc. Here is how this script works: - Read in all the selected objects on the active layer and "save" them in a list - Go through all the objects in this list - If the object is a rectangle - Create two duplicates of the rectangle - Move one of them by the amount you specified the offset to be (width and height of the shadow) - Set the color and opacity of the other duplicated rectangle to the right values (black and 40%) - Clip the moved rectangle from the colored rectangle - Deselect the original item Regards, Letti
  14. Hello, i changed the existing "Alert Inform Dialog", maybe it fits your needs now. To create the node simply replace the whole code of any Marionette node with the code below. @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( 'Alert Inform Dialog' ) this.SetDescription( 'Displays an alert dialog which provides the ' + 'user an information about the result of a ' + 'command. It offers no user choices.' ) #Input Ports input = Marionette.PortIn( None , 'item') input.SetDescription( "input" ) alertTxt = Marionette.PortIn( "" , 'str_alert') alertTxt.SetDescription( "input" ) advTxt = Marionette.PortIn( "" , 'str_advice') advTxt.SetDescription( "input" ) #OIP Controls minorAlrt = Marionette.OIPControl( 'Minor Alert', Marionette.WidgetType.Bool, False) minorAlrt.SetDescription( 'The severity of the alert: minor(true) or major(false)' ) #Output Ports output = Marionette.PortOut('item') output.SetDescription( "output" ) #BEHAVIOR # this.SetListAbsorb() def RunNode(self): #inputs input = self.Params.input.value alertTxt = self.Params.alertTxt.value advTxt = self.Params.advTxt.value minorAlrt = self.Params.minorAlrt.value #script if input is not None: vs.AlertInform(alertTxt, advTxt, minorAlrt); #outputs self.Params.output.value = input To create the string you can just add strings together with the "Str" Node if you put in a list of things (in your case an integer and a string). Regards, Letti
  15. Hello, to solve problems like this i like to look into Marionette nodes. There is a Marionette Node "Get Arc" and the first output is the radius and this is how it was written in the node: arcvalues = vs.GetArc(h) perim = vs.HPerim(h) sweepR = vs.Deg2Rad(arcvalues[1]) radius = perim / sweepR Regards, Letti
  16. Hello, i think there is a function you can use for this. You can read about the function here: https://developer.vectorworks.net/index.php/VS:FindObjAtPt_Create I use this in one of my scripts, but i never tried using it within a marionette network. However you can put this function into a marionette node. Such a node could look something like this (to create the node, please replace the code in a node with the code below and click ok): @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( 'get_objects_at_point' ) this.SetDescription( 'get_objects_at_point' ) #Input Ports point_in = Marionette.PortIn( (0, 0), 'point' ) point_in.SetDescription( "point" ) #OIP Controls object_options_input = Marionette.OIPControl( 'object options', Marionette.WidgetType.Popup, 0, ['All objects', 'Visible only', 'Selected only', 'Unlocked only']) object_options_input.SetDescription('object options') travers_options_input = Marionette.OIPControl( 'travers options', Marionette.WidgetType.Popup, 0, ['Shallow', 'Groups']) travers_options_input.SetDescription('travers options') pick_radius_input = Marionette.OIPControl( 'rick radius', Marionette.WidgetType.Real, 0.1) pick_radius_input.SetDescription('rick radius') #Output Ports objects_out = Marionette.PortOut('objects') objects_out.SetDescription( "objects" ) #BEHAVIOR def RunNode(self): #inputs point = self.Params.point_in.value object_options = self.Params.object_options_input.value travers_options = self.Params.travers_options_input.value pick_radius = self.Params.pick_radius_input.value # FUNCTIONS def get_objects_at_point(object_options, travers_options, point, pick_radius): object_finder_id = vs.FindObjAtPt_Create(vs.Handle(0), object_options, travers_options, point[0], point[1], pick_radius) objects_at_point = [] for i in range(vs.FindObjAtPt_GetCount(object_finder_id)): objects_at_point.append(vs.FindObjAtPt_GetObj(object_finder_id, i)) vs.FindObjAtPt_Delete(object_finder_id) return(objects_at_point) #script #outputs self.Params.objects_out.value = get_objects_at_point(object_options, travers_options, point, pick_radius) This node gives you a list of all objects at a specific point. Please note that it is possible that some settings/arguments do not make sense if this function is run within a marionette network even if i included them into the node (for example the setting/argument "selected only"). Regards, Letti
  17. Letti R

    hgarnade

    Hello, here is a new version of the tool. I fixed an error that occured when the document units were set to imperial with unit marks displayed. This error did not cause wrong results in your drawings (for example wrong bit diameter or wrong additional bone length), the tool just was not able to run under the mentioned circumstances. If you are using imperial units please dont use the document settings "feet and inches" together with this tool, as this will likely result in very small rounding errors in the bit diameter and additional bone length. However if you use the settings only "inches" or only "feet" this rounding error will not occur. Thanks to @Ken S. for reporting this error and helping me to fix it. Also if someone knows the proper way to deal with user input in imperial units in vw, i would realy like to learn about it. Regards, Letti 2D Mill Fill_0_2_1.vst
  18. Hello, it seems like it does not work in your case, because the wrapper builds a group in which all groups from the network are put in. So you have groups that were made by nodes in a group that was made by the wrapper. There are two solutions that come to my mind: Ungroup every group from every node that created one, aswell as the group from the wrapper, with a node. I think doing the above two or more times might do the trick, although i have not testet that. I also spotted something i dont like in the network from my previous post. I think it would be better to put a "remove duplicates" node between "get parent" and "ungroup" node, so that the network only tries to ungroup every group once. Set the parent of all created objects to be the active layer (or any other layer you want). Unfortunately i could not find a node that comes with vw that does that. But because i can write nodes by myselfe i quit searching pretty quick and just write the node myself. Just replace the whole code in any node with this code and click on ok. If you find another node that does the same thing as mine, than use the other node. Chances are high, that it is written better than mine. Here is the code of the node: @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( 'set_parent' ) this.SetDescription( 'set_parent' ) #Input Ports x = Marionette.PortIn( [], 'items' ) x.SetDescription( "items" ) #OIP Controls #Output Ports y = Marionette.PortOut('items') y.SetDescription( "items" ) #BEHAVIOR this.SetListAbsorb() def RunNode(self): #inputs x = self.Params.x.value #script handle_active_layer = vs.ActLayer() for item in x: vs.SetParent(item, handle_active_layer) #outputs self.Params.y.value = x Here is an image of your wrapper with the node, and as far as i can tell it works (i'm sorry i cant give you the .vwx file, because i only have an educational version): Regards, Letti
  19. Hello, you can get the handle of the group where the line is in with the "Get Parent" node. Than you can ungroup this group with the "Ungroup" node. But as @Pat Stanford pointed out the Marionette network will no longer overwrite the previously generated geometry but will draw a new line everytime you run the network. Regards, Letti
  20. Hello, is there a way to get the SDK for VW23 SP1, because when i download the SDK it is still version VW28.0.0. Regards, Letti
  21. Hello, i compiled my tool with the 2023 SDK without changing anything in the code (the tool works without any problems in VW 2022). The compilation ends without an error, but when i tried to run the tool, VW crashed. My VW version ist 2023 SP1, and the SDK version is VW28.0.0. I think the crash occurs when tool points are cleared, but im not sure. I can get rid of crashing VW by using "VWToolDefaultLine_EventSink" instead of "VWToolDefault_EventSink", but than i dont know how to remove the 3 standard buttons in the mode bar . Also i noticed that everytime i crash VW a crash dump file gets created, is there a way to open these files and get meaningful information from them? And how do i find out what exactly causes VW to crash? Or would it be better to remove the standard buttons that come with "VWToolDefaultLine_EventSink"? Regards, Letti
  22. Letti R

    hgarnade

    Hello, after some changes and bug fixing, i am happy to share the tool with you that i wrote for @hgarnade. The tool automates the creation of “Dog-Bone” and “T-Bone” fillets in VW. Dog-Bones and T-Bones are used to deal with the rounded inner corners, that result from the diameter of the mill, when cutting materials with a CNC. This solution is often used to create joints, where one piece must fit precisely in a hole. Here is a short video on how the tool is used. The tool works on Rectangles, Polygons and Polylines. Currently the tool does not work if you are inside a group, symbol, extrude etc. If you have any problems with the tool, or an idea on how to improve it, please feel free to message me. Thanks to @hgarnade for the feedback while testing early versions of the tool. Use at own risk. Although the tool has been thoroughly tested, bugs cannot be ruled out. Please consider saving your VW file before using this tool. Regards, Letti 2D Mill Fill 2023.vst
  23. Hello, unfortunately i cant figure out if your Marionette is working correctly, because it is quite complicated, but i think a simple "Delete" node right behind the "Rectangle" node could do the trick. But i also wrote the node you were looking for, or at least i think so: @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( "Planar Boolean" ) this.SetDescription('This node performs a boolean operation between lists of objects. The operation will be performed for each possible combination of objects in the lists supplied.') #Input Ports in0 = Marionette.PortIn( vs.Handle(0), 'hBlank' ) in0.SetDescription('A list of objects to be operated on (blanks)') in1 = Marionette.PortIn( vs.Handle(0), 'hTool') in1.SetDescription('A list of objects to operate on "in0" with (tools)') n_action_in = Marionette.PortIn( 0, 'nAction' ) n_action_in.SetDescription( '0 = Add, 1 = Subtract, 2 = Intersect' ) #OIP Controls #Output Ports out = Marionette.PortOut('hObj') out.SetDescription('The resulting objects') #BEHAVIOR this.SetLinksObjects() this.SetListAbsorb() def RunNode(self): #inputs in0 = self.Params.in0.value in1 = self.Params.in1.value n_action = self.Params.n_action_in.value[0] #script output = [] if type(in0) != list: in0 = [in0] for blank in in0: if blank != vs.Handle(0): if type(self.Params.in1.value) != list: in1 = [in1] for tool in in1: newObj = vs.Handle(0) if tool != vs.Handle(0): #Add if n_action == 0: newObj = vs.AddSurface(blank, tool) # blank and tool will be deleted after this operation if newObj != vs.Handle(0) and newObj != None and newObj != tool: blank = newObj #Subtract elif n_action == 1: newObj = vs.ClipSurfaceN(blank, tool) # blank and tool won't be deleted after this operation if newObj != vs.Handle(0) and newObj != None and newObj != tool: vs.Marionette_DisposeObj(blank) vs.Marionette_DisposeObj(tool) blank = newObj #Intersect elif n_action == 2: newObj = vs.IntersectSurface(blank, tool) # blank and tool won't be removed after this opeartion if newObj != vs.Handle(0) and newObj != None and newObj != tool: vs.Marionette_DisposeObj(blank) vs.Marionette_DisposeObj(tool) blank = newObj while blank != vs.Handle(0): if n_action in [1, 2]: if blank != tool: output.append(blank) else: output.append(blank) blank = vs.NextObj(blank) #outputs self.Params.out.value = output If you need, i could also add a "Do nothing"- action to this node, where the "hBlank" is put out of the node unchanged and the "hTool" object gets deleted? Regards, Letti
  24. Hello, it seems like the "Planar Boolean" node is not working as expected if you want to add many objects to many objects. However the node is working properly if you try to add many objects to one object. Luckily in this case we can take advantage of that. So i just took the first "Blank" rectangle and added all "Tool" rectangles to it. Than i added all remaining "Blank" rectangles to the resulting polygon of the step before. I think this is only possible here because every "Blank" rectangle is overlapping every "Tool" rectangle. So this is NOT a good solution to the general problem, but maybe it solves your specific problem. Here is an image of the things i changed in your network: Regards, Letti
  25. Hello, i think the solution of @Pat Stanford is working when the "False" value of the "If" node is "vs.Handle(0)" (take a "Any" node and write "vs.Handle(0)" into it). I tested it with 2 rectangles, my Marionette looks like this: I tried to find an explanation for this behaviour, but i think i will leave it to the experts ☺️ Regards, Letti
×
×
  • Create New...