-
Posts
641 -
Joined
-
Last visited
Content Type
Profiles
Forums
Events
Articles
Marionette
Store
Posts posted by DomC
-
-
Took a quick look
I think, it is not the Marionette Network or the code inside the Marionette that produces the crash from my sight. It is the PIO which crashes by handling it in the script. I can see a crash by duplicate and move with alt-key and by edit the script. No crash with a Version, that not contains the PIO you insert in the script. That indicates, that the PIO you use inside script is crashing. Also not crash in 2024 (but maybe still an issue).
Some Points that i saw:
1. Insert PIO then delete after
The strategy is, to insert a PIO which has the same size as the segment of a polygon. If a Bool is 0 then delete the PIO. So you insert the PIO, set Bool to 0 and then after insertion delete PIO. Also i see, that the text you insert is not deleted in that case what would result in async text and PIO.
Better would be not insert Bool is 0. Also then you have to filter the rest of the network also.
2. Writing to the record "Korpusmöbel - Objektinfo"
Which is a read-only record in my opinion. Or minimum will be overwritten by the PIO itself. Maybe it works but still something risky.
3. Crash
No idea what exactly produces a crash. Definitely no crash without PIO if i deactivate the symbol node. Also no crash, running the network not as a PIO Node just as a Network. The used cabined PIO may not be designed to exist inside Marionettes or other PIOs. That's maybe the source of the crashes. However i would 2024 give a try and skip 2023. Because there i can see no crash.
-
1
-
-
It seems to be possible also by deleting with the selection state. So far it seems to be the best option.
vs.DeleteObjs()
-
vs.DoMenuTextByName('Clear',0)
OK, this would delete the Original PIO. But i am not feeling good by using a DoMenuText in this situation.
-
Hello
I have a PIO with Button-Widgets. One of them should convert the PIO in another PIO and back. Is it possible to delete the PIO with the Button at all?
elif theButton == cButton6: if replace_object(): vs.DSelectAll() vs.SetSelect(GlobalValues.pio_handle) vs.AlertInform('Press delete after action to delete original object', '','') #This would work so far vs.DelObject(GlobalValues.pio_handle) #This wont work (and if it would work i think it may result in a crash?)
-
Hi
Did not looked into your code details because i keep that theme for a time from my brane.
I think the general we can take an objects entity matrix and set that entity matrix to another object. With Set- and get Entity Matrix. This is not really hard. What was always the point is, that having some points in 3D which defines a plane transferring to an entity matrix wen need for the SetEntityMatrix Script command.
What i have so far in that direction:
1. A way to have 3 points and gets an VW entity matrix of 3 points. Somehow my code os spreaded over a bigger code so i do now know if exactly that works in your example. code and functions i needed there code snippeds.
I would say the code here took me several hours of figuring out that easy looking code. But i think at the end it maybe needs just a few lines if it was optimated. Also the vs.Vec2Ang() solves a lot. It would be hard to find out in which quadrant the plane is oriented and the direction of the points etc..
Like i told, not looked yet into your code. This snipped worked here for getting rotation matrix from 3 points. Not sure, if it works in all directions and for vertical planes in every situation. I always thought there must be a general solution for that. And there is but on the other side we must fit it to the vw SetEntity matrix also the plane matrix are different from the rotation matrix.
2. Getting a centroid and a plane. With that we can project points on that plane (not a vw plane, a plane defined by the normal matrix of the custom getPlane Node in that example). Here:
At one point everything is turning into hard work. But we still have fun 🙂 -
Initially the issue is, that putting geometry into the profile group it is centered to the mid point (Even if you move profile before you create path it does not matter, it will be centered independent from its coordinates, thats why we have to move AFTER creation of path extrude). I am not sure anymore, why i used that locus point to get offset of the profile group(if you know the offset of the reference point to the middle of the profile you do now use locus point you can just move the profile by a known value). Reseting path extrude after moving the profile inside, is definitely still necessary in my opinion.
-
1
-
1
-
-
Hello
Sorry kinda occupied at the moment. The vs.ResetObject(x) will do reset at the end of a script i guess. So when it it duplicated it duplicates the unreseted state of the object and converting to mesh deletets the path position which is not reseted.
What you can do, is a "hard reset" by using
vs.SetObjectVariableBoolean(x, 1167, True)
instead of vs.ResetObject(x)
As far as i notice by changing the reset node it would keep the mesh in position. Hope that works for you-
1
-
-
Agreed, class organization is still a crucial aspect, often posing challenges for users. Not all offices and projects require the same workflows. In the realm of Big Projects, the class structure may deviate from the standard, evolving over several years, and copying from old drawings might not be a significant concern.
On the whole, it appears to be the right approach to employ a management tool that seamlessly connects various elements. This functionality seems to be already present in Vectorworks and is working quite effectively but always open for future improvements. We have the Ebenen/Klassen-Manager tool and/or the class/layer mapping feature. These tools allow users to define class mappings and save/load them for use in different projects. While mapping classes during object pasting might be functional, it does not align perfectly with the broader workflow requirements addressed by the aforementioned features, such as inserting resources and importing geometry.
Try thinking one step forward i can imagine, that something like a overall document style (Not just for classes, mybe also central saved values as project data etc. - i think styles are really a great working concept) could be worth thinking about in this direction.
However:Admittedly, I have not insight to "smart paste" feature in action, so my assumptions may be incorrect. It appears that this command executes a standard "paste" action initially, followed by a dialog that enables the user to modify the class of the pasted elements within a selected class, while also offering the option to delete newly created classes if undesired. Due to potential reliance on legacy commands or an inaccessible included file, the functionality may no longer be operational. Generally, scripts can be normally easily adapted for new versions, even when some functions are outdated. But the script does not seems to be available anymore?
I use a similar script for records, i invested some time to fit to the class requirements. The script saves the substitution dictionary on disk, a feature seemingly unsupported by the old function. This script appears to encompass approximately 30% of the original "smart paste" pascal-script and its associated included file. It suggests that a fundamental element may be missing or that the dialog code in my example is more concise due to the dynamic creation of the object without the use of dialog builder components.
''' DomC 26.12.2023 Disclaimer: This script comes with no warranty or official support services (excluding the Community Forum). Use at your own risk. It is recommended to test with a copy of your original documents. Known Issues: - Some content within symbols or PIOs may lead to unexpected results. - Pasted resources, including colors, symbols, line types, dimension standards, etc., are not translated; only classes are affected. - The script performs an all-encompassing paste action, resulting in a change to the pastes, still selected elements after pasting. - Pasting inside annotations, Symbols, PIO Graphic Containers etc. may result in unexpected results. - If a bug occours no pasted objects should be missed. Just maybe in wrong classes or maybe unwanted classes are deleted at the worst case. - This script is proof of concept and not matured by testing in real environment The script manages settings using a JSON file (smart_paste_settings.json). It provides functions to read and write a dictionary of class translations from and to the JSON file. Class Management: It defines functions to get a list of existing class names in the document and find the difference between two lists of classes. After a Paste operation (vs.DoMenuTextByName('Paste', 0)), it identifies new classes. Dialog Interface: If the debug_dialog flag is set to True, a predefined list of new classes is used for testing the dialog. The script creates a dialog that allows the user to interactively manage class translations. The dialog includes options to paste all into the active class, view classes present in the dictionary, substitute classes in the dictionary but not in the drawing, and handle new classes not yet in the dictionary. Dialog Functionality: The dialog provides an organized interface with columns for the original class name, the last translated class, and a dropdown menu for selecting a new class. It includes color-coding for clarity (blue for in the dictionary, green for in the drawing but not in the dictionary, red for not in the dictionary). Users can save their settings using a checkbox. Undo Mechanism: If the dialog is canceled, the script performs an Undo operation (vs.DoMenuTextByName('Undo', 0)). Post-Dialog Processing: After the dialog, if saving settings is enabled, it updates the JSON file with the new class translations. It handles the class translations for pasted objects, updating their classes according to the user's selections. It identifies classes to delete based on the difference between new classes and those in the class dictionary. Overall, the script provides a user-friendly interface for managing class translations, making it easier to handle classes in a Vectorworks document. ''' import vs import os import json # Set the folder and file paths for the settings settings_folder = os.path.join(vs.GetFolderPath(-15), 'smart_paste') settings_file = os.path.join(settings_folder, 'smart_paste_settings.json') # Set debug mode (True for debugging, False otherwise) debug_dialog = False # Get the active class name active_class_name = vs.ActiveClass() # Function to read settings from a JSON file def read_settings(settings_folder, settings_file): # Create the settings folder if it doesn't exist if not os.path.isfile(settings_folder): os.makedirs(settings_folder, exist_ok=True) try: # Read the class dictionary from the settings file with open(settings_file, 'r', encoding='utf-8') as file: class_dictionary = json.load(file) except: # If an error occurs during reading, set an empty dictionary class_dictionary = {} return class_dictionary # Function to write settings to a JSON file def write_settings(settings_folder, settings_file, class_dictionary): # Create the settings folder if it doesn't exist if not os.path.isfile(settings_folder): os.makedirs(settings_folder, exist_ok=True) try: with open(settings_file, 'w', encoding='utf-8') as file: file.write(json.dumps(class_dictionary, ensure_ascii=False, indent=2)) except: # If an error occurs during writing, display an alert dialog vs.AlrtDialog('Error writing setting File') # Function to get all class names in the document def get_class_names(): out_classes = [] num_class = vs.ClassNum() for i in range(1, num_class + 1): cname = vs.ClassList(i) out_classes.append(cname) return out_classes # Function to find the difference between two lists of classes def class_diff(old_list, new_list): return [c_new for c_new in new_list if c_new not in old_list] # Read existing translation from the settings file class_dictionary = read_settings(settings_folder, settings_file) # Get existing class names in the document existing_classes = get_class_names() # Perform a Paste operation vs.DoMenuTextByName('Paste', 0) # Get existing class names after pasting actual_classes = get_class_names() # Get new classes after pasting by finding the difference new_classes = class_diff(existing_classes, actual_classes) # class list for testing dialog if debug_dialog: new_classes = [ "Lorem ipsum", "Unknown Class1", "Dolor sit am", "Consectetur", "Adipiscing", "ClassNotInDictionary", "Elit", "Sed do eiusm", "Unknown Class2", "Tempor", "Incididunt ut", "Labore et", "Dolore magna", "Aliqua", "Ut enim ad", "Minim veniam", "Quis nostrud", "Exercitation", "Ullamco", "Laboris", "Duis aute", "Reprehenderit", "Voluptate", "Velit esse", "Cillum", "Excepteur sint", "Proident", "Culpa qui", "Aenean commodo", "Massa quis", "Enim justo", "Rhoncus ut", "Integer", "Tincidunt", "Cras dapibus", "Vivamus", "Elementum", "Aenean vulpu", "Aliquam lorem", "Phasellus", "Fermentum", "Viverra quis" ] items_left = [] items_middle = [] items_right = [] translate_list = [] saved_settings = {} def dialog_settings(): # Control IDs kOK = 1 kCancel = 2 # UIAskForStringsToReplace def CreateDialog(): # Alignment constants # Create the main dialog layout dialog = vs.CreateLayout( 'Class Substitute', False, 'OK', 'Cancel', True) # Create controls and set their positions vs.CreatePushButton(dialog, 5, 'Paste all in active class.') vs.SetFirstLayoutItem(dialog, 5) vs.CreateStaticText(dialog, 6, 'new_class present in dictionary', 30) vs.SetStaticTextColorN(dialog, 6, 0) vs.SetBelowItem(dialog, 5, 6, 0, 1) vs.CreateStaticText(dialog, 7, 'substitute class in dictionary but not in drawing', 40) vs.SetStaticTextColorN(dialog, 7, 4) vs.SetRightItem(dialog, 6, 7, 0, 0) vs.CreateStaticText(dialog, 8, 'new class not yet in dictionary', 30) vs.SetStaticTextColorN(dialog, 8, 2) vs.SetRightItem(dialog, 7, 8, 0, 0) vs.CreateStaticText(dialog, 9, 'Existing class manually attached', 30) vs.SetStaticTextColorN(dialog, 9, 3) vs.SetRightItem(dialog, 8, 9, 0, 0) # Script Scope Variable initialization max_lines = 20 num_groups = int(len(new_classes) / max_lines + 1) kgroup_list = [] start_id = item_id = 12 class_counter = 0 kgroup_list = [] for i in range(num_groups): # Create a group for each set of classes item_counter = 1 group_name = 'List ' + str(i) vs.CreateGroupBox(dialog, item_id, group_name, False) kgroup_list.append(item_id) last_item = item_id item_id += 1 for c_index in range(class_counter, len(new_classes)): c_new = new_classes[c_index] if class_counter >= max_lines * (i + 1): break # Check if the class is in the dictionary and set text styles accordingly in_dict = False in_dict_butnot_drawing = False if c_new in class_dictionary: in_dict = True last_choice = class_dictionary[c_new] if last_choice not in existing_classes: in_dict_butnot_drawing = True text_style = 2 # 2blue, 3green, 4red, 0black if in_dict: text_style = 0 if in_dict_butnot_drawing: text_style = 4 else: class_dictionary.update({c_new: active_class_name}) text_style = 2 last_choice = class_dictionary[c_new] # Create static texts for class names and last choices vs.CreateStaticText(dialog, item_id, c_new, 65) vs.SetStaticTextColorN(dialog, item_id, text_style) if item_id == kgroup_list[-1] + 1: vs.SetFirstGroupItem(dialog, kgroup_list[-1], item_id) else: vs.SetBelowItem(dialog, last_item - 2, item_id, 0, 1) last_item = item_id item_id += 1 vs.CreateStaticText(dialog, item_id, last_choice, 65) vs.SetStaticTextColorN(dialog, item_id, text_style) vs.SetRightItem(dialog, last_item, item_id, 0, 0) last_item = item_id item_id += 1 vs.CreateClassPullDownMenu(dialog, item_id, 25) vs.SetStaticTextColorN(dialog, item_id, text_style) vs.SetRightItem(dialog, last_item, item_id, 0, 0) last_item = item_id item_id += 1 item_counter += 3 class_counter += 1 item_counter += 1 # Create a tab control for better organization vs.CreateTabControl(dialog, 10) vs.SetBelowItem(dialog, 6, 10, 0, 5) for id in kgroup_list: vs.CreateTabPane(dialog, 10, id) # Create a checkbox for saving settings last_item = item_id item_id += 1 vs.CreateCheckBox(dialog, item_id, 'Save Settings') saved_settings['id_save'] = item_id vs.SetBelowItem(dialog, 10, item_id, 0, 2) return dialog # Dialog handler function for dialog interactions def DialogHandler(item, data): if item == 12255: # Enter Dialog pass if item == 5: # Update middle column with the active class name for all classes for id_middle in items_middle: vs.SetItemText(dialog, id_middle, active_class_name) vs.SetStaticTextColorN(dialog, id_middle, 3) class_dictionary[vs.GetItemText( dialog, id_middle - 1)] = active_class_name if item in items_right: # Update the right column with the selected class name item_text = vs.GetItemText(dialog, item) vs.SetItemText(dialog, item - 1, item_text) vs.SetStaticTextColorN(dialog, item - 1, 3) if item_text not in existing_classes: vs.SetStaticTextColorN(dialog, item - 1, 4) class_dictionary[vs.GetItemText(dialog, item - 2)] = item_text if item == kOK: # Save settings if the checkbox is selected saved_settings['save'] = vs.GetBooleanItem( dialog, saved_settings['id_save']) # Store translation information in a list for id_left, id_middle, id_right in zip(items_left, items_middle, items_right): c_old = vs.GetItemText(dialog, id_left) c_new = vs.GetItemText(dialog, id_middle) c_last = vs.GetItemText(dialog, id_right) translate_list.append([c_old, c_new, c_last]) return kOK # Initialize variables and run the dialog result = False dialog = CreateDialog() if vs.RunLayoutDialogN(dialog, DialogHandler, True) == kOK: result = True return result result = True if len(new_classes) > 0: result = dialog_settings() if result: # Check if saving settings is enabled if saved_settings['save']: # Write updated settings to the settings file write_settings(settings_folder, settings_file, class_dictionary) # Initialize a list to store pasted objects pasted_objs = [] # Function to add handles to the list def add_handle(h): pasted_objs.append(h) # Get the active layer and its name lh = vs.ActLayer() ln = vs.GetLName(lh) # Define criteria for selecting objects based on the active layer name c = "(INSYMBOL & INOBJECT & NOTINDLVP & NOTINREFDLVP & ((L='ldummy') & (SEL=TRUE)))" c = c.replace('ldummy', ln) # Use ForEachObject to collect handles of selected objects vs.ForEachObject(add_handle, c) # Loop through the pasted objects and update their classes for obj in pasted_objs: old_class = vs.GetClass(obj) new_class = class_dictionary.get(old_class, 'None') vs.SetClass(obj, new_class) # Identify classes to delete classes_to_delete = [] for class_n in new_classes: if class_n not in class_dictionary.values(): classes_to_delete.append(class_n) # Delete identified classes for class_name in classes_to_delete: vs.DelClass(class_name) if not result: vs.DoMenuTextByName('Undo', 0)
For testing purposes this Marionette can be helpful to train the dictionary.
Not really tested in real-application. @matteoluigi you see potential to take over the existing script?
Test Classes.vwx-
2
-
-
Update:
After Working a little more in this environment and Drawing some Modells. I see a little better the lag in user-interaction. Not slow but the little lag, that would let us loos a game or missing the string of a guitar. I short: Nothing for Vectorworks Artists ...
Also i see, that some (loved) tools (Ähnliches Aktivieren) and menu commands (Edit Workspace works but not Exit and save) wont work. And I am sure, some further issues i will see. Menu looks strange, seperators looks like empty lines in menu commands.
Issues see with
- Tool Ähnliches Aktivieren
- Callout Tool
- Auto Dimension
- Elevation Benchmark
- Measure Angle
- Grid Axis
- Eye Dropper
- Parallel Tool
Just too many tools do not work it looks ...
Promising at the first look, the second look is disapointing but still better, than i thought but for me no alternative to a native Windows System. 😢 -
I think there is no difference between VMWare or Native ARM System. Vectorworks run in "compatibility - Mode" on ARM Windows. except in VMWare or parallels it is just slower. From my sight, VMWare seems to play in one league higher than parallels.
Emulating Software somehow does hurt my hart but if i really look at my Solution:
1. Money was spent on a very nice and powerfull M3 max (How i love that machine ...)
2. Running the Emulation thing is a sacrilege but in fact: I can run A Windows system with an startet Vectorworks in 20 Seconds! by just pausing the Virtual machine and saving the state:
3. Speed and lags are comparable to a Medium Windows System which is 3 Years old. Still i need much less power to work on that system
4. Additionally the hope, that update of Windows and native ARM Software will even improve the situation
If i look at the facts in that moment i will not buy a new pc for some time and i think i will practice this "sacrilege" workflow.-
1
-
-
Hi Marcel
Thank you very much for responce. So far my experience, that it was able to install VW with an alternative Windows Image (Win 11 ARM). After starting VW Mentioned, that some vlb was not able to load. (Cinerender)
After That VW works quiet smooth and fix in 2D, but in 3D nothing visible. Like you mentioned. Also no wireframe model.
After Deactivated the Parallels Display driver, the 3D Shaded view is visible but it is very slow. Also a bigger modell crash.
Next Test with VM Ware Fusion. Test-Version. I only have two CPU cores. I hope this is because of free Test Version.
After Installing Windows 11 with the same iso image i was able to install VW. With VM Ware Fusion it was able to install something like VMWare Tools. This installing Drivers also Display Drivers. After Restart i have a Graphic Adapter Named VMWare SVGA. Then I start VW. It Installation and startup of VW is slower than on parallels. But on Parallels I had 12 CPU Cores and on VWMare Fusion . Only two. After Shut Down the virtual Machine i can set up more cores
It seems to be good enough for testing, Support but not for really working or offering as a Training Computer for Customers. Additionally Cinema 4D do not run at all. But Shades View is OK.
Edit:
After giving the virtual Machine more than 4GB RAM, it works better 🙂
But Still generating the 3D Takes more time and the double emulation (Mac Silikon > Windows ARM > Win 11 ARM > Winx86 VW) seems to be incompatible to the VW Render-System. -
Hi
I try to install a Windows Version on Parallels on my m3 for special Support- and Training cases.
After all i found out, Parallels 19 needs a Windows 11 ARM Version. And on a Windows ARM Version, the Installer of Vectorworks 2024 will not start. Somebody have experience with that constellation?Thanks
-
"C:\\Temp\\Output.csv" would work also
I would strongly recommend, always create path strings with the path module. So it is as proof as it can be and this works also cross-platform:
import os path = os.path.join('C:', 'Temp', 'Output.csv') # or even more propper path = os.path.join('C', os.sep, 'Temp', 'Output.csv')
-
2
-
-
I would say maybe a rookie error:
#allowed >> produces no errors caching is off vs.SetPref(412, True) # turn off caching #don't do that >> seems to breaks the vs modul or ignore newer methods vs.SetPref(412, False) # turn off caching #allowed >> produces no errors caching is on #vs.SetPref(412, True) # turn off caching
-
1
-
-
Must be specific an issue of my vso 🤔
I will STF (Search Till Found) -
Hello
I have a Vectorscript tool (not Event driven 2024). This tool rund a python module. The tool is working so far.
code of the tool
PROCEDURE ClickCallback; VAR x1, y1 : REAL; path : STRING; BEGIN SetCursor(LgCrossC); GetPt(x1, y1); PythonExecute('import dev.tool.mod.poly2PIO'); END; RUN( ClickCallback );
the module poly2PIO runs this code:import vs import os #vs.SetPref(412, True) #turn off caching #vs.Message(str(dir(vs))) with open(os.path.expanduser('~') +'/file_vst.txt', "w", encoding='utf-8') as f: f.write('\r'.join(dir(vs))) # error here isOnLine undefined method isOnLine = vs.PtOnLine((0,0), (-10, 0), (10, 0), 0.00001)
everything and also vs.PtOnLine() is working. If i use that tool.
But then, if i run run another vso (Event Enabled path object) it seems that the vst does not have the same vs-function anymore as before.
Also if i use a standard vso (Script Based like the Rolling Stairs) the vs class in my vst do not contains the same methods anymore.
import vs #from datetime import datetime import json import math import copy #import uuid import os import base64 import time #import urllib.request import code.common.controler as controler #vs.SetPref(412, False) # turn off caching with open(os.path.expanduser('~') +'/file_vso.txt', "w", encoding='utf-8') as f: f.write('\r'.join(dir(vs)))
The functions in the vst does not work anymore. Also other vst's have the same issues now.The special thin i do is, that i run a pascal script and call a python after i click in the drawing. For further debug i write a text file with dir(vs) which lists all methods of the vs class.
If i then compare the two files, i can see, that the dump written from file_vst.txt has much less methods available (left) as the file dumped from the vso?
Somebody knows if this is a normal limitation or if it is worth for further diving in?
I think not many devs wrapps a pascal around a python script so maybe this is a normal limitation that the methods freezed on a specific version or it is just a bug?
It looks some-like, that methods after 2014 are not included now for my vst.
Anybody knows what could going on?
Here a screenshot from the method list compared with diff Merge
-
-
Marionette is a Programming-Tool. In such tools wer are in a place to have the force to produce wonderful artwork or unwanted behaviors (crashes?) and comparative we are mostly alone with our artworks. And thanksfully there are forums like this other people can help for bringing those projects to success.
I took a look a the Marionette Control-Point and agree, there is some space for improvement:
1. Fixing Axis
I think @Gregi wantet to fix one axis. This is not possible because the position of the control-point comes from the Mouse not from a value inside the script. This value is just a default value. To change the control point by script itself is theoretically possible to manipulate the Record of the Marionette Node where the position of the point is stored but it would be very hard (Because also the position of the PIO is involved). So this is not a bug it works the way the feature is designed.
2. Moving 3D Point in Standard View.
If I am in a standard view (front right etc.). Lets say from right and I move the point in z-Direction, the x value from the point snaps on the working plane and the x-value gets 0. Which can maybe produces issues in the script inside the PlugIn. So working plane should be used or unwanted values have to be intercepted inside the script (which is always the most costly part). So if the script crash because the width of the pio change to 0 it is not a bug in the code of the 3D modification point. It is just an unhandled error. Error can be handled on different places. In shoft:
OK, I can see, that the reshape behaviour of this modi-point can be improved and i will report this as an enhancement Request.
3. Position of the 3D Point outside of PIO geometry.
If the Modification Point is the most outside object in a PlugIn. And not geometry is there, the position of the Point somehow is calculated wrong relatively to the object. So in our test with Extrudes etc. it always works as expected. But If the extrude is smaller than the bbox of the modipoint and the 0-point it somehow Fails.
I think, this is definitely a bug. I will report.
4. Position of the 3D Point with layer elevationI think this is already known but I try to give it an impact.
Generally, there are not much additional layers of error-handling between marionette and the Script Engine. I think the more "idiot-proof" something is made the weaker it is. Not 100% the truth (It could be possible to have both). But this is the way I am still pleased even if my script crashes 😁 -
This may also help
-
OK, the part of the code which I will not paste is the part how you update your certificates by the script on mac computers to make python accept them to communicate over TLS (SSL) (https instead of http).
caution should be exercised. -
The forum allows me not to paste some code ... I think maybe for security reasons.
Or your testing api request:
import urllib.request import json api_url = "https://jsonplaceholder.typicode.com/todos/1" result_string = '' with urllib.request.urlopen(api_url) as f: result = json.loads(f.read().decode('utf-8')) vs.AlrtDialog(str(result))
An other real example with a http request url, if you can't get https to work
import urllib.request import json import math #dezimalgrad in minuten und Sekunden umwandeln (copy paste aus dem Netz) def deg_to_dms(deg, type='lat'): deg = float(deg) decimals, number = math.modf(deg) d = int(number) m = int(decimals * 60) s = (deg - d - m / 60) * 3600.00 compass = { 'lat': ('N','S'), 'lon': ('E','W') } compass_str = compass[type][0 if d >= 0 else 1] return '{}º{}\'{:.2f}"{}'.format(abs(d), abs(m), abs(s), compass_str) h = vs.FSActLayer() x = 2600000 y = 1200000 z = 500 #Nimmt Position von aktiviertem Hilspunkt, Objekt oder Symbol sonst Bern Sternwarte als Vorgabewert if h != vs.Handle(0): x,y,z = vs.GetLocus3D(h) #vs.AlrtDialog(str(vs.GeogCoordToVWN(x, y))) vs.AlrtDialog(str(vs.VWCoordToGeog(x, y))) xPt, yPt, zPt = vs.PtDialog3D('LV95 Koordikante zu WGS84', x, y, z) #Abfragestring auf dem Geportal direkt im Internet url = "http://geodesy.geo.admin.ch/reframe/lv95towgs84?easting="+str(xPt)+"&northing="+str(yPt)+"&altitude="+str(zPt)+"&format=json" result_string = '' with urllib.request.urlopen(url) as f: result = json.loads(f.read().decode('utf-8')) #Antwort vom Geoportal interpretieren und umwandeln in json result_string = str(result['easting']) + '\r' + str(result['northing']) + '\r' + str(result['altitude'])+'\r\r'\ 'Grad: ' result_string += '\r' result_string += 'Grad Minuten Sekunden: \r' + deg_to_dms(result['easting'], 'lat') +' ' + deg_to_dms(result['easting'], 'lon') vs.AlrtDialog(str(result_string))
-
On 8/14/2023 at 9:46 PM, Samuel Derenboim said:
additional libraries
Maybe not necessarely. urllib is a standard library and also should do the job.
Give a usable feedback or your request:
-
Oh, this is an old code and not very nice one. Without testing:
1. The vs.GetType should replaced by:vs.GetTypeN(res)
2. The node returns not the Symbol Name. That means the node itself insert the Symbol. In fact it looks, like the output just returns the last inserted symbol. Which means the node should insert the symbols in the number of rows and should do the job but not returning the resulting symbol handles. With that node, you can't use the output useful disconnect symbol node and print debug node. -
Agree with Letti
I would vote for the smart solution using the function node without wrapping.
Problem with MAC OS Sonoma 14.5
in General Discussion
Posted · Edited by DomC
Hello

I got a new MacBook Pro m3 end last year. I have sonoma 14.3. After setup my new system i had a short time of very big frustration because the performance was not as i excpected. Slow and epic lags (4 seconds or more and juddery).Also other things worked laggy like text editor or Filemaker. But there i am not so sensible.
I think those was lags maybe another user could would take as "normal" and ignore it but i compared to my 2018 intel mac it was slower. On the internal Monitor everything was fast very fast and smooth. Also with a new user (which is often the workflow to test if it is something related to settings of the system) I found the option "screens uses different spaces" (which is translated from my german version. Do not know, if this is the exact name of the option in english too) which was turned off. After switching it on (which does make not difference for me to work) it is the best performance i ever dreamed of and very stable. Maybe can you look at that option @Dagny?
I fellow just updated his intel Mac on 14.5 and have issues. The other fellows with a Apple silicon not issues after updating on 14.5
So personally i will stay on 14.3 till i can take the risk of something do not work anymore.