michaelk Posted December 7, 2023 Share Posted December 7, 2023 24 minutes ago, Jesse Cogswell said: @michaelk I noticed in your screenshot that the two columns UUID and Parent UUID are visible. These are supposed to be hidden (have a column width of 0), did you expand the columns or is that how it presents on Mac? I'm asking because this plug-in will also use a hidden column to conceal the record name for each plug-in object so that it instead presents the localized name. If the Record Name column is visible when you run this, let me know and I'll change up how the programming works a little bit. I really hesitate to tell you this, but…. The slight offset in the column headers in the header row and in the body between Object Type and # in drawing that you see in Windows is more offset in Mac. I can see the R in Record. This is just going to make me go back over all your other menu commands and try to move columns around. Quote Link to comment
michaelk Posted December 7, 2023 Share Posted December 7, 2023 I don't think you should change it. Anyone who is capable of installing a 3rd party tool and cares enough to make sure everything is in the right class is advanced enough to handle seeing non localized record names. 2 Quote Link to comment
grant_PD Posted December 8, 2023 Author Share Posted December 8, 2023 @Jesse Cogswell My first run w/ your plug in was really cool thank you! Is there a way to force all the objects to take the class attributes as well? Aside from not putting things in the right class, sometimes people just override the class attributes from the attributes panel. Quote Link to comment
Jesse Cogswell Posted December 8, 2023 Share Posted December 8, 2023 I've added this ability, but I did notice a fun bug when it comes to Callouts. The script technically works but the new attributes won't show up on the callout until you use the Attribute Palette to change something. None of the usual tricks to force a reset work, changing the Callout's layer, changing a parameter, or moving the object around. If you change the Callout's class after the fact it will take on the attributes of the new class but I could not get it to work within a single run of the script. I know you probably want this to work on Callouts since they're probably one of your most mis-classed objects, but there doesn't seem to be a solution with a script at the moment. Even running the command twice, once to set attributes by class and again to set the new class, didn't work. This is true at least for VW2019, 2023, and 2024 on Windows. It might work properly on Mac. Callout in the None class with no By Class attributes: Running the command: After running the command, the only attribute that "stuck" is the fill pattern: Changing parameters, layer, and even the note contents has no effect: Selecting the note and using the Attribute Palette "Make All Attributes By Class" button: This seems to be a bug with the Callout tool itself. I tried a simple script that would set the pen color of any selected object to magenta and it works fine on everything except Callouts. Neat. Anyhow, updated plug-in is attached. Save it over the existing one in your User Folder and restart Vectorworks. Reset Plug-in Obj Classes.vsm Quote Link to comment
Pat Stanford Posted December 8, 2023 Share Posted December 8, 2023 27 minutes ago, Jesse Cogswell said: None of the usual tricks to force a reset work, changing the Callout's layer, changing a parameter, or moving the object around. If you change the Callout's class after the fact it will take on the attributes of the new class but I could not get it to work within a single run of the script. Have you tried the Reset All Plug-in Object command from the Tools:Utilities menu? That should make them reset. And if you are only doing it occasionally after running the Classing PIO, then the delay should be tolerable. Quote Link to comment
Jesse Cogswell Posted December 8, 2023 Share Posted December 8, 2023 2 hours ago, Pat Stanford said: Have you tried the Reset All Plug-in Object command from the Tools:Utilities menu? That should make them reset. And if you are only doing it occasionally after running the Classing PIO, then the delay should be tolerable. Just tried it in both VW2019 and VW2024, no change on the Callout object. I'm assuming that the menu command just runs on ResetObject on every object in the drawing (something along the lines of ForEachObject(ResetObject,(INSYMBOL & INVIEWPORT & (ALL)));), so it has the same effect as my script since it contains a ResetObject command as part of the execution. The test that I just did looked like this: Initial Setup After running the script: After running Tools - Utilities - Reset All Plug-ins: No change. That test script looks like this: SetPenFore(FSActLayer,65535,0,65535); SetPenBack(FSActLayer,65535,0,65535); ResetObject(FSActLayer); ReDrawAll; Quote Link to comment
michaelk Posted December 8, 2023 Share Posted December 8, 2023 Callouts are not normal. Here's a script that changes a text object to a callout. You would think that to create a callout you just CreateCustomObject('Callout',…. Then write some data to the record and Bob's your uncle. Nope. Take a look at how attributes are handled inside of what looks like comments. PROCEDURE Test; VAR hCallout,hText,Waldo : HANDLE; tempHandle, objectHandle, textHandle:HANDLE; objectName:STRING; index:INTEGER; s1 : DYNARRAY[] of CHAR; fakeName : STRING; objType : INTEGER; xx,yy,zz : REAL; BEGIN; Locus(0,0); Waldo := LNewObj; hText := PrevSObj(Waldo); DelObject(Waldo); HCenter(hText,xx,yy); fakeName := Date(2,1); SetName(hText,fakeName); objType := ObjectType(N = fakeName); IF objType = 10 THEN BEGIN {AlrtDialog(CONCAT('Objecty Type: ',objtype));} s1 := GetText(hText); {AlrtDialog(s1);} tempHandle := CreateCustomObject('Callout',0",0",#0.0000000000000d); objectHandle := LNewObj; SetDropShadowData(objectHandle, 0,0.003937,0.001969,#315.0000000000d,75,0,0,0); EnableDropShadow(objectHandle, FALSE); objectHandle := LNewObj; {SetObjectVariableBoolean(objectHandle, 1160, FALSE);} Record(LNewObj,'Callout'); SetRField(LNewObj,'Callout','Link To Database','False'); SetRField(LNewObj,'Callout','Place As Keynote','False'); SetRField(LNewObj,'Callout','Keynote Prefix',''); SetRField(LNewObj,'Callout','Keynote Suffix',''); SetRField(LNewObj,'Callout','BubbWidth','2"'); SetRField(LNewObj,'Callout','Vertical Placement','Auto'); SetRField(LNewObj,'Callout','Orientation','Auto'); SetRField(LNewObj,'Callout','Left','False'); SetRField(LNewObj,'Callout','Bubble Style','None'); SetRField(LNewObj,'Callout','Radius Factor','0.046850393700787"'); SetRField(LNewObj,'Callout','Margin','0.046850393700787"'); SetRField(LNewObj,'Callout','Bubble Shadow','False'); SetRField(LNewObj,'Callout','Shoulder','1''0.000000000000002"'); SetRField(LNewObj,'Callout','Leader Type','Straight'); SetRField(LNewObj,'Callout','Leader Style','Line'); SetRField(LNewObj,'Callout','LineLength','7''2.331410057273573"'); SetRField(LNewObj,'Callout','__ShowDialog','False'); SetRField(LNewObj,'Callout','Rise','0.19"'); SetRField(LNewObj,'Callout','Text',S1); SetRField(LNewObj,'Callout','DNE','Solid Arrow\1\-1'); SetRField(LNewObj,'Callout','TextFont','Arial'); SetRField(LNewObj,'Callout','TextSize','203.200000'); SetRField(LNewObj,'Callout','TextStyle','Plain'); SetRField(LNewObj,'Callout','ControlPoint01X','-1''7.526018289463835"'); SetRField(LNewObj,'Callout','ControlPoint01Y','-1''11.734217624645211"'); SetRField(LNewObj,'Callout','ControlPoint02X','-4''7.239175964666458"'); SetRField(LNewObj,'Callout','ControlPoint02Y','-1''7.431487403991564"'); SetRField(LNewObj,'Callout','ControlPoint03X','1''0.000000000000002"'); SetRField(LNewObj,'Callout','ControlPoint03Y','0"'); SetRField(LNewObj,'Callout','ControlPoint04X','9''0.046850393700751"'); SetRField(LNewObj,'Callout','ControlPoint04Y','0"'); SetRField(LNewObj,'Callout','__dbName',''); SetRField(LNewObj,'Callout','__dbUUID',''); SetRField(LNewObj,'Callout','__NoteUUID','{FFA5C43C-FC3C-40A2-AC80-C4D561E385E2}'); SetRField(LNewObj,'Callout','__NoteDescrip','This is a callout'); SetRField(LNewObj,'Callout','__KeynoteNumber','0'); SetRField(LNewObj,'Callout','__OldPlaceAs','False'); SetRField(LNewObj,'Callout','__OldBubbWidth','2"'); SetRField(LNewObj,'Callout','__OldShoulder','1''0.000000000000002"'); SetRField(LNewObj,'Callout','__OldLeaderStyle',''); SetRField(LNewObj,'Callout','__IsFlipped','False'); SetRField(LNewObj,'Callout','__isNew','False'); SetRField(LNewObj,'Callout','__version','2800'); SetRField(LNewObj,'Callout','__markerCode','1;0;15;0.125000;0.000000;2;2.000000;'); SetRField(LNewObj,'Callout','Arrow Style',''); SetRField(LNewObj,'Callout','Marker Symbol',''); SetRField(LNewObj,'Callout','Marker Scale Factor','0.039370078740157"'); SetRField(LNewObj,'Callout','MarkerAng','15'); SetRField(LNewObj,'Callout','Marker Weight','1'); SetRField(LNewObj,'Callout','__OldCtrlPt03X','304.8'); SetRField(LNewObj,'Callout','__OldCtrlPt03Y','0'); SetRField(LNewObj,'Callout','__OldCtrlPt04X','2744.39'); SetRField(LNewObj,'Callout','__OldCtrlPt04Y','0'); SetRField(LNewObj,'Callout','Keynote Legend','Default Legend'); SetRField(LNewObj,'Callout','__OldKeynoteLegend','Default Legend'); SetRField(LNewObj,'Callout','Leader Radius','0"'); SetRField(LNewObj,'Callout','OldText','This is a callout'); SetRField(LNewObj,'Callout','__IsUseReletivePath','False'); SetRField(LNewObj,'Callout','__DBReletivePath',''); SetRField(LNewObj,'Callout','Text Angle','0.00°'); SetRField(LNewObj,'Callout','Rotate Text','False'); SetRField(LNewObj,'Callout','__OldTextAngle','0.00°'); SetRField(LNewObj,'Callout','__BubbleShadowPenColor','-3'); SetRField(LNewObj,'Callout','__BubbleShadowFillColor','-3'); SetRField(LNewObj,'Callout','HorizontalTextAlignment','Center'); SetRField(LNewObj,'Callout','New Bubble Style V20','None'); SetRField(LNewObj,'Callout','New Vertical Placement','Auto'); SetRField(LNewObj,'Callout','Draw Extended Shoulder','False'); SetRField(LNewObj,'Callout','Text Style Ref','0'); SetRField(LNewObj,'Callout','Text Spacing Index','2'); SetRField(LNewObj,'Callout','Text Spacing Value','0'); SetRField(LNewObj,'Callout','Leader Angle','-150.00°'); SetRField(LNewObj,'Callout','__ObjectRotationAngle','0'); SetRField(LNewObj,'Callout','__DrawTwoSoulders','False'); SetRField(LNewObj,'Callout','__LeadingLeaderPointX','0'); SetRField(LNewObj,'Callout','__LeadingLeaderPointY','0'); SetRField(LNewObj,'Callout','__SecondaryLeaderPointX','2028.6094375'); SetRField(LNewObj,'Callout','__SecondaryLeaderPointY','0'); SetRField(LNewObj,'Callout','ControlPoint05X','5''7.866513287401574"'); SetRField(LNewObj,'Callout','ControlPoint05Y','0"'); SetRField(LNewObj,'Callout','__OldSecondaryShoulderPointX','1723.8094375'); SetRField(LNewObj,'Callout','__OldSecondaryShoulderPointY','0'); SetRField(LNewObj,'Callout','__LeaderLinesData','{ "handles" : [ { "index" : 1, "firstPtIndex" : 1, "lastPtIndex" : 4, "leaderType" : 0 } ] }'); SetRField(LNewObj,'Callout','__CustomPointsData',Concat('{ "handles" : [ { "index" : 1, "type" : 1, "x" : 0, ',' "y" : 0, "bezier" : false }, { "index" : 2, "typ','e" : 2, "x" : -1899.0359340549093758, "y" : -1096.40890772','73740713, "bezier" : false }, { "index" : 3, "type"',' : 4, "x" : -495.96086455238139479, "y" : -602.84912766598','836242, "bezier" : true }, { "index" : 4, "type" : ','5, "x" : -1403.0750695025280947, "y" : -493.55978006138570','89, "bezier" : true } ] }')); SetRField(LNewObj,'Callout','Max Leader Lines','2'); SetRField(LNewObj,'Callout','__ActiveSubObject','4'); SetRField(LNewObj,'Callout','__SubObjectDataAttributes',Concat('{ "handles" : [ { "index" : 1, "objectType" : 1, "hi','ghlightingObject" : false, "objectPenStyle" : 1, "objectCl','assPenStyle" : 1, "objectPenPatternIndex" : 2, "objectPenP','atternForeColor" : 257, "objectPenPatternBackColor" : 256, ',' "objectPenColor" : 257, "objectPenLineType" : 2, "objectP','enLineTypeName" : "", "objectThickness" : 2, "objectMarker','Style" : 0, "objectMarkernAngle" : 15, "objectMarkerdSize"',' : 0.125, "objectMarkerdWidth" : 0, "objectMarkernThicknes','sBasis" : 2, "objectMarkerdThickness" : 2, "objectFillOpac','ity" : 100, "objectOpacity" : 100, "fillColorByClass" : fa','lse, "penColorByClass" : false, "thicknessByClass" : false',', "markerByClass" : false, "fillOpacityByClass" : false, ',' "opacityByClass" : false }, { "index" : 2, "objectTy','pe" : 2, "highlightingObject" : false, "objectPenStyle" : ','1, "objectClassPenStyle" : 1, "objectPenPatternIndex" : 2,',' "objectPenPatternForeColor" : 257, "objectPenPatternBackC','olor" : 256, "objectPenColor" : 257, "objectPenLineType" :',' 2, "objectPenLineTypeName" : "", "objectThickness" : 2, ',' "objectMarkerStyle" : 0, "objectMarkernAngle" : 15, "obj','ectMarkerdSize" : 0.125, "objectMarkerdWidth" : 0, "object','MarkernThicknessBasis" : 2, "objectMarkerdThickness" : 2, ','"objectFillOpacity" : 100, "objectOpacity" : 100, "fillCol','orByClass" : false, "penColorByClass" : false, "thicknessB','yClass" : false, "markerByClass" : false, "fillOpacityByCl','ass" : false, "opacityByClass" : false }, { "index" : ','3, "objectType" : 3, "highlightingObject" : false, "obj','ectPenStyle" : 1, "objectClassPenStyle" : 1, "objectPenPat','ternIndex" : 2, "objectPenPatternForeColor" : 257, "object','PenPatternBackColor" : 256, "objectPenColor" : 257, "objec','tPenLineType" : 2, "objectPenLineTypeName" : "", "objectTh','ickness" : 2, "objectMarkerStyle" : 0, "objectMarkernAngle','" : 15, "objectMarkerdSize" : 0.125, "objectMarkerdWidth" ',': 0, "objectMarkernThicknessBasis" : 2, "objectMarkerdThic','kness" : 2, "objectFillOpacity" : 100, "objectOpacity" : 1','00, "fillColorByClass" : false, "penColorByClass" : false,',' "thicknessByClass" : false, "markerByClass" : false, "','fillOpacityByClass" : false, "opacityByClass" : false }, ','{ "index" : 4, "objectType" : 4, "highlightingObject" :',' false, "objectPenStyle" : 1, "objectClassPenStyle" : 1, ',' "objectPenPatternIndex" : 2, "objectPenPatternForeColor" : ','257, "objectPenPatternBackColor" : 256, "objectPenColor" :',' 257, "objectPenLineType" : 2, "objectPenLineTypeName" : "','", "objectThickness" : 2, "objectMarkerStyle" : 0, "obj','ectMarkernAngle" : 15, "objectMarkerdSize" : 0.125, "objec','tMarkerdWidth" : 0, "objectMarkernThicknessBasis" : 2, "ob','jectMarkerdThickness" : 2, "objectFillOpacity" : 100, "obj','ectOpacity" : 100, "fillColorByClass" : false, "penColorBy','Class" : false, "thicknessByClass" : false, "markerByClass','" : false, "fillOpacityByClass" : false, "opacityByClass" ',': false } ] }')); SetRField(LNewObj,'Callout','__KeynotesListUpdate','False'); SetRField(LNewObj,'Callout','TextSizePagePoints','12.000000'); SetRField(LNewObj,'Callout','Auto Fit Bubble Width','True'); SetRField(LNewObj,'Callout','Max Bubble Width','2"'); SetRField(LNewObj,'Callout','Keynote Identifier','0'); SetRField(LNewObj,'Callout','__OldKeynoteIdentifier','0'); SetRField(LNewObj,'Callout','__IsNoteUpdated','True'); SetRField(LNewObj,'Callout','__UseFirst42','True'); ResetObject(LNewObj); HMove(LNewObj,xx,yy); DelObject(hText); DelName(fakeName); END ELSE BEGIN SysBeep; AlrtDialog('No Text Object Selected'); END; END; RUN(Test); 1 Quote Link to comment
Jesse Cogswell Posted December 9, 2023 Share Posted December 9, 2023 @michaelk Yeah...I'm not touching that. How did you get that information? Is it documented anywhere? Quote Link to comment
michaelk Posted December 9, 2023 Share Posted December 9, 2023 Nope. Unless there's something in the SDK. I did it unsuccessfully for a while just using the usuall methods. Then I tried exporting a file with nothing but a callout as a VS and got that nonsense. Turns out that nonsense is totally necessary to create a new callout from scratch if you want the leader line to work. Without the nonsense you can create a callout, but nothing you do in the OIP after creation will create a leader line. It looks like the nonsense controls the attributes. Which I assume is why you can't do it the normal way with your menu command. There's a hidden field in the Callout record called __SubObjectDataAttributes which is a big concat. Somehow I think THAT is controlling the attributes. Quote Link to comment
grant_PD Posted December 10, 2023 Author Share Posted December 10, 2023 @michaelk so what is required to make this work? Does vw have to recreate the callout from scratch? Are we doomed to never being able to control one of the most commonly used drawing tools? Quote Link to comment
michaelk Posted December 17, 2023 Share Posted December 17, 2023 @grant_PD For the foreseeable future, yes. I think there is even more going on here than we can see. Graphic elements of the callout object can be controlled from a Keynote Legend and from Text Styles. That's in addition to callouts being attached to databases. I think the callout object is a much more complicated object than it appears to be. It wouldn't be that difficult (famous last words of everyone writing vectorscript) to make a callout replacement plug-in object that could never be a keyed note and could never attach to a database. There may already be some out there floating around. (I always need to check every idea I have for a script or plug-in to make sure @Sam Jones hasn't already written it.) 1 Quote Link to comment
Sam Jones Posted December 18, 2023 Share Posted December 18, 2023 (edited) On 12/17/2023 at 9:30 AM, michaelk said: (I always need to check every idea I have for a script or plug-in to make sure @Sam Jones hasn't already written it.) You and @Jesse Cogswell are usually ahead of me unless it was really simple and deals with the Lighting Device. If that is the case, I wrote it 20 years ago. Edited December 18, 2023 by Sam Jones add a word Quote Link to comment
line-weight Posted December 18, 2023 Share Posted December 18, 2023 Callouts really are a pain. For years I had the habit of hardly ever inserting them "fresh", instead copy-pasting from somewhere else, because it was easier than pinning down exactly what controls their attributes. They also have a confusing behaviour in the way they exist in page/world units. I think you can set defaults in page units but then they convert to world units when you place them - something like that. And copying them between viewports of different scales messes them up. 2 Quote Link to comment
grant_PD Posted December 18, 2023 Author Share Posted December 18, 2023 Kind of depressing to hear all of this about the callout. I guess I'll submit a wishlist request to overhaul it. Thank you all for the cool other tips and tools. 2 Quote Link to comment
geo44rey Posted December 18, 2023 Share Posted December 18, 2023 Ok, so I got this far, which indicates that Classing and Visibility in Viewports is a constant time-suck, and it would be SUPER HELPFUL to have a tool built into the UI to search and replace and destroy classes with one click or whatever. The reduced-scope 2024 standard classing seems like a good logical step to less classes in general (yay), even if it means all of our symbols and classes are now out of date and duplicated, and everyone is confused as to which is the "right one" to use now. Obviously I barely know what I am talking about, but my impression from 5 or so years ago is that Marionette was a way to do this (even with "callouts", etc???) 1 Quote Link to comment
Jesse Cogswell Posted December 20, 2023 Share Posted December 20, 2023 @geo44rey I wrote a plug-in a couple of weeks ago to help consolidate classes. It essentially remaps all objects of one class into another class with an option to delete the original class. It's along the same lines as deleting a class and reassigning objects using that class to a different class, but the plug-in lets you do it for multiple classes at once. The original post can be found here: As for Marionette, there might technically be a way to recreate my script in Marionette but I could see it being a huge pain. Marionette is essentially a visual way of writing scripts but I find the implementation to be clunky and slow, and have several problems with the execution. And I really don't think Marionette has a solution for the Callouts problem since it's typically much more limited than the Vectorscript / Python scripting. Consolidate Classes.vsm 4 Quote Link to comment
geo44rey Posted January 3 Share Posted January 3 @Jesse Cogswell SOUNDS PERFECT. THANK YOU, Thank you. Quote Link to comment
geo44rey Posted January 3 Share Posted January 3 OK, so I need some help (sorry) about how I can get VW 2024 to install a .vsm script (i.e. Jesse's above). Thanks! Quote Link to comment
michaelk Posted January 3 Share Posted January 3 VW>Preferences>User Folders>Reveal in Finder Find the Plug-ins folder. Put the .vsm file in that folder. (I find it very useful to make the user folder a favorites in Finder) Restart VW. Tools>Workspace>Edit Current Workspace (or choose Workspaces… and create a new workspace based on a copy of the current one) in the Workspace Editor > Menus Tab On the left will be groups of menu commands. Jesse's are usually in a group called JNC. Find the menu command you want On the right are a list of all the menu commands in that workspace in VW. Open up the target menu group and Drag the new menu command on the left to the desired location on the right. Hit OK. As a bonus, you could just grab the JNC heading on the left and drag it to the right. You will now have a JNC menu. I'm currently using 9 JNC menu commands! 1 Quote Link to comment
Jesse Cogswell Posted March 22 Share Posted March 22 I have some good news! After doing some research, I have figured out how to handle Callouts, so the Reset Plug-in Obj Classes command posted above will now be able to force all Callouts to take attributes By Class. Updated command is attached here and has been tested in VW2019, VW2022, VW2023, and VW2024. For those playing along at home who want a little more background on how the Callout object works, the answer is surprisingly simple. The Callout object stores the visual attribute data for each of its components in a record field called __SubObjectDataAttributes as a JSON string. Using Python, you can parse the JSON into a Dictionary and then change the necessary key values before re-encoding back to a string and sending it back to the Callout object. The Python script is very simple and looks something like this (when acting on a selected Callout): import vs import json h = vs.FSActLayer() s = vs.GetRField(h,"Callout","__SubObjectDataAttributes") data = json.loads(s) for k in data["handles"]: k["penColorByClass"] = True k["thicknessByClass"] = True k["markerByClass"] = True k["opacityByClass"] = True s = json.dumps(data) vs.SetRField(h,"Callout","__SubObjectDataAttributes",s) vs.SetFillColorByClass(h) vs.SetFPatByClass(h) vs.SetLSByClass(h) vs.SetLWByClass(h) vs.SetMarkerByClass(h) vs.SetOpacityByClass(h) vs.SetPenColorByClass(h) vs.ResetObject(h) I should mention that the resulting JSON Dictionary in this case will have a single key, called "handles" whose value will be a List containing a nested Dictionary for each component of the Callout with the necessary information. I should also mention that the implementation that Vectorworks uses for the string data contains a lot of tab characters within the data between the keys and values. The script above will strip those tabs out, but as far as I can tell, doing so doesn't affect VW or the Callouts in any negative way and changing any attribute of an affected Callout will reset the formatting. Showing the __SubObjectDataAttributes in a Worksheet, left is a Callout before running the command, right is after running the command: I should also mention that you really have to use Python when handling the __SubObjectDataAttributes since the string length will be longer than the 2047 character cap that Vectorscript seems to have on strings. Reset Plug-in Obj Classes.vsm 3 Quote Link to comment
Pat Stanford Posted March 23 Share Posted March 23 For a VS version try using a DynArray of Char instead of a string. It will give you the same functionality, but allow your up to 32,XXX chars. 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.