Raph Posted November 10, 2022 Share Posted November 10, 2022 Hello to all, I have a new request for you... I would like to create a small program (parametric symbol) to calculate the need for panels on a floor. The principle is quite simple because it is enough to add panels in a row. However they must cross each other in order to be more stable and to use the remains. I enclose a picture to illustrate the problem. If someone has already done it or has an idea of the tools I can use I'm listening... 😉 Greetings Raph GraphiqueCollé-1.pdf Quote Link to comment
Pat Stanford Posted November 11, 2022 Share Posted November 11, 2022 Try this one as a starting point. Very poorly scripted, but it seems to work. Procedure TileRects; {November 11, 2022} {©2022 Patrick Stanford pat@coviana.com} {Licensed under the GNU Lesser General Public License} {No Warranty Expressed of Implied. Use at your own risk.} {Very limited testing.} {Tiles a rectangular area with a set of rectangles} {the beginning of each row is the "cutoff" from the} {end of the row above.} VAR X1,X2,Y1,Y2 :Real; FX1,FX2,FY1,FY2 :Real; {Floor Dims} RX1,RX2,RY1,RY2 :Real; {Rect Dims} Hd1 :Handle; W1, H1 :Real; {panel width and height} NP :Integer; {number of full panels in row} Extra :Real; CurrentX, CurrentY :Real; SheetEndX, SheetEndY :Real; RemainderX, RemainderY :Real; ThisY :Real; Done :Boolean; BEGIN PtDialog('Enter the size of panel', '2500mm', '675mm', W1, H1); Hd1:=FSActLayer; If Hd1 <> Nil THEN BEGIN GetBBox(Hd1, FX1, FY1, FX2, FY2); CurrentX:=FX1; CurrentY:=FY1; SheetEndX:=FX1+W1; SheetEndY:=FY1-H1; RemainderX:=0; RemainderY:=0; NP:=1; Done:=False; SetDSelect(Hd1); WHILE Not Done DO BEGIN While SheetEndX <= FX2 DO BEGIN ThisY := Max(CurrentY-H1, FY2); Rect(CurrentX, CurrentY, CurrentX + W1, ThisY); CurrentX:=CurrentX + W1; SheetEndX:=CurrentX+W1; NP:=NP+1; End; RemainderX:=W1-(FX2-CurrentX); Rect(CurrentX, CurrentY, FX2,Max(CurrentY - H1,FY2)); If ((SheetEndX <> FX2) and (SheetEndY <> FY2)) then Begin CurrentY:=Max(CurrentY-H1, FY2); CurrentX:=FX1+RemainderX; SheetEndY:=Max(CurrentY-H1,FY2); Rect(FX1,CurrentY,CurrentX,SheetEndY); SheetEndX:=CurrentX+W1; END Else Done:=True; End; End; End; Run(TileRects); Procedure TileRects; {November 11, 2022} {©2022 Patrick Stanford pat@coviana.com} {Licensed under the GNU Lesser General Public License} {No Warranty Expressed of Implied. Use at your own risk.} {Very limited testing.} {Tiles a rectangular area with a set of rectangles} {the beginning of each row is the "cutoff" from the} {end of the row above.} VAR X1,X2,Y1,Y2 :Real; FX1,FX2,FY1,FY2 :Real; {Floor Dims} RX1,RX2,RY1,RY2 :Real; {Rect Dims} Hd1 :Handle; W1, H1 :Real; {panel width and height} NP :Integer; {number of full panels in row} Extra :Real; CurrentX, CurrentY :Real; SheetEndX, SheetEndY :Real; RemainderX, RemainderY :Real; ThisY :Real; Done :Boolean; BEGIN PtDialog('Enter the size of panel', '2500mm', '675mm', W1, H1); Hd1:=FSActLayer; If Hd1 <> Nil THEN BEGIN GetBBox(Hd1, FX1, FY1, FX2, FY2); CurrentX:=FX1; CurrentY:=FY1; SheetEndX:=FX1+W1; SheetEndY:=FY1-H1; RemainderX:=0; RemainderY:=0; NP:=1; Done:=False; SetDSelect(Hd1); WHILE Not Done DO BEGIN While SheetEndX <= FX2 DO BEGIN ThisY := Max(CurrentY-H1, FY2); Rect(CurrentX, CurrentY, CurrentX + W1, ThisY); CurrentX:=CurrentX + W1; SheetEndX:=CurrentX+W1; NP:=NP+1; End; RemainderX:=W1-(FX2-CurrentX); Rect(CurrentX, CurrentY, FX2,Max(CurrentY - H1,FY2)); If ((SheetEndX <> FX2) and (SheetEndY <> FY2)) then Begin CurrentY:=Max(CurrentY-H1, FY2); CurrentX:=FX1+RemainderX; SheetEndY:=Max(CurrentY-H1,FY2); Rect(FX1,CurrentY,CurrentX,SheetEndY); SheetEndX:=CurrentX+W1; END Else Done:=True; End; End; End; Run(TileRects); 1 Quote Link to comment
Raph Posted November 14, 2022 Author Share Posted November 14, 2022 Hi Pat, Thanks for this program, it works very well. I have already adapted with an additional condition that removes 4mm from the remaining panels. This is to deduct the thickness of the blade. I am now working on putting an additional condition that will make it so that if the panel at the end of the line is smaller than X (200mm) it will start the row with a whole panel. thanks you very much for your help your base allows me to move forward Raph 2 Quote Link to comment
Pat Stanford Posted November 14, 2022 Share Posted November 14, 2022 I am glad it helped. I basically brute forced it. You can probably optimize that script a lot. Quote Link to comment
Raph Posted November 17, 2022 Author Share Posted November 17, 2022 @Pat Stanford Hi Pat, just a question.... why didn't you make the program in python language? Are there points that are easier to code with VectorScript or just out of habit? Well... that's 2 questions sorry Thanks in advance for your reply Quote Link to comment
Raph Posted November 17, 2022 Author Share Posted November 17, 2022 (edited) Hello, I made some changes 1. a deduction in the remaining panel of the thickness of the blade (ThBl:4mm) 2. a minimum dimension at the end of a line that allows to decide if the line starts with a new panel (WmaxSold:200mm) Procedure TileRects; {November 11, 2022} {©2022 Patrick Stanford pat@coviana.com} {Licensed under the GNU Lesser General Public License} {No Warranty Expressed of Implied. Use at your own risk.} {Very limited testing.} {Tiles a rectangular area with a set of rectangles} {the beginning of each row is the "cutoff" from the} {end of the row above.} {Modified by Raph_N November 17, 2022} {added two parameters: 1. a deduction in the remaining panel of the thickness of the blade (ThBl:4mm) 2. a minimum dimension at the end of a line that allows to decide if the line starts with a new panel (WmaxSold:200mm).} VAR X1,X2,Y1,Y2 :Real; FX1,FX2,FY1,FY2 :Real; {Floor Dims} RX1,RX2,RY1,RY2 :Real; {Rect Dims} ThBl :Real; {Thikness of the blade Dims} Hd1 :Handle; W1, H1 :Real; {panel width and height} NP :Integer; {number of full panels in Total} NProw :Integer; {number of full panels in row} Extra :Real; CurrentX, CurrentY :Real; SheetEndX, SheetEndY :Real; RemainderX, RemainderY :Real; RemainderX2 :Real; ThisY :Real; WmaxSold :Real; {maximum weight of the sold} Done :Boolean; NewLine :Boolean; BEGIN PtDialog('Enter the size of panel', '2500mm', '675mm', W1, H1); Hd1:=FSActLayer; If Hd1 <> Nil THEN BEGIN GetBBox(Hd1, FX1, FY1, FX2, FY2); CurrentX:=FX1; CurrentY:=FY1; SheetEndX:=FX1+W1; SheetEndY:=FY1-H1; ThBl:=4; RemainderX:=0; RemainderY:=0; NP:=1; NProw:= Trunc((FX2-FX1)/W1); WmaxSold:= ((FX2-FX1)-(NProw*W1)); Done:=False; SetDSelect(Hd1); WHILE Not Done DO BEGIN RemainderX2:=W1-WmaxSold; NProw:= Trunc(((FX2-FX1)-(W1-WmaxSold))/W1); WmaxSold:= ((FX2-FX1)-(NProw*W1)-RemainderX2); While SheetEndX <= FX2 DO BEGIN If ((NP <> 1) and (WmaxSold<200)) then BEGIN RemainderX:=0; NewLine:=True; END ELSE ; ThisY := Max(CurrentY-H1, FY2); Rect(CurrentX, CurrentY, CurrentX + W1, ThisY); CurrentX:=CurrentX + W1; SheetEndX:=CurrentX + W1; NP:=NP+1; End; RemainderX:=W1-(FX2-CurrentX)-ThBl; Rect(CurrentX, CurrentY, FX2, Max(CurrentY - H1,FY2)); If ((SheetEndX <> FX2) and (SheetEndY <> FY2)) then Begin If (NewLine = true) then BEGIN CurrentX:=FX1+W1; NewLine:=False; NProw:= Trunc((FX2-FX1)/W1); WmaxSold:= ((FX2-FX1)-(NProw*W1)); END ELSE CurrentX:=FX1+RemainderX; CurrentY:=Max(CurrentY-H1, FY2); SheetEndY:=Max(CurrentY-H1,FY2); Rect(FX1,CurrentY,CurrentX,SheetEndY); SheetEndX:=CurrentX+W1; NP:=NP+1; END Else Done:=True; End; End; End; Run(TileRects); Edited November 17, 2022 by Raph Quote Link to comment
Pat Stanford Posted November 17, 2022 Share Posted November 17, 2022 11 minutes ago, Raph said: just a question.... why didn't you make the program in python language? I have been programming in Vectorscript (Pascal) for over 35 years. It is just more comfortable for me. I have three major problems with Python. 1. It is case sensitive. I am not a great typist and making sure I always use the same capITAlizATION in all of my variable names is a challenge. 2. It is white space delimited. Changing the number of spaces a block of code is indented changes what block it is in and how a loop may perform. I much prefer the explicit Begin/End construction of VS. VS also allows me to throw in debugging code that is left aligned so I can go back and find/change/delete it easily later. 3. Variables are not typed. In VS the type of each variable must be explicitly declared (boolean, string, integer, real, etc) If I try to assign a different type of value to that variable I get an error. In Python, variables are more dynamic. If I use a variable to hold a number and then get confused and later assign a string to it it does not complain. Especially in my quick and dirty coding, this can lead to improper execution and debugging issues. If you don't need to do anything outside of VW, then VS and Python are equivalent (Python uses VS calls for handling all VW objects). Or almost equivalent as there are a few things that Python can't do well (wait for user input is one). If you need to do anything outside of VW (pull in data from the web, do array calculations, use libraries like SciPy or Pandas) then Python is the only way to go. While I was able to create the above in about an hour in VS (due to my experience) my guess is it would have taken me 2 to 5 times as long in Python (due to my inexperience). If you are familiar with Python, it is fairly easy to convert the VS code into Python. I like your modifications. One suggestion. If you are pasting code into the forum use a code block Then your code will show up in a monospaced font and it will handle tabs as well as spaces for indentation Like this. Quote Link to comment
Raph Posted November 17, 2022 Author Share Posted November 17, 2022 Hi Pat, Thanks for your reply, i unterstand your preferences and the reasons that push you to continue on VS. Is it possible to link VS code with Marionette? Or is it only possible with Python? My basic idea was to create a parametric symbol (Marionette) where you just have to change the input variables (Floor dimensions and Panel dimensions) to recalculate the tile distribution. So now I try to write it in Python. You wrote: "If you are familiar with Python, it is fairly easy to convert the VS code into Python." No, it's not... I've done VBA instead. So the declaration of variables I also like a lot 😉 With python I tried to add two values and it tells me it's impossible because one time it's an 'int' and another is in 'list'??? grrr Thank you for your suggestion, I have corrected the post directly Kind regards Raph Quote Link to comment
Pat Stanford Posted November 17, 2022 Share Posted November 17, 2022 Unfortunately, Marionette nodes are Python only. If you have a script that works, it can be converted into a Plug-in Object with just a few modifications to the script. Go to the Plug-in Manager and create a new Rectangle Object. You will by default get two parameters, LineLength and BoxWidth. These will automatically change when you reshape the "rectangle" of the object. Use them to draw the outline of the room. Create two new parameter for the sheet width and height (what you are currently getting from the PtDialog). Paste your script into the Script window of the PIO. Change the FSActLayer to draw a rectangle using the LineLength and BoxWidth parameters. You have to place as letter p (pLineLength, pBoxWidth) in front so that the compiler recognizes them as parameters and not just variables. Don't start any of your variable names with the letter p unless they are parameters. Remove the PtDialog and change that to read the parameters you entered. it SHOULD be EASY. It won't be, but you will learn a lot and it will be far easier than starting from scratch and trying to do this in Marionette since you already have VS that works. Ask again when you get stuck. Welcome to the club. 😉 Quote Link to comment
Raph Posted November 18, 2022 Author Share Posted November 18, 2022 Hi Pat, No, it's not easy... but very interesting and formative. Can I really ask you the questions that come to me during this process? I begin with the first one, you say: "Go to the Plug-in Manager and create a new Rectangle Object. You will by default get two parameters, LineLength and BoxWidth. These will automatically change when you reshape the "rectangle" of the object. Use them to draw the outline of the room." ok i have make that, but I have a blank file with no text in it! Is this normal? see image in attached file Thank you for your wishes (welcome) Regards Raph Quote Link to comment
Pat Stanford Posted November 18, 2022 Share Posted November 18, 2022 Start with setting the Langue: to Vectorscript and then paste in the script that you have running. Then from there start making the changes necessary to make it work as a PIO. Change the PtDialog to just setting the W1 and H1 variables to the height and width parameters you set. Change the HD1:=FSActLayer to instead use the LineLength and BoxWidth parameters to draw the rectangle and set HD1 to a handle to the rectangle you draw. If you are still stuck, let me know and I can make you a version that works. Maybe I will do it as a video for others as well. Quote Link to comment
Raph Posted November 19, 2022 Author Share Posted November 19, 2022 (edited) Hi Pat, Thanks for your answers and your time It was very helpful. I think I'm not too far from success. missing me 1-2 hour Attached is a picture of my Marionette network. It gives an idea of what I want to be able to set up. I have adapted the code a bit as I thought My code below: # November 11, 2022 # ©2022 Patrick Stanford pat@coviana.com # Licensed under the GNU Lesser General Public License # No Warranty Expressed of Implied. Use at your own risk. # Very limited testing. # Tiles a rectangular area with a set of rectangles # the beginning of each row is the "cutoff" from the # end of the row above. # Modified by Raph_N November 17, 2022 # added two parameters: # 1. a deduction in the remaining panel of the thickness of the blade (ThBl:4mm) # 2. a minimum dimension at the end of a line that allows to decide if the line starts with a new panel (WmaxSold:200mm) @Marionette.NodeDefinition class Params(metaclass=Marionette.OrderedClass): # APPEARANCE # Name this = Marionette.Node("TileRects_OSB") this.SetDescription( 'This node performs a tiles a rectangular area with a set of rectangles the beginning of each row is the "cutoff" from the end of the row above.') # Input Ports in0 = Marionette.PortIn(vs.Handle(0), 'hObj1') in0.SetDescription('A list of objects to be operated on (blanks)') inWf = Marionette.PortIn(1, 'n_Wfloor') inWf.SetDescription('A dimension of the width (Pannels)') inHf = Marionette.PortIn(1, 'n_Hfloor') inHf.SetDescription('A dimension of the height (Pannels)') inWp = Marionette.PortIn(1, 'n_Wpan') inWp.SetDescription('A dimension of the width (Pannels)') inHp = Marionette.PortIn(1, 'n_Hpan') inHp.SetDescription('A dimension of the height (Pannels)') inThBl = Marionette.PortIn(1, 'nBlade') inThBl.SetDescription('A dimension with a thickness of a (Blade)') # Output Ports out = Marionette.PortOut('hObj') out.SetDescription('The resulting objects') # BEHAVIOR # this.SetLinksObjects() # this.SetListAbsorb() def RunNode(self): # inputs FX2 = self.Params.inWf.value FY2 = self.Params.inHf.value W1 = self.Params.inWp.value H1 = self.Params.inHp.value ThBl = self.Params.inThBl.value # script in0 = vs.FSActLayer() if in0 is not None: FX1 = 0 FY1 = 0 CurrentX = FX1 CurrentY = FY1 SheetEndX = FX1 + W1 SheetEndY = FY1 + H1 RemainderX = 0 RemainderY = 0 NP = 1 NProw = ((FX2-FX1)/W1) WmaxSold = ((FX2-FX1)-(NProw*W1)) Done = False NewLine = False vs.Rect(FX1, FY1, FX2, FY2) while not Done: RemainderX2 = W1 - WmaxSold NProw = vs.Trunc(((FX2 - FX1) - (W1 - WmaxSold)) / W1) WmaxSold = ((FX2 - FX1) - (NProw * W1) - RemainderX2) while SheetEndX <= FX2: if NP != 1 and WmaxSold<200: RemainderX = 0 NewLine = True else: Number = ((CurrentY - H1), FY2) ThisY = max(Number) vs.Rect(CurrentX, CurrentY, CurrentX + W1, ThisY) CurrentX = CurrentX + W1 SheetEndX = CurrentX + W1 NP = NP + 1 RemainderX = W1 - (FX2 - CurrentX) - ThBl vs.Rect(CurrentX, CurrentY, FX2, ThisY) if SheetEndX != FX2 and SheetEndY != FY2: if NewLine == True: CurrentX = FX1 + W1 NewLine = False NProw = Trunc((FX2 - FX1) / W1) WmaxSold = ((FX2 - FX1) - (NProw * W1)) else: CurrentX = FX1 + RemainderX Number = ((CurrentY - H1), FY2) CurrentY = max(Number) CurrentX = FX1 + RemainderX SheetEndY = max(Number) vs.Rect(FX1, CurrentY, CurrentX, SheetEndY) SheetEndX = CurrentX + W1 NP = NP + 1 else: Done = True # outputs TileRectsFloor_v2.vwx Edited November 19, 2022 by Raph 1 Quote Link to comment
Raph Posted November 21, 2022 Author Share Posted November 21, 2022 Hello, Well.... I have made good progress I'm just blocked to finish the Y loop by changing the parameter "max" in "min" the loop runs without end, I think since VW crashes. Does anyone have an idea? Pat? I know that Python is not your favorite field but you have more experience than me😉 I tried to put a "if" SheetEndX > FX2 Do SheetEndX = FX2 but nothing works!!! file and printscreen attached Kind regards TileRectsFloor_v5.vwx Quote Link to comment
Raph Posted November 22, 2022 Author Share Posted November 22, 2022 Hello, OK I finished my program🤩 See attached file!!! Thank you Pat for your very valuable help I remain open to any possible improvement Greetings to all TileRects_Symbol.vwx 1 1 Quote Link to comment
Raph Posted November 25, 2022 Author Share Posted November 25, 2022 (edited) Hello, I would still like to export a "worksheet" list of the panels with the number and the dimension. Does anyone have an idea on the functions to use to make this happen? Thanks in advance greetings Raph Edited November 25, 2022 by Raph Quote Link to comment
Pat Stanford Posted November 25, 2022 Share Posted November 25, 2022 As long as this is 2D and the rectangles are perpendicular to the axes, it is pretty easy. Create a worksheet. Right Click in one of the Row Headers (I like to start with Row 3 so there is room above for headers and titles when I need them.). Set it to be a Database Row. Edit the criteria to select only the rectangles you want. Modify your Marionette to put them in a Class or on a Layer or attach a Record so you can separate them out from all the other rectangles in the file. In the database header row ( the one that is just 3, not 3.1, 3.2, etc) column 1 enter a formula of =Width. In column 2 put in a formula of =Height. In column 3 put in a formula of =Count Recalculate the worksheet. You should now have a list of all the rectangles with their widths and heights and a count of 1 next to each of them. Click on the black disclosure triangle in the width column and click the SUMmarize check box. You should now have a much smaller list that shows a single subrow for everything with the same width and the Count column counting the number of pieces with the same width. Repeat on checking the SUMmarize box in the Height column. Your list should expand and now you will have two rows for every width, one for the ones in the main body, and one for the trimmed bottom row rectangles. Ask again if this is not clear enough. HTH. Quote Link to comment
Thomas W Posted November 25, 2022 Share Posted November 25, 2022 Bonjour, Je n'ai pas encore essayé Marionette mais ça donne envie! Vous trouverez ci-joint un exemple de tableau qui récupère la largeur, la hauteur, la teinte et des options possibles de hauteur et de largeur. La somme des options pose un problème vu qu'elle viennent d'une liste déroulante mais après un export excel cela fonctionne. Fonctionne avec des rectangles, une base de données et une étiquette de données qui est liée au rectangle. Peut être que ça peut vous aider pour réaliser votre tableau. Fichier exemple en pièce jointe. Bonne journée! Hello, I haven't tried Marionette yet but it makes me want to! Attached is an example table that retrieves the width, height, tint and possible height and width options. The sum of the options poses a problem since it comes from a drop-down list but after an excel export it works. Works with rectangles, a database, and a data label that is bound to the rectangle. Maybe it can help you to make your table. Sample file attached. Have a good day! Thomas Exemple simple panneau de façade et tableau v2.vwx Quote Link to comment
Raph Posted November 25, 2022 Author Share Posted November 25, 2022 Thanks for your quick feedback My idea was to create it with vs.python code Pat an idea? create a table in VS? 😁 1 Quote Link to comment
Pat Stanford Posted November 25, 2022 Share Posted November 25, 2022 Yes, it can be done. This link is to the most recent version of a script I posted that makes a worksheet via script. You probably want to read through the entire thread. And this one shows how to set a row to be a database and set the criteria. Take a look at the line that sets the variable FORMULA and then how that is used. 1 1 Quote Link to comment
Raph Posted November 28, 2022 Author Share Posted November 28, 2022 Hi Pat, Hi Everybody, Here is the last parametric symbol that generates a worksheet Thanks Pat for your help As usual, if anyone has any suggestions for improvements, we'd love to hear from you greetings Raph TileRects_Symbol_WS.vwx 2 Quote Link to comment
DomC Posted November 29, 2022 Share Posted November 29, 2022 (edited) Great Guys How cool is That! I will for sure use it soon to lay floor-panels soon in my basement hobby-room. Don't forget to share in the gallery. Edited November 29, 2022 by DomC 1 Quote Link to comment
Recommended Posts
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.