Jump to content

Paolo

Member
  • Posts

    180
  • Joined

  • Last visited

Posts posted by Paolo

  1. 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.

    1128158651_Schermata2020-11-19alle10_31_31.thumb.png.e917e9ebde8f34e039ca4ef8770879bc.png

    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

  2. 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+'/')

     

  3. 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;

     

    • Like 2
  4. 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...

  5. 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.

     

     

  6. 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!

  7. 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'.

  8. 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.

    1703803555_Schermata2020-09-03alle14_47_38.thumb.png.f8f0d885b80687e5e04e1a31e7ebcd07.png


    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)

    940706786_Schermata2020-09-03alle14_52_26.thumb.png.65aa8b0bf15fbc420a69cc447200aeb1.png

     

    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.

  9. Is there someone that can test the marionette node contained in this file (it should install PIL python module in the user folder) on Vectorworks 2020 SP4 on Windows?

     

    Download PIL.vwx

     

    It worked some time ago, it does not anymore.

    Something has changed with the recent SP4 (maybe) and the VerifyOrGetLib() seems to refuse to install python modules.

    I have checked (on Mac) and VerifyOrGetLib() is identical to SP3 version (see the code in the first post).

    The bug should reside in pip3.exe, since the ret_code is 1 (what does it mean?), see code below.

    I have no way to test it by myself, cause I am on Mac (and Mac does not have this problem…)

     

    any help?

     

    @Marissa Farrell, @JBenghiat, @relume

    if sys.platform == 'win32': 
    					piploc = 'Python35\Scripts\pip3.exe'
    					pathpip = 'Python35\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.')

     

  10. I distribute a plugin written in Python that makes use of the PIL module.

    To import the module I use the Marionette function VerifyOrGetLib() as seen in some marionette examples from Marissa Farrell and others.

     

    	if platform == 2: #windows
    		PIL = 'https://pypi.python.org/packages/bb/f7/d644a9a65a25ff0bf43b7f69ce3ef9803742a5d6e438ddfc7e925c007e6c/Pillow-7.1.2-cp35-cp35m-win_amd64.whl#md5=6d62274af5c88c1cfe31c977f7531ed6'
    	else: #Mac
    		PIL = 'https://files.pythonhosted.org/packages/7d/b4/755848342213bcb5a5c570657ca21f20ebc104daf15d7847b08e18b4d2fd/Pillow-7.1.2-cp35-cp35m-macosx_10_10_intel.whl'
    			
    	if Marionette.VerifyOrGetLib('PIL', PIL):

     

    Now I am receiving messages from some Windows users saying the installation fails.

    Unfortunately I am on a Mac and cannot test it directly.

    While the directory Python Externals is correctly created inside the user folder a message is shown saying that the module cannot be downloaded.

    But the above link, if copied directly in a browser, indeed download a 2Mb file (Pillow-7.1.2-cp35-cp35m-win_amd64.whl)

     

    Here's the code of the VerifyOrGetLib() (contained in the Marionette module)

    def VerifyOrGetLib(missingLib, missingLibURL):
    	# try to install user's package
    	exit_code = False
    	appfolder = vs.GetFolderPath(1)
    	appuserfldr = vs.GetFolderPath(12)
    	
    	cmd = 'Python Externals'
    	cmd = appuserfldr + cmd
    	
    	if not os.path.exists(cmd):
    		os.makedirs(cmd)
    	try:	
    		try:
    			importlib.import_module(missingLib)
    			exit_code = True
    		except ImportError:
    			#show dialog here
    			question = 'Python module ' + missingLib + ' is not installed. Would you like to download and install it now?'
    			res = vs. AlertQuestion(question,'', 1,'','','','') 
    			if res == 1 :
    				if sys.platform == 'win32': 
    					piploc = 'Python35\Scripts\pip3.exe'
    					pathpip = 'Python35\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+'/')
    			else:
    				exit_code = False
    	except:
    		pass	
    	return exit_code  

    Is someone experiencing the same problem?

    Any help is wellcome!

    • Like 1
  11. Thank you JBenghiat, just tested and it works!

     

    r, offset, rotationXAngle, rotationYAngle, rotationZAngle = vs.GetEntityMatrix(imageHandle)

    rotationZAngle is the image (imageHandle) rotation value (the same showed in the OIP)

  12. Did you forget to take some measures during your last architectonical survey?

    That's a bummer! But, wait… You've got some pictures? Then Plumb-Bob's got your back!

    Plumb-Bob is a perfect completion for your architectural survey!

    Everything you need is an image (even one taken from your phone), in which four known key points are clearly visible.

     

    Here's what you can do with Plumb-Bob:

     

     

    You can obtain the Plumb-Bob plugin for just €10+ via the Gumroad® platform at my personal page or starting from the plugin dedicated page here below:

    https://fitplot.it/vwplugins/PlumbBobPlugin.html

    • Like 2
  13. Hello all,

    is there a way to get the rotation angle of an image (bitmap) inserted in Vectorworks?

    The angle is clearly shown in the OIP but it seems to be unreachable by code 🤔 

     

    Here's what I tried:

    vs.HAngle(h)

    This returns always 0.

     

    I also searched in the appendix for some documented index to get the angle, but found nothing…

    vs.GetObjectVariableReal(h, index)

     

    Also tried to get it from record fields…

    vs.GetParametricRecord(h)

    but Bitmaps are a native type and not plugin objects, so neither this worked…

     

    Other ideas / suggestions?

  14. Ready, at last!

    Plumb-Bob for Vectorworks is available on the Gumroad® platform at €10+.

     

    You can get it from the official page here:

    https://fitplot.it/vwplugins/PlumbBobPlugin.html

     

    or from my Gumroad® page here:

    https://gumroad.com/pamarcu

     

    Note for Vectorworks italian users:

    This same plugin should be included in the next Vectorworks update (italian version) , under the name Ortofoto.

     

    Hope you enjoy it,

    Paolo

    • Like 1
  15. I am almost ready to release my PlumbBob for Vectorworks version, here's the new Plugin Icon:109625071_icona-plumBob-x-VWuniversal@2x.thumb.png.e7ce0021afa27564c7e4009eb491ec3d.png

    …and a screenshot of the plugin in action:

     

    1991818195_Schermata2020-05-01alle10_34_15.thumb.png.349341716535d794a8d7380a46305545.png

     

    Purpose of the Plugin:

    Starting from a picture, and knowing 4 points on it (for example a window's four corners), it is possible to rectify the picture so that you can take exact measurements of all openings lying on the plan to which the points (window in the example) belong.

    Also the plugin does the same operation on 2D objects traced on the picture (points, lines, polygons etc.)

    Also the plugin is able to do the reverse operation, transporting bitmaps and 2D objects from the rectified plan to the original picture point of view.

     

    While I had way to develop and test it on my Mac version of Vectorworks 2020, I still need someone to try it on Windows.

    This test is needed since the program relies on Pillow, a python library (for image manipulation) that is downloaded and installed (at first run) in the user library of Vectorworks.

    Please, if you are interested in testing PlumbBob (and get it for free, of course), leave me note (mouse over my icon and click ✉️Message).

    I'll provide to send you the plugin and necessary instructions.

     

    Thank you in advance

     

    • Like 1
×
×
  • Create New...