Jump to content

MullinRJ

Member
  • Posts

    2,017
  • Joined

  • Last visited

Everything posted by MullinRJ

  1. ktech, I'm guessing here, but I think your Polyline has too many vertices, even though 338 seems like it is a small enough number. I say this for two reasons, both speculative. 1) If I convert your Polyline to a Polygon (Using: Modify > Convert > Convert To Polygons), the result is about half your original shape and the vertex count hits 32,712. It looks like the operation aborted when the "Polygon" vertex count got close to the limit of 32,766. 2) If I cut your Polyline in half (and close each half), I CAN clip the surface as I expect I should. My advice is to either simplify the shape (a lot), or cut it into smaller pieces that VW can handle. HTH, Raymond
  2. Donald, In the top left corner of the RM, click on the minus sign "-" and make it a plus sign "+". When you see the + the RM will stay open when your cursor moves away. You can open and close the RM with a hotkey. The default is CMD-R, but you can change it to anything you like in the Workspace Editor. You can also click on the X to the left of the + and the window will close, (but I'm guessing that's obvious.) I'm not sure if the symbols are identical on the PC, but you should be able to figure it out if they are not. Raymond
  3. This topic should have been started in the Vectorscript forum, but I'll let the powers that be move it if they deem fit. To operate on multiple objects you can use a WHILE loop, such as this: h := FSActLayer; WHILE (h <> nil) do begin { hmove your stuff here } H := NextSObj(H); { get handle to next selected object } end; { WHILE } or use ForEachObject(), which uses a procedure to perform a small task on each object, like this: PROCEDURE MoveToOrigin; { move all Selected objects on the Active Layer to the origin } VAR LyrName :String; procedure DoThis(h :Handle); Var x, y :Real; Begin HCenter(h, x, y); HMove(h, -x, -y); End; { DoThis } BEGIN LyrName := GetLName(ActLayer); { name of active layer } ForEachObject(DoThis, SEL & (L=LyrName) ); SysBeep; END; Run(MoveToOrigin); Of course, with a script like this, all selected objects will be stacked on top of each other at the drawing origin. If you want to keep them in their relative position after they are moved, you might try grouping them first, moving the Group, then ungrouping them. Then you won't need ForEachObject() and FSActLayer will return a handle to the Group. HTH, Raymond
  4. Scott, I use something like this. You should consult the VectorScript Function Reference for PrimaryUnits(), SetUnits() and the Appendix if you want to change any of the settings. The Func Ref is in your application HELP folder, and also online at http://developer.vectorworks.net/index.php/Main_Page. This script works on the document units display, but not on Dimension objects. For that you will need to change the dimension standard applied to individual dimensions; i.e., you'll need another script. { Toggle between INCHES and mm. Script BEEPS when Inches are applied. } { This script should be customized to meet individual needs. } { 21 April 2017 - Ray Mullin. No warranties expressed or implied. } { Excessive use may cause finger cramps. Use responsibly. } if (GetPrefReal(152) = 1) then begin { if Units Per Inch = 1 } { style, prec, dimPrec, format, angPrec, showMark, dispFrac } { 7=mm, 3 decimals, 1 Dim decimals, 0=Custom, Angle Fmt 8= 0.0000°, Show unit mark=T, display Feaction=F } PrimaryUnits(7, 3, 1, 0, 8, TRUE, FALSE); { fraction=0, display=3 decimals, format 0=decimal, UPI, name='mm', square name=' sq mm' } SetUnits(0, 3, 0, 25.4, ' mm', ' sq mm'); SetPref(163, TRUE); { show unit mark } SetPref(164, TRUE); { show leading 0 } SetPref(165, FALSE); { show trailing 0 } SetPref(214, TRUE); { show leading 0 (dual dimension) } end else begin { style, prec, dimPrec, format, angPrec, showMark, dispFrac } { 2=inch, 3 decimals, 2 Dim decimals, 0=Custom, Angle Format 8=0.0000°, Show unit mark=T, display Feaction=F } PrimaryUnits(2, 3, 2, 0, 8, TRUE, FALSE); { fraction=0, display=3 decimals, format 0=decimal, UPI, name='"', square name=' sq in' } SetUnits(0, 3, 0, 1, '"', ' sq in'); SetPref(163, TRUE); { show unit mark } SetPref(164, TRUE); { show leading 0 } SetPref(165, FALSE); { show trailing 0 } SetPref(214, TRUE); { show leading 0 (dual dimension) } SysBeep; { Beep for INCHES } end; Toggle on, Raymond
  5. Hi Sam, Try it again when you update your OS. I ran OS 10.10 for a while and some things didn't work that started working again in OS 10.11. It's mostly moot, but it's worth a peek. Raymond
  6. Sam, have you tried running VW 2010? It runs on my macMINI with OS10.11.x. So does VW 2009. Earlier versions do not and neither does VW 2011 or VW 2012. Then VW 2013-17 do run. I keep old versions around and old machines to run them, though I rarely have the need; but when I do, they work perfectly. To the original question, it's all perfectly fair. It's a subjective judgement call, to upgrade the OS/SW or not. I once had to buy a new computer to stay current, but nobody made me. This is nothing new. Since about 1980 we've all danced this dance. Raymond
  7. Peter, I just copied the two images you posted and saved them from Preview to my desktop, naming them appropriately as A.png and A@2x.png. They imported as I expected and invoked no error message. I saved them twice, with and without the alpha channel, but VW imported both versions the same. I am not sure where your problem lies, but I don't think it is with the image files. Raymond
  8. 25 hours - That's how long it took the engineers to fix it. From Bug Submitted to Resolved in 25 hours. That's not the best I've seen (I think I've seen one fixed in 4 hours), but it's still freaking awesome. The next question is how long will it take to get released? Sadly, that takes a little longer. I'll post back if I hear definitively. Raymond :-)
  9. Peter, I swapped your ArcByCenter() call with the original VS Arc() call and the error persists. I changed this: {Sets up checkbox in OIP to flip arc sweep} swp := 180; IF flip THEN swp := -180; {Draws Arc} ArcByCenter(bridgelength/2, 0, bridgelength/2, 180, swp); to this: {Draws Arc} IF flip THEN Arc(0, bridgelength/2, bridgelength/2, -bridgelength/2, 0, 180) else Arc(0, bridgelength/2, bridgelength/2, -bridgelength/2, 180, 180); using Pat's suggestion worked: {Draws Arc} IF flip THEN Arc(0, bridgelength/2, bridgelength/2, -bridgelength/2, 0, 179.99) else Arc(0, bridgelength/2, bridgelength/2, -bridgelength/2, 180, 179.99); though it really SHOULD work with a sweep angle of 180. Drawing a 180° ARC on a Design Layer and rotating it produces the same problem. It seems VW 2017 has a geometry problem. Bug report to follow. Raymond You are right about the Object Properties dialog. SetParameterVisibility() only works in the OIP. Dialogs and Palettes are drawn by completely different engines. There are different calls that can be used to hide dialog elements, but we cannot modify built-in dialogs like the Object Properties dialog.
  10. Peter, I, too, see the problem, but have no idea why it exists. However, I noticed your object will draw the wrong way based on its rotation, and possibly its position on the drawing. Very weird. In the OIP, I changed the rotation from 0° to 360° (by 10° increments) and at some values it draws the wrong way. Move the object to a different location and repeat changing the angle, and it will draw incorrectly at different rotation values. I assume there is a bug in the VS code of the ArcByCenter call, but that will take some testing to prove. The problem could also be cause by an interaction between ArcByCenter and the PIO environment. I'll enter a bug and see what happens. I'll try drawing the arc the old-fashioned way and post back. Pat, Peter draws the LINE at 45° then rotates it back to 0°. He converts degrees to radians properly, so yes, you were presumably tired. I shortened his code and draw the LINE horizontally, but it does not change anything. Here it is for reference. It's shorter, but not better. PROCEDURE BridgeLineNew; VAR objh, objrech, wallh : HANDLE; flip, setcoverweight, result : BOOLEAN; coverweight : INTEGER; bridgelength, adj, swp : REAL; objn : STRING; BEGIN {retrieve custom object information} result := GetCustomObjectInfo(objn, objh, objrech, wallh); {if object information was successfuly retrieved} IF result THEN BEGIN {retrieves parameters} bridgelength := PLINELENGTH; setcoverweight := PSET_COVER_WEIGHT; coverweight := PCOVER_WEIGHT; flip := PFLIP; {Hides cover weight from the Set Cover Weight parameter in the OIP} IF NOT setcoverweight THEN SetParameterVisibility(objh, 'Cover Weight', FALSE); {Hides the LineLength parameter in the OIP} SetParameterVisibility(objh, 'LineLength', FALSE); {Gets current pen attributes} PushAttrs; {Sets pen attributes to draw line} PenSize(coverweight); PenFore(65535, 65535, 65535); PenPat(2); {Adjusts coverweight for mils} adj := coverweight * 0.0254; {Adjusts line start point by 1/2 coverweight thickness} MoveTo(adj/2, 0); {Draws Line and shortens length for cover weight thickness} Line(bridgelength - adj, 0); {resets pen attributes} PopAttrs; {Sets up checkbox in OIP to flip arc sweep} swp := 180; IF flip THEN swp := -180; {Draws Arc} ArcByCenter(bridgelength/2, 0, bridgelength/2, 180, swp); END; END; Run(BridgeLineNew); NSITH*, Raymond * Not Sure If This Helps
  11. Robert, as you have probably surmised, the interactive calls do not work well (if at all) in Python. There have been earlier threads in this forum about vs.GetPt(), vs.GetLine(), vs.GetRect(), etc., with similar complaints. My advice is to use VS for these calls, if you can, until a solution is found for Python. Many people are waiting for these to work in Python. If you do find a way to make it work, please post back with a solution. You will make a lot of people happy. Raymond
  12. It's hard to get in ahead of you, Pat. It's like you live here, or something. :-p Honestly, I don't know where you find the time. Raymond
  13. Christian, After VW 2014, MESSAGE, CLRMESSAGE, and WAIT do not work well together. If you have a copy of VW 2014 loaded, your script will work well there. In newer versions of VW only the last message generated will be displayed, and ONLY after the script finishes. In your case, the ClrMessage command is closing the Message Window before it is even displayed for you to see. Bugs have been submitted to correct this behavior, but they have not been addressed yet. If you want to see the message in VW 2017, remove the ClrMessage line. If you want to hear your script, add a "SysBeep" command at the end. This will indicate that your script actually got to that line (assuming your speakers are connected and turned on). Moving the SysBeep line around and rerunning is also a good debug tool to trace the flow of more complicated programs. Also, your signature does not indicate which version of VW you are running, or what platform and OS you use. Adding this info can be very helpful for people trying to answer your questions accurately. At the very least it saves one round of posts requesting the info. HTH, Raymond
  14. I am attaching a sample file that contains two Worksheets that are able to convert weight fields with units to numeric values that can be used directly in calculations. The weight values can exist in WS cells or in record fields attached to objects in the drawing. I did not venture too far into the plethora of units available worldwide, but this example does show how to convert between kilograms (Kg) and pounds (Lb) for displaying or summing weights in a single unit base. As a bonus, ounces (oz avoirdupois) can be used as an input value, but I did not include a function to convert to ounces as an output value. I'll leave that as an exercise to anyone who is feeling cerebrally sedentary. Note, though it is possible to mix weight units for separate objects and the worksheet will convert them accordingly, mixing units for a single object is not yet supported. That is, it is not possible to have a weight field contain "3 lb 2 oz". This is not a silver bullet to the task of summing weights in VW Worksheets, but it does provide a way to retrieve weight values attached to objects, possibly with mixed units, and perform calculations in either pounds or kilograms. A similar approach could be applied to monetary values. If anyone needs help with similar functions, please PM me or contact me offline. If anyone finds this useful, please let me know. HTH, Raymond WS Weights.vwx
  15. Did you use the Modify>Scale Objects... menu recently? If so, was the Entire Drawing checkbox checked? Was your scale factor 96.9? Raymond
  16. Hi Michael, The main problem with the script is all the Classic Dialog calls (the ones in this script) are now obsolete. All dialogs must now use Modern Dialog calls. Here's a list of the Classic Dialog calls on the left and the corresponding Modern Dialog calls on the right. If you plan to do all of the edits yourself, you will need to get familiar with the VS Function Reference, which can be found in your VW application folder in the VWHelp>Script Reference folder, or online at http://developer.vectorworks.net/index.php/VS:Function_Reference CLASSIC MODERN AddButton CreatePushButton, CreateCheckBox, CreateRadioButton AddChoiceItem CreatePullDownMenu AddField CreateStaticText, CreateEditText, CreateEditTextBox, CreateEditInteger, CreateEditReal AddGroupBox CreateGroupBox, CreateCheckBoxGroupBox, CreateRadioButtonGroupBox AddHelpItem SetHelpText BeginDialog CreateLayout ClrDialog --- DelChoice RemoveChoice DialogEvent RunLayoutDialog DrawDialog --- EndDialog --- GetChoiceStr GetChoiceText GetDialog --- GetField GetItemText, GetMultilineText GetSelChoice GetSelectedChoiceInfo InsertChoice AddChoice ItemSel GetBooleanItem NumChoices GetChoiceCount SelChoice SelectChoice SelField SelectEditText SetField SetItemText SetHelpString SetHelpText SetItem SetBooleanItem SetItemEnable EnableItem SetTextEditable EnableTextEdit SetTitle --- You'll also need to write a dialog event handler procedure. When you get that far, write back and I or someone else will help you with it. If you want help offline, PM me. HTH, Raymond
  17. Don't you mean: IF (objHd <> NIL) THEN ? Also, SetParameterVisibility() is not part of the IF statement. You'll need a BEGIN and END to include it. Raymond
  18. Laura, I haven't looked at Pat's code, but he is using a ListBrowser approach. It isn't wrong, but it's a lot more complicated than what you need (IMO). I added comments to your code and commented out pieces that were causing errors. It runs but doesn't do much. I hope this helps. Raymond PROCEDURE dialogl_Main; VAR dialog1 : INTEGER; PROCEDURE dialog1_Setup; BEGIN dialog1 := CreateLayout( 'CreateListBox', FALSE, 'OK', 'Cancel' ); CreateListBoxN( dialog1, 4, 30, 10, TRUE ); SetFirstLayoutItem( dialog1, 4 ); END; { dialog1_Setup } PROCEDURE Dialog_Handler(VAR item :LONGINT; data :LONGINT); VAR i : INTEGER; nl : INTEGER; layers : DYNARRAY OF STRING; { this needs to be GLOBAL or it will be rewritten on each dialog event. } h : HANDLE; BEGIN CASE item OF SetupDialogC: BEGIN { you need a loop here to add your design layer names to the dialog ListBox using AddChoice() } { are these layer names? they are being added to the Layer Name ListBox. } { or is this test data? (which is OK) } AddChoice( dialog1, 4, 'PLANTA 1', 0 ); AddChoice( dialog1, 4, 'PLANTA 2', 0 ); AddChoice( dialog1, 4, 'PLANTA 3', 0 ); END; { SetupDialogC } 1: BEGIN { this only gets one choice starting at the second line (line 1) } { the lines start at "line 0". Not the documentation says this function is "0-based". } { there is no consistency in VS as to what is "0-based" or "1-based". You have to read. } { put this in a loop to get all choices and save the text in your array as you go. } { GetSelectedChoiceInfo(dialog1, 4, 1, i, layers); } { count your design layers and allocate your Layer Name array here. } { then add your choices to it with a loop. } { GetSelectedChoiceInfo() will return -1 when it can't find any more selections } END; { 1 } 4: BEGIN { this code is in the wrong place } { pasting needs to be done in ITEM 1 (at the end) or in the main program after the dialog is done. } { copying needs to be done on SetupDialogC event, or before the dialog code starts. } { item 4 doesn't really need any control. Selection is handled by the ModernDialog machine. } (* nl := NumLayers; Layers := GetLNAME (h); DoMenuTextByName('Copy', 0); FOR i :=1 TO nl DO BEGIN DoMenuTextByName('Paste In Place', 0); *) END; { 4 } END; { case } END; { Dialog_Handler } { this was missing } BEGIN dialog1_Setup; IF (RunLayoutDialog(dialog1, Dialog_Handler) = 1) THEN BEGIN END; { this was missing } END; RUN(dialogl_Main);
  19. Laura, You'll also need: GetSelectedChoiceInfo(dialogID, componentID :LONGINT; startIndex :INTEGER; VAR SelectedIndex :INTEGER; VAR SelectedChoiceText :STRING); to determine which items are selected. Raymond
  20. Laura, You are going to need to use: CreateListBoxN(dialogID, itemID, widthInCharacters, heightInCharacters, isMultipleSelect); to display your layer names. The last parameter should be TRUE to allow multiple selections. Also, you need to call a procedure to handle your dialog events, i.e., what to do when you click controls: result := RunLayoutDialog(id, DialogHandler); DialogHandler has two parameters: procedure DialogHandler ( var item :Longint; data Longint ); and usually contains a CASE statement to handle the events: case item of ... end; { case } The first item in the CASE is usually: SetupDialogC: begin { setup code goes here ( load your list with layer names ) } { use AddChoice(dialogid, dialogitem#, list_text, list#); } end; The other CASE items will be your dialog control item numbers if needed. For item 1 (OK) in the CASE statement, you can harvest the selected items in your list there. That is, fill a global array variable with your Layer Names based on the selected list items. After your dialog code exits you will use the array to perform your PASTE operation. Raymond
  21. I tend to use ForEachObjectInLayer() more than ForEachObject(). Some people like to think using <criteria> to sort the whole document, while I like to think of lists describing smaller sections of the document. Essentially you should be able to do either to get the same result, but with ForEachObject() you will be looking at everything drawn on all layers if you don't filter anything out. Since you got your problem working, you can ignore this for now, but you might want to give ForEachObjectInLayer() a try next time. ForEachObjectInList() is also quite useful if you have a targeted list you want to traverse, like the Symbol Definition List, and you already have a handle to an object in that list. One caveat, the ForEach... commands use a built in equivalent of NextObj(), and not PrevObj(). Lists will always be traversed this way. Raymond
  22. Derek, I should have read the documentation before I asked my question. 'objname' is returned by the function vs.GetCustomObjectInfo(). However, in Python, all returned variables must be to the left of the equal sign. Try this: result, objname, oh, rh, wh = vs.GetCustomObjectInfo() then use the handle "oh" in your vs.SetParameterVisibility() calls. Raymond
  23. In Python, how are you assigning a value to "objname"? Raymond
  24. Writing the dialog code will be the harder part of this task. To paste on multiple layers just requires a simple loop where the layer name can be accessed each time, and you won't need to copy before running the script, the script can do it for you. Just select your objects and run your script. The code will look something like this: BEGIN << Dialog code to select multiple layers and save in an array >> if not DidCancel then begin DoMenuTextByName('Copy', 0); { copy selected objects to paste } for I := 1 to NumSelectedLayers do begin Layer(LayerNameArray[I]); { change active layer for pasting } DoMenuTextByName('Paste In Place', 0); end; { for } end; { if } END;
  25. Laura, This is how your script reads: 1) Get a handle to the 1st object on the active layer. 2) Get the class of that object. 3) Change the Active Class to '0Sup'. 4) Change class options to ONLY show the Active Class, which is now '0Sup'. 5) Test if the class named 'Active_Class' is visible. This will always return TRUE when a class name does not exist, and I assume 'Active_Class' is not in your drawing. Inside the IF: 6) Make class ''0Muros' visible. (This has no noticeable effect since the Class View Options are set to ActiveClass, and '0Sup' is the active class.) 7) Call the Polygon tool for one use. (The Polygon drawing mode is not specified and will draw in whatever the last Polygon mode was selected.) 8) Delete the 1st object on the layer, whatever it is. (This may be desirable, or not, depending how you plan to use this tool.) Comments: A likely mistake: IF ((GetCVis('Active_class')) = 0) THEN should probably be written: IF (GetCVis(Active_class) = 0) THEN if you want to reference the string variable Active_class and not a class named 'Active_class'. Next: assigning the active class to string variable Active_Class is usually written as: Active_class := ActiveClass; The first object on the active layer may, or may not, be in the active class. It is not guaranteed. However, since I am not sure what you are really intending, your code may do what you want. Next: To show multiple classes at the same time you cannot set the Class View Options to "Active Class Only". You will have to hide the classes you don't want to see. This will require more extensive programming, since you will probably what to save the current visibility state, and restore it when you are done. Next: If you want the Bucket Mode of the Polygon tool you will have to explicitly ask for it. CallToolwithMode(-207, 1, 2); { Polygon tool, Bucket mode } If you want the last mode used, then your script does that. Next: The code as written will delete the 1st object on the layer. Each time you run it, something will disappear. I'm guessing this is not what you want. Your last line will need some work. Suggestions: 1) Write your intended actions down on paper, in English (or your favorite language). Use this as your guide for the script. 2) When you get a line working, add a comment to the right describing exactly what it does. It comes in very handy later when you revisit your code, especially when numeric options are used in a line. This way you don't have to look up the meaning of the numbers each time. 3) Use the Message() statement inline, or in a test script, to see how expressions evaluate. Example: "Message(GetCVis('AnyUnusedClassName'));" Note this will return 0, even when a class name doesn't exist. <<Side effects happen!>> 4) Last tip – Visit here often. Help is free, and that's a good deal even at thrice that price. HTH, Raymond
×
×
  • Create New...