Jump to content

MullinRJ

Member
  • Content Count

    1,264
  • Joined

  • Last visited

Everything posted by MullinRJ

  1. MullinRJ

    Renaming a field in an existing record format?

    Ryan, I don't think you can do it directly. The best I can suggest is to use a brute force approach. 1) create a new record with the fields of the old record and the one renamed as you like. 2) move default values from the old record to the new. 3) go through the file and attach the new record to any object that has the old record attached. 4) move values from the old attached record to the newly attached record. 5) delete the old record format. This should detach all instances in the file, but if you like, remove the old record after you attach and clone the new one. 6) rename the new record to the old record name with SetName(GetObject('NewRecordName'), 'OldRecordName'). 7) turn this code module into a procedure so you can use it again without a lot of grief. Ideally, if you could get a handle to a record field, you could use SetName() on it, but I don't see that as an option in the VS calls. NOTE: If the record is a PIO record, all bets are off. Also, I have no idea how this will affect any worksheet that references the old record. Since the formulae are text based, it may not matter. As with all complex surgeries, try this on a COPY of your file first! Have fun. If you get it to work let me know. I love it when you get to use a bazooka to swat a fly. 🙂 Raymond
  2. MullinRJ

    Century Gothic Vector issue

    Font Suitcases are pretty old. I would definitely look for a newer version of the font. There seem to be quite a few sites on the web that offer free versions of this typeface. Good Luck, Raymond
  3. MullinRJ

    Century Gothic Vector issue

    Hello Patricia, What kind of font is it; Postscript Type 1, TrueType, OpenType, Scalable Vector Graphics, or (hopefully not) Bitmap? Also, how old is the font file? Perhaps a newer version of the Century Gothic type face would alleviate your problem. Raymond
  4. MullinRJ

    Text is in outline

    Christopher, If you ever do figure out how to do this manually, please post back. I'd love to know how it can be done, too. On either platform, you can set these attributes with a script similar to the one I posted earlier that clears them. e.g., DSelectAll; TextFace( [ Shadow, Outline ] ); { sets the Outline and Shadow text styles } It is also possible to cut and paste text between documents that has one or both TextStyle flags set, but that would not affect the application setting, only the object's. However, the EyeDropper tool has a checkbox that "could" transfer those hidden attributes to be part of the text creation default settings. It's a long shot that you would fall into this rabbit hole, but not impossible. Honestly, I think you did it some other way, but I have no idea at the moment how. Again, please post back if you ever figure out how you got there. All the best, Raymond
  5. MullinRJ

    Text is in outline

    Since I'm getting a bunch of thumbs-up on this last post, I'm posting a copy of the Vectorworks Enhancement (VE) request I entered yesterday. Please feel free to comment on anything I missed. Anything relevant, I'll add it to my request. Thanks, Raymond ———————————————————————————— VE-99490: Make UI consistent on MAC and WIN for Text objects [Raymond Mullin] Description: With a text object selected, the OIP on Windows does not show checkboxes for the Outline or Shadow style attributes. Outline and Shadow are attributes that can be assigned on the Mac, but not on the PC. A problem exists where a text object can have the Outline or Shadow attributes applied on the Mac and then saved. The same file opened on a Windows version of VW will not indicate in the OIP these attributes are assigned, even though they still are. Searches for Plain Text will not find these objects. The Windows platform will attempt to show outlined text, but the user will be confused how to clear this effect since the OIP is missing these two attributes. Solution, the Outline and Shadow attributes should be added to the OIP on Windows. Even if they always remain gray they would indicate when these attributes are set so users can be informed and act accordingly. I assume the Text>Font Style menu on Windows is also missing these two attributes, but I cannot check now. If so, it too should be updated. ADDITIONALLY, the "Plain Text" attribute that is present in the "TEXT>FONT STYLE" menu should be added to the OIP so users can clear all Font Style attributes with one click, including the inaccessible Outline and Shadow settings on Windows versions. This will benefit Windows users more than Mac users, but it will make the OIP consistent with the TEXT menu and across platforms. Please see this recent thread on the Forum that initiated this VE: (>THIS THREAD<) Graphic of UI elements involved. (Christopher, I hope you don't mind me using your OIP screen shot.)
  6. MullinRJ

    Text is in outline

    Thanks @Jim Wilson, One VE coming up (shortly). Raymond
  7. MullinRJ

    Text is in outline

    Hi @Jim Wilson, I think Kevin is referring to the Outline and Shadow options that are available on the Mac but not on the PC. They don't show in the OIP of PC. If a user gets a file that was edited on the Mac, these attributes could be set but wouldn't show in the PC's OIP. This adds a lot of confusion files edited on both platforms. I was planning on writing a VE for this this morning. Would you rather have me enter a bug instead? Raymond
  8. MullinRJ

    Text is in outline

    @Mason2152, You're welcome. Were you able to fix it with the Text Menu, or did you use the script? Just curious. @Kevin McAllister, Without the "Plain Text" checkbox in the OIP, there is no way to clear all TextStyle settings (like the hidden ones on the PC) in the OIP like you can when you use the TEXT menu above. The OIP and the TEXT menu items should be consistent. You can get there from here, but you have to use multiple UI items to do so. Not good. Raymond
  9. MullinRJ

    Text is in outline

    Christopher, The OUTLINE and SHADOW TextStyles are available on the Mac, but not the PC, which is why they don't show in the OIP when you select a text block that has them set. Easy fix - With nothing selected, click on the 'Text > Font Style > Plain Text' menu item. There will be a check mark in front of 'Plain Text' the next time you open the menu. When you see the check mark in front of 'Plain Text', close the file (save if necessary, but not required) and QUIT Vectorworks. This will save this text setting as the default font style when you start a new VW session. If for any reason this doesn't work, then run this short VectorScript and QUIT VW as outlined above. { Set VW TextStyle to PLAIN TEXT (i.e., no formatting). } DSelectAll; TextFace([]); HTH, Raymond
  10. I am. Please send the file to the address above. Raymond
  11. Tui, I just tried your function in VW 2017 and both versions (with descend=TRUE and descend=FALSE) convert the contents of the group to the new class. vs.SetClass(), when used with a GROUP handle always changes the container and all its contents to the new class name. Have you seen it do differently, and if so, where? Thanks, Raymond
  12. GioPet, The only way I know of that Layer(), or vs.Layer(), will create another numbered layer is if the name passed to the Layer() procedure is an empty string ( i.e., vs.Layer("") ) and that would occur if the handle variable 'item' is NIL. You should put a trap in your routine to test for 'item' being NIL. Here's one way, albeit an overly simple one. for item in ExtendedGroups: if (item != vs.Handle()): layHand = vs.GetLayer(item) layName = vs.GetLName(layHand) vs.Layer(layName) vs.SetSelect(item) vs.Ungroup() vs.NameClass(TargetClass) vs.Group() vs.DSelectAll() else: vs.AlrtDialog("item == NIL") Raymond
  13. GioPet, I am not sure how you got that code snippet to run, but the first line is not syntactically correct. layerName: 'Design Layer-1'; should read: layerName := 'Design Layer-1'; When your variable "layerName" has the value 'Design Layer-1', it will not create 'Design Layer-2' and it will either make 'Design Layer-1' active, or leave it active. BUT, if "layerName" has the empty string value '', it will create 'Design Layer-2'. My guess is that your variable "layerName" is uninitialized when you pass it to the LAYER() procedure. HTH, Raymond PS - be careful copying code from Safari (my browser), and potentially other browsers, so that you don't introduce INVISIBLE characters to your code. When I copied your two line example, and then copied pieces of it to embellish my answeer, I introduced about a dozen copies of unicode character 0xFEFF. This character is invisible, unless you know how to look for it. Always filter your code through a word processor that can show INVISIBLE characters.
  14. MullinRJ

    Easy Text with color SOLVED!!

    Correct. The first approach we discussed ignores the VW Preference entirely and forces a Fill Color and Pattern after the text is created. The second approach changes the preference to allow the current document Fill attribute to be applied when the text is created, then restores the preference to its original state. So either way you go, that VW Preference remains unchanged after the script has run. Raymond
  15. MullinRJ

    Easy Text with color SOLVED!!

    Hi @avictorgm , when I wrote my earlier replies, I was not at my best. I completely forgot about the VW Preference "Create text without fill". The Python call "vs.CreateText()" will create text with the document fill color and pattern IF the "Create text without fill" PREF is disabled, but if the preference is set, then the text background fill color and pattern are ignored, as if the document fill pattern were set to NONE. So, you could do as I suggested above, and force the fill after creating the text, OR, you could toggle the preference OFF before creating your text, and restore its setting after your text is created. Something like this: CreateTextWOFillPref = vs.GetPref(8) # save pref setting (boolean) vs.SetPref(8, False) # disable pref setting vs.CreateText(str("Motor ") + str(X1) + str(", ") + str(Y1)) vs.SetPref(8, CreateTextWOFillPref) # restore pref setting This code snippet will create TEXT using the document fill color and pattern and ignore the VW preference to "Create text without fill". If your code is working as you like it, there is absolutely no need to change anything. I am just trying to provide a more comprehensive answer. All the best, Raymond
  16. Hello @SLFY I don't know that I can add much to what was previously written, except to support what @orso b. schmid has written. Orso's advice is spot on. You definitely want to use ValidNumStr() to convert string data to numbers in document units. This function will also perform rudimentary arithmetic such that the string ' 1mm + 1" ' will evaluate to 1.03937 if the document is in INCHES or it will evaluate to 26.4 if the document is in mm. Note leading and trailing white spaces are ignored. This is indeed a very powerful function. LABELS must be declared and used (with the GOTO command) at the same level in the program. If you need to escape nested routines, then you will need to use a unique LABEL at each nestled level and use a GOTO at that level to jump to the end of the routine you are escaping. You will also need one, or more, global variables (boolean flags) to signal that you are coming out early. This way you can leapfrog all the way to the end of the main program, if that is your intention. Here's a quick example of 3 nested subroutines, each with a LABEL used to escape out to the next level.: PROCEDURE MAIN; LABEL 1; VAR gError :Boolean; procedure SubroutineA; LABEL 2; procedure SubroutineB; LABEL 3; BEGIN { SubroutineB } AlrtDialog('I am at 3 - Sub B entry'); { stuff that coud cause an error. } if gError then GOTO 3; { Do stuff here if no ERROR } AlrtDialog('I am at 4'); 3: AlrtDialog('I am at 5 - Sub B exit'); END; { SubroutineB } BEGIN { SubroutineA } AlrtDialog('I am at 2 - Sub A entry'); SubroutineB; if gError then GOTO 2; AlrtDialog('I am at 6'); { Do stuff here if no ERROR } { more stuff that coud cause an error. } if gError then GOTO 2; AlrtDialog('I am at 7'); { Do stuff here if no ERROR } 2: AlrtDialog('I am at 8 - Sub A exit'); END; { SubroutineA } BEGIN { MAIN } AlrtDialog('I am at 1 - MAIN entry'); SubroutineA; if gError then GOTO 1; AlrtDialog('I am at 9'); 1: AlrtDialog('I am at 10 - MAIN exit'); END; Run(MAIN); As written, this will execute with all Alert Dialogs counting up from 1 - 10. Add this line into the code to simulate ERRORS that will invoke the GOTO calls to escape out of nested sections. Try placing it at line 15 for starters. gError := True; { move this statment around to see how it affects execution. } Lastly, it should be possible to write PASCAL code entirely without GOTOs, but if they are working for you there is no need to rewrite anything. Use what works save the new stuff for a rainy day. I'm not sure if I helped you, but I hope this helps someone, somewhere. All the best, Raymond
  17. MullinRJ

    Easy Text with color SOLVED!!

    You're very welcome. A word of caution; using color calls like "vs.FillBack(4)" with a single argument that represents a palette position may produce unexpected results: in different files, on different systems, or after VW software updates, as palette definitions may vary under these conditions. Using these calls with three explicit color values should always produce the repeatable results. All the best, Raymond
  18. MullinRJ

    Easy Text with color SOLVED!!

    @avictorgm , After a light investigation, it appears that "vs.CreateText()" does not use the document FILL PATTERN, nor does, "vs.CreateText()" return a handle. You will have to set the FILL attribute after you create the text. So, change: h = vs.CreateText(str("Motor ") + str(X1) + str(", ") + str(Y1)) to: vs.CreateText(str("Motor ") + str(X1) + str(", ") + str(Y1)) Then use: h = vs.LNewObj() # if you want to save the handle to the text object vs.SetFPat(h, 1) Or use: vs.SetFPat(vs.LNewObj(), 1) # if you don't need to save the handle to the text object Also, all calls using color values use LONGINTS and need to be in the 0-65535. Multiply color values in the 0-255 range by 257 to convert them to the LONGINT range. Lastly, you need to pass the color values as a TUPLE, and not three Longint values. Eg. vs.PenBack((0, 65535, 0)) # GREEN HTH, Raymond
  19. LOL – Thank you, Justin. If I had a mantle, I'd place it there. Perhaps I can tape it to the refrigerator. 😉 Raymond
  20. MullinRJ

    GetSavedSetting and Dynarray of Char

    Thank you,@klinzey. I vaguely remember something being mentioned to that effect, but details and dates tend to blur the longer I do this. I started back in 1990 with MC+2.0. There's a lot of blur piling up. Yes, I see the difference now. Very nice to know. Thanks for mentioning it. @Sam Jones, If you count the number of characters in the Dynarray in my example you'll see why I said, "but it runs and returns all 437 characters in string "S",". In another test I tried it with a text block twice that amount to see if there was a 512 limit, but it worked with 874 characters. The Devil's in the Details. You can store Dynarrays in a record field, but that's local to file. With a little bit of work you could split your DynArray into 255-char-bite-sized-chunks and store each piece in the SavedSettings library. Some reassembly is required. Or, you could write your data to a file if all else fails. Raymond
  21. MullinRJ

    GetSavedSetting and Dynarray of Char

    Sam, A simple test script would give you your answer. I happen to have one here: PROCEDURE xxx; CONST category = 'DummyCatAGory'; setting = 'SomeSetting'; VAR valueIN, valueOUT :Dynarray of Char; S :String; BEGIN valueIN := '/F1 /Helvetica ff [-144 72 div 0 0 144 72 div 0 0] mf def /F2 /Helvetica ff [-20 72 div 0 0 20 72 div 0 0] mf def /F3 /Helvetica ff 144 72 div scf def /F4 /Helvetica ff 20 72 div scf def /F5 /Helvetica ff 28 72 div scf def /F6 /Helvetica ff [-28 72 div 0 0 28 72 div 0 0] mf def /F7 /Helvetica ff 16 72 div scf def /F8 /Helvetica-Bold ff 24 72 div scf def /F9 /Helvetica ff 36 72 div scf def /F10 /Helvetica ff 96 72 div scf def'; SetSavedSetting(category, setting, valueIN); if GetSavedSetting(category, setting, S) then message(S) else message('Nope'); SysBeep; END; Run(xxx); Now what you need to explain is why this script works. 1) When I declare "valueOUT" as a Dynarray of Char the complier kicks an error with GetSavedSetting(), saying valueOUT is not the correct variable type. 2) When I substitute string "S" for the return variable "valueOUT", which GetSavedSetting() DOES accept, not only does the script compile (as I expect it to), but it runs and returns all 437 characters in string "S", much more than a STRING's allotted 255 characters is supposed to handle. So, to answer your questions, YES, SetSavedSetting() WILL accept a DynArray; and NO, GetSavedSetting() WILL NOT accept a DynArray. But who cares since the latter call works with a STRING. ——— Caveat, this script was only run in VW 2019. Your mileage may vary in earlier VW versions. ——— Raymond
  22. Not even one 👍? ¡¡¡Oh, la inhumanidad de todo!!! :-p You're welcome. 🙂
  23. Hi Justin, Yes, look for an object inside the CSG container. If it returns NIL, then it is a Generic Solid. If the handle exists, then the Solid has history. Run this one line script on various selected 3D objects. vs.Message(vs.FIn3D(vs.FSActLayer()), ' ', vs.GetTypeN(vs.FIn3D(vs.FSActLayer()))) Raymond
  24. MullinRJ

    Script for closing polygons

    Hi rosebud5, I opened your file and I see your problem. The artwork you are importing was not drawn to be filled. It is line art and close is definitely good enough for the person who created it. You obviously want it to perform better than it was designed. Okay, I can appreciate that. When you say you are "wasting a lot of time closing the gaps", are you using the Connect/Combine Tool and/or the Join Tool to remove the gaps, or are you adjusting the Polys, Lines, and Arcs manually? If you are doing the latter, you can save a lot of time by using the right built-in tools. If you're already using those tools, then perhaps a custom script is in order. Though I haven't written one, perhaps one of the other scripters on this forum already has. I'd wait a little longer to see if someone else responds with a suitable answer. If nobody responds, you might want to pursue having a custom script written for you. Depending on how often you need to perform cleanup on these imported drawings, it might well be worth the investment. It won't be a simple script, so it won't be overly cheap; but if it saves you 10-50 hours (or more) a year it should be reasonably affordable. For now, All the best, Raymond
  25. MullinRJ

    Script for closing polygons

    rosebud5, Here's a no-frills script to CLOSE all Polygons and Polylines on the Active Layer. This script does not discern if the opening is "a short distance away". It will close ALL Polys. If you need that capability, will you please define how "close" is "close enough to close", or how "open" is "too far to close". PROCEDURE ClosePolys; { Close all Polygons and Polylines on Active Layer. } { This script: } { - will enter Groups on the Active Layer; } { - will NOT "show" segments that are "hidden" in the middle of a Polyline; } { - does not require objects to be selected, nor will it change the selection state; } { - will NOT work on a collection of LINES that "looks" like a Poly. } { 26 Sep 2018 - Raymond J Mullin } { DISCLAIMER: THIS SCRIPT IS OFFERED AS IS. SAVE YOUR FILE BEFORE USING THIS SCRIPT. } { UNDO WILL WORK, BUT ALWAYS BE SAFE. } function CloseIt(H :Handle) :Boolean; { Closes Polygons and Polylines. Does not affect Polys that are already CLOSED. } Var OT :Integer; Begin OT := GetTypeN(H); { object type } if (OT=5) | (OT=21) then { Polygon or Polyline } SetPolyClosed(H, TRUE); { close the Poly } End; { CloseIt } BEGIN ForEachObjectInLayer(CloseIt, 0, 1, 0); { All objects, Enter Groups, Active Layer } SysBeep; END; Run(ClosePolys); Raymond

 

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.

×