Jump to content


  • Content Count

  • Joined

  • Last visited

Everything posted by Paolo

  1. Thank you @Brian(J) for your prompt reply. Here's a file with just three rows of converted text text with stroke test.svg When the program finds a "text" type in the selection, it shows this dialog: If you include strokes, they will be 1pt with the same color as fill. Thank you to get in touch with Shaper. I have browsed their site and downloaded their Illustrator template to compare with mine. No differences (they use SVG 1.1 as in my previous tests), rather my code is more simple and clean, since I want it to be widely compatible. Hope they give some tracks, though.
  2. Thank you @Brian(J) for your test. Objects come grouped, this is necessary due to the transformation (scale(1,-1)) needed to flip the Y axis that is reversed in Vectorworks. This is needed, there is no other way to flip Y, as far as I know. About the truncated circle, this is a very special case where you cannot get the same (partially stroke in Vectorworks) circle in SVG unless you draw a truncated circle (really is a polyline) for the fill and an arc for the stroke. About the letters, they should be polylines, maybe the problem is that they have no stroke and your program does not recognise it? This should not a be a problem. From a graphical point it is correct that there is no stroke (as they appear in Vectorworks!) but if you need strokes, anyway, I'll do in way to propose stroke as option. I have also changed the SVG version <svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" since I use the attribute vector-effect="non-scaling-stroke" that is available from this version (1.2 Tiny). However this attribute is already present in most SVG implementations, but it may be not the case of Shaper, that does not recognise the code. I have tried with an online validator this new version and it passes the test correctly. This attribute is used to get the the visually balanced line weight independently from view zoom, but it does not alter the real weight (that is, if you open the exported file in Illustrator, you get the same line weight that in Vectorworks), so I can simply decide to omit this attribute, if it 'd be a problem. I have uploaded the updated version of the two tests, please, give them a try, if you can. geometry test.svg lines test.svg
  3. Here's a couple of SVG produced with the Export selection to SVG command. Feel free to test it in your workflow, I'd like to have your feedback before to release. geometry test.svg lines test.svg and here's a part of the produced SVG code: geometry text.svg <?xml version="1.0" encoding="utf-8"?> <!-- Generator: SVG Export Plug-In © Paolo Marcuccetti 2020. SVG Version: 20201128) --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="Level 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0" width="595.2px" height="841.68px" viewBox="0 0 595.2 841.68" xml:space="preserve"> <g transform="scale(28.346456692913385 -28.346456692913385) translate(10.498666666666667 -14.8463)"> <rect x="-8.498666666666667" y="7.995558273480356" width="4.850741726519645" height="4.850741726519644" fill="rgb(204, 204, 204)" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-width="2.016" stroke="rgb(221, 9, 7)" /> <rect x="-2.425370863259822" y="7.995558273480356" width="4.850741726519645" height="4.850741726519644" rx="1.0" ry="1.0" fill="rgb(204, 204, 204)" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-width="2.016" stroke="rgb(221, 9, 7)" /> <path fill="rgb(204, 204, 204)" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-width="2.016" stroke="rgb(221, 9, 7)" d= "M8.498666666666667 11.425550642086936 7.077917308753603 12.8463 5.068674298060086 12.8463 3.6479249401470226 11.425550642086938 3.6479249401470226 9.416307631393419 5.068674298060084 7.995558273480356 7.077917308753605 7.995558273480356 8.498666666666665 9.416307631393417 Z "/> <circle cx="-5.924629136740178" cy="3.570187410220533" r="2.4253708632598228" fill="rgb(204, 204, 204)" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-width="2.016" stroke="rgb(221, 9, 7)" /> <path fill="rgb(204, 204, 204)" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-width="2.016" stroke="rgb(221, 9, 7)" d= "M2.4253708632598228 2.746332281802734 -0.6412188019392882 2.746332281802734 -0.6412188019392879 4.394042538638335 2.4253708632598228 4.394042538638335 2.4253708632598228 5.995558273480356 -2.425370863259822 5.995558273480356 -2.4253708632598214 1.1448165469607112 2.4253708632598228 1.144816546960712 Z "/> <path fill="rgb(204, 204, 204)" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-width="2.016" stroke="rgb(221, 9, 7)" fill-rule="evenodd" d= "M5.078295803406844 2.5751874102205337 5.078295803406844 4.565187410220534 7.068295803406845 4.565187410220534 7.068295803406845 2.5751874102205337 Z M8.498666666666665 3.5701874102205333 A2.425370863259822 2.425370863259822 10313.240312354817 0 1 3.6479249401470213 3.5701874102205347 L3.6479249401470213 3.5701874102205333 A2.425370863259822 2.425370863259822 10313.240312354817 0 1 8.498666666666665 3.5701874102205324 Z "/> <line x1="-8.498666666666669" y1="-12.206080187949256" x2="8.498666666666669" y2="-12.206080187949256" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-width="1.2959999999999998" stroke="rgb(119, 119, 119)" /> <line x1="-8.498666666666669" y1="-12.8463" x2="8.498666666666669" y2="-12.8463" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-width="1.44" stroke="rgb(119, 119, 119)" /> </g> </svg>
  4. The plugin is now in an advanced testing phase (it is ready, almost). I just want it to be perfect, more or less 😉 Please follow this post to know the release announce. As promised in my previous reply, I have added the support for texts. Texts that are included in the selection to export, are sent to the SVG as paths. No need for the user to convert them into polylines. All is done inside the plugin process.
  5. @Brian(J), I know, of course, just forgotten to mention it in the post (edited!) Convert a text to path and you get a polyline (or a group of polylines). Ungroup, if needed, and you are ready to export in SVG. This is just the first version. I will add the text support either as direct text tag in the SVG or advising the user about the conversion to path (copying and converting it on the fly, leaving the actual text untouched).
  6. Hello, I am happy to show you my next coming plugin (menu command) to export SVG out of Vectorworks. Here's a short presentation with a video:
  7. Hello, I am happy to show you my next coming plugin (menu command) to export SVG out of Vectorworks. Here's a short presentation with a video:
  8. Hello, my new plugin to get SVG files out of Vectorworks is in beta testing. Let me know if you are interested, as soon as I am ready the plugin will be placed on my Gumroad® page, at a reasonable price. With this menu command you'll be able to export your Vectorworks elements (such as polylines, polygons, rects, arcs etc.) objects to an SVG file suitable for CNC machines. All you have to do is select the objects to export and select the menu "Export selection to SVG", then choose a file name and click OK. The program will produce the correct SVG code to replicate the same selected object in the SVG viewbox determined by the Vectorworks active layer drawing size. Object are exported relatively to the active layer scale, so, if you need them for CNC purposes, better set the layer scale to 1:1 before exporting. export SVG demo movie.mov What Export selection to SVG can do: The plugin CAN export the following Vectorworks objects: Lines Rects Rounded rects Arcs / circles Ellipses Polygons Polylines (also with holes) The plugin CANNOT export all the other types that are not included in the above types such as: Groups, Symbols, Plugin objects (unless converted in the above types) 3D objects Texts (unless converted to polylines) Quotes Images Attributes: The SVG produced will preserve the following object attributes: Solid fills Solid strokes Fill and stroke colors The plugin does not consider dashes, gradients, textures etc..
  9. I have found a way, it works, but has some inaccuracy (due to the PointAlongPoly precision), but I can leave with it. Of course, if there is a better solution it will welcome! import math def angleBetweenPoints(p1, p2): #given 2 point coordinates it retrieves the angle of the line passing between them orientation = None if p1[0]==p2[0]: if p1[1] <= p2[1]: orientation = 90 else: orientation = 270 if p1[1]==p2[1]: if p1[0] <= p2[0]: orientation = 0 else: orientation = 180 if (p1[0]!=p2[0]) and (p1[1]!=p2[1]): if p1[0]<p2[0]: quadrant = 0 else: quadrant = 180 orientation = quadrant+vs.Rad2Deg(vs.ArcTan((p1[1]-p2[1])/(p1[0]-p2[0]))) return orientation def tangentAtIndex(h, index, resolution): minDist = 1e308 #a very large number initially tangent = None ptVt, vertexType, arcRadius = vs.GetPolylineVertex(h, index) ht = vs.ConvertToPolygon(h, resolution) #cycle searching min distance for i in range(1, vs.GetVertNum(ht)+1): pi = vs.GetPolyPt(ht, i) dist = vs.Distance(ptVt[0], ptVt[1], pi[0], pi[1]) if dist < minDist: minDist = dist if (i > 1) and (i+1 < vs.GetVertNum(ht)): pt1 = vs.GetPolyPt(ht, i-1) pt3 = vs.GetPolyPt(ht, i+1) c = vs.ThreePtCenter(pt1, pi, pt3) tangent = angleBetweenPoints(c, pi)+90 else: if i == 1: #angle between 1 and 2 pt1 = vs.GetPolyPt(ht, 1) pt2 = vs.GetPolyPt(ht, 2) tangent = angleBetweenPoints(pt1, pt2) if i == vs.GetVertNum(ht): #angle between latest and latest-1 pt1 = vs.GetPolyPt(ht, vs.GetVertNum(ht)) pt2 = vs.GetPolyPt(ht, vs.GetVertNum(ht)-1) tangent = angleBetweenPoints(pt1, pt2) vs.DelObject(ht) return tangent #test a selected polyline h = vs.FSActLayer() for i in range(1, vs.GetVertNum(h)+1): t = tangentAtIndex(h, i, 512) p, vertexType, arcRadius = vs.GetPolylineVertex(h, i) vs.Locus(p[0], p[1]) vs.MoveTo(p[0]-1*math.cos(vs.Deg2Rad(t)), p[1]-1*math.sin(vs.Deg2Rad(t))) vs.LineTo(p[0]+1*math.cos(vs.Deg2Rad(t)), p[1]+1*math.sin(vs.Deg2Rad(t)))
  10. I am working on a script that converts Vectorworks polylines into SVG paths and I have managed to "translate" everything except for the cubic splines vertexes. I know that a cubic splines vertex control point is equivalent to two bezier vertexes, simply crossing the tangent lines, see figure. The problem is: how I determine the tangent exactly in a polyline vertex? The only way seems to go with this one… def vs.PointAlongPoly(h, dist): return (BOOLEAN, pt, tangent) …but I cannot know what distance the control point has. Furthermore, testing this (and the similar PointAlongPolyN), I get inaccurate results placing of the points on the curve. I know (from past experiences) that this function calculates distances on the poly just "polygonizing" the curve, but the conversion resolution is unknown (and not settable). Thank you for the help. Paolo
  11. Hello python experts, I am trying to install the Pillow module (on MacOS, Vectorworks 2021) using the function Marionette.VerifyOrGetLib() as from the following script: PIL = 'https://files.pythonhosted.org/packages/53/7d/c0db10e5f990905aa4bc4f8166414d8a30fb766c1624ced9fe9a43a211d9/Pillow-7.2.0-cp38-cp38-macosx_10_10_x86_64.whl' import Marionette if Marionette.VerifyOrGetLib('PIL', PIL): #vs.Message(PIL) from PIL import Image, ImageChops … This worked in Vectorworks 2020, now I am getting this annoying script error / warning: WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip. Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue. To avoid this problem you can invoke Python with '-m pip' instead of running pip directly. Warning: You are using pip version 20.1.1; however, version 20.2.3 is available. You should consider upgrading … Though the library is correctly installed, is there a way to avoid this error / warning? I have examined the VerifyOrGetLib() function (on MacOS is inside /Applications/Vectorworks 2021 IT/Plug-in/Marionette.vwlibrary/Contents/Resources/Marionette.vwr/Scripts/Marionette.py) As far as I know (I am not a python expert), while on PC this function uses the Vectorworks pip installation, on MacOS, it seems to use the provided system pip that is different (hence the version warning). I do not know the old script wrapper warning means. @tbexon and @K.Lalkovski, any suggestion? Here's the relevant part of the function VerifyOrGetLib() : if sys.platform == 'win32': piploc = 'Python38\Scripts\pip3.exe' pathpip = 'Python38\Scripts' cdpath = os.path.join(appfolder, pathpip) cmdpip = os.path.join(appfolder, piploc) wd = os.getcwd() if os.path.exists(cmd) and os.path.exists(cmdpip): os.chdir(cdpath) ret_code = subprocess.call([cmdpip, 'install', missingLibURL, '-t', cmd ]) if ret_code > 0: vs.AlrtDialog('Module ', missingLib, ' cannot be downloaded.') exit_code = False else: exit_code = True sys.path.append(cmd + '\\') os.chdir(wd) vs.AlrtDialog('Module ', missingLib, ' has been successfully installed.') elif sys.platform == 'darwin': import pip import shlex pos1 = missingLibURL.rfind('/') pos2 = missingLibURL.rfind('whl') downloadedfile = missingLibURL[pos1+1:pos2] +'whl' destination = appuserfldr + downloadedfile command_line = "curl -o " + '\"' + destination + '\"' + " "+ missingLibURL args = shlex.split(command_line) ret_code = subprocess.call(args) if ret_code == 0: sys_executable_orig = sys.executable sys.executable = '/usr/bin/python' ret_code = pip.main(['install', destination,'-q','--target', cmd]) sys.executable = sys_executable_orig if ret_code > 0: vs.AlrtDialog('Module ', missingLib, ' cannot be installed.') exit_code = False else: vs.AlrtDialog('Module ', missingLib, ' has been successfully installed.') exit_code = True else: vs.AlrtDialog('Module ', missingLib, ' cannot be installed.') exit_code = False sys.path.append(cmd+'/')
  12. Thank you all. I think I am going to rewrite this python plugin in Vectorscript since all functions and procedures I need are in Vs. I know I should start to refactor my (Mouldings) plugins in python, but it’s a big work! Paolo
  13. Hello, Is it possible to use a VectorScript function in a python script? I have many procedures and functions (in an include .vss file) written in VectorScript and I would avoid to rewrite them all… There should be the vs.CallDynVSFunction for this, but how to use it? Someone has tried it? Are there examples? Thank you in advance Paolo
  14. Inspired by this post, I have added the full Paramount Wood Moulding catalog to my Mouldings Plugin. It taken just one day to convert all the downloaded dwg files to the proprietary cpf files (with the above mentioned tool Save Profile to File cpf). I did not found downloadable dwg archives for the Fox catalog, @AEChadwick could you give me a link?
  15. Thanks very much to Mr. @MullinRJ and Mr. @PatStanford, the case was been brilliantly solved! Here's the check passage to be sure a folder gets its unique name (paths is the string var to be queried): k := 1; {loop to check if there is already an object named paths or paths is the name of a plugin in the current workspace (conflict!)} {add '-1', '-2', …-'n' to paths until there is no more conflict match.} while ((getObject(paths) <> nil) or HasPlugin(paths, paletteName)) do begin if k = 1 then paths := concat(paths, '-', num2Str(0,k)) else {ho già aggiunto un numero} paths := concat(Copy(paths, 1, len(paths)-len(num2Str(0,k))), num2Str(0,k)); k := k+1; end; nameObject(paths); BeginFolderN(16); … EndFolder;
  16. Maybe this should work: FUNCTION HasPlugin( itemUniversalName :STRING; VAR PaletteName :STRING) : BOOLEAN;
  17. Ok, now that we found the cause, is there a procedure to get a list of the plugins names currently used so to check if a name can be used? The nameList() doesn’t show plugins names, just the objects named in the drawing. And what happens if I create a ‘Xyz’ folder, then, later, I install a ‘Xyz’ plugin? Just curious...
  18. Thank you @PatStanford and @MullinRJfor your help. Siding is actually the name of one plugin in my mouldings package. Is it not allowed to name an object with a name of a plugin? Tomorrow I’ll try with the word ‘Corner’ that is another plugin of the package. We will see... About restarting VW, I had the very same behavior on two different Vectorworks installations, home and office, both with the Mouldings Package installed, VW2020 SP4 Italian version.
  19. To verify @Pat Stanford conjecture, I have made this test: procedure test; var i : integer; h : handle; begin for i := 1 to nameNum do writeln(NameList(i)); h := GetObject('Siding'); if h = nil then {try to create an object and assign it the name 'Siding')} begin rect(0,0,100,100); setName(LNewObj, 'Siding'); {this gives an error!} end; end; run(test); Applied to a new empty document, the result (in the output file), the following: Nessuna Quote Irregolare Tavolozza-1 Script-1 No sign of any "Siding", though the last part of the script… setName(LNewObj, 'Siding'); Issues a script error (name already used!). Also manually naming an object (in the OIP) as 'Siding' is not allowed. Until now there is no a 100% chance that creating a symbol folder with a particular name will not lead to an error, despite all checks and control you can do priorly. "Siding" is a word not allowed, discovered by accident. How many more words like this are there? There is a list of the reserved words? I think I have to live with it!
  20. Hi Pat, the problem is that if you try GetObject('Siding'); it returns Nil, so you can think that 'Siding' is a name free to use, but… nameObject('Siding'); Returns a script error (name is already in use!). So I cannot be sure (AFAIK) if a name I pass to GetObject is really Nil because it either has nothing associated or is a "reserved" word like 'Siding'.
  21. In my Mouldings plugins package I use a file of symbols and symbol folders as a database to be used in the plugin. The database is browsable using a tree control like this. The symbol folders are created starting from an actual folder on the disk and, recursively, for each folder inside it. I use the following commands (inside the recursion cycle): {paths is the name of the actual folder as read from the disk} nameObject(paths); BeginFolderN(16); Unfortunately folders on the disk and symbol folders in Vectorworks do not behave the same. Vectorworks doesn't allow two entities with the same name. For example, two folders can have the same name on the disk as soon as they are in different locations. This cannot happen in Vectorworks, so I have a check to assign a progressive number each time a name already exists. {paths is the name of the actual folder as read from the disk} k := 1; while getObject(paths) <> nil do begin if k = 1 then paths := concat(paths, '-', num2Str(0,k)) else {I have already started the numbering…} paths := concat(Copy(paths, 1, len(paths)-len(num2Str(0,k))), num2Str(0,k)); k := k+1; end; nameObject(paths); BeginFolderN(16); In this way I will have, for example Folder, Folder-1, Folder-2 and so on. The problem is that I found a name ("Siding") that is probably a reserved word! In this case getObject('Siding') returns nil and nameObject('Siding') returns an error message saying that there is already an object with that name. Also Name2Index('Siding') returns 0 (no object associated with that name). This is a contradiction! Is there a way to see if a name is used other than to check for the associated object (that may fail!)? This is the test script if you want to verify the contradiction: procedure test; var h : handle; begin h := getObject('Siding'); if h = nil then message('No object with this name! ', Name2Index('Siding')); nameObject('Siding'); BeginFolderN(16); end; run(test); It shows a script error, here's mine (in Italian) It says that 'Siding' name is already existing, but how can I check in advance if a name exists, avoiding showing the script error? Thank you for the help.
  22. @tbexon, @K.Lalkovski, I know (from a beta tester) that the beta version 2021 bs still has the faulted version of pip3. Do you, @K.Lalkovski, know if this problem is going to be fixed or not?
  23. Thank you @K.Lalkovski, as stated in my previous posts, I report problems from Windows users with 2020 SP4. From my side (2020 SP4 on MacOS) all is working. I will ask them to send me more details on this and post them as soon as i get them.


7150 Riverwood Drive, Columbia, Maryland 21046, USA   |   Contact Us:   410-290-5114


© 2018 Vectorworks, Inc. All Rights Reserved. Vectorworks, Inc. is part of the Nemetschek Group.

  • Create New...