Jump to content

MullinRJ

Member
  • Posts

    2,017
  • Joined

  • Last visited

Everything posted by MullinRJ

  1. You don't need to invoke your tool to place it with a script. Since you coded the object, you know everything about it. Simply PLACE the object, ATTACH the PIO record to it, and FILL in all the record fields with values you want. Here's a VS sample of a bolt object (not a custom object, but the steps are the same). H := CreateCustomObject('Hex Bolt (ISO)', 0, 0.8, #0d); Record(H, 'Hex Bolt (ISO)'); Field(H, 'Hex Bolt (ISO)', 'boltType', 'Hex Bolt'); Field(H, 'Hex Bolt (ISO)', 'size_1', 'M12 X 1,75'); Field(H, 'Hex Bolt (ISO)', '__size_2', 'M12 x 1,75'); Field(H, 'Hex Bolt (ISO)', '__size_3', 'M12 x 1,75'); Field(H, 'Hex Bolt (ISO)', '__size_4', 'M12 x 1,75'); Field(H, 'Hex Bolt (ISO)', 'length', '1.9685'); Field(H, 'Hex Bolt (ISO)', 'threadStyle', 'Simplified'); Field(H, 'Hex Bolt (ISO)', 'view', 'Front'); Field(H, 'Hex Bolt (ISO)', 'drawFillet', 'False'); Field(H, 'Hex Bolt (ISO)', 'stdLength', 'True'); Field(H, 'Hex Bolt (ISO)', 'centerline', 'False'); Field(H, 'Hex Bolt (ISO)', '__oldSize', 'M12 X 1,75'); Field(H, 'Hex Bolt (ISO)', '__oldType', '1'); If that is not enough, then ResetObject(H) when you're done. It should be pretty easy to Pythonize this. HTH, Raymond
  2. The count is higher because there are a lot more objects in that list than Worksheets. If you put another counter inside your IF statement you should get 15 for the Worksheet count. if (GetTypeN (h) = 18) then begin q := q + 1; RecalculateWS (h); end; ... Message('Total Cnt= ', p, ' Worksheet Cnt= ', q); Raymond
  3. Pat, like you, I've spent WAY more time on this than I intended, but I think I've got it — assuming I read the question correctly. Then I spent a bunch more time playing with it. All of it non billable, so I hope someone enjoys this besides me. MattG, Having never worked with Linked Text before, I started out like a rank beginner. Now I understand how it works. It weren't [sic] obvious. I am also not sure I solved the problem you stated above. Hopefully I am close. I'm attaching a v2013 file with 3 scripts. The first converts "symbols with selected text" to "symbols with Linked Text", and it makes a LOT of assumptions on how the file is set up. A list of the assumptions can be found at the top of the script. Use the Script Editor to read them. If anyone uses this script on their own files — WORK ON A COPY OF YOUR WORK – until you know the script does what you want. All Common Sense Disclaimers apply. Because this task starts with symbol instances and ends up modifying symbol definitions, it was necessary to make two passes to do it right. Here's my basic approach: With each symbol instance: find the first selected text object inside the SymDef. attach the LinkedText record to the symbol instance. add the selected text from inside the SymDef to the record field. Go back through each symbol instance: find the first selected text object inside the SymDef. attach the Linked Text record to the SymDef. add the selected text from inside the SymDef to the record field. This is the Default text when the symbol is placed. LinkText() from the selected text object to the Linked Text record and field. The second script places symbols and modifies the Linked Text. The third script resets the file to its initial state. If anyone has any questions about what I've done, Pat will be happy to answer you. ;-) Raymond Link SymText to Sym v2013.vwx
  4. Define "simple". Try this in place of vs.LineTo() when you want to enter distance and angle. def LineToAng(D, A): # works like LineTo() with a distance and an angle (in degrees) as input X, Y = vs.PenLoc() A = vs.Deg2Rad(A) vs.LineTo(X+D*vs.Cos(A), Y+D*vs.Sin(A)) Use it without the "vs." prefix like this: vs.MoveTo(0, 1) LineToAng(3, 30) # from current point draw a Line 3 units long at 30° HTH, Raymond
  5. Vincent, Think of it as "Sick Leave." When you get better, you come back. Door's always open. ;-) Raymond
  6. After a little poking around (literally) I found the "date of post" is invisible until you roll your cursor over the invisible field by the poster's name. Cute, but not desirable. I'd like to be able to make that information visible at all times when I visit this forum. I can read much faster than I can mouse. Raymond
  7. One feature of the old Techboard I liked was the date of the last post was displayed next to the name of the last poster. Is it possible to configure this board the same way? If not, can it be added? (JimW? ;-) ) Another feature I don't see is the "Preview Post" button which used to reside next to the "Submit Topic" button. Is that hidden somewhere, or can it be reinstated? Thanks, Raymond
  8. Alan, Can it make a creaky noise as it opens? I've often desired the ability to add an extra sound to VW, to complement the SysBeep. A raspberry, or foghorn, I could attach to a negative event. Ding for good, and Thbbbbb for not-good. A creaky noise would be cool too. Raymond
  9. Checking my calendar... looks good, Checking my wallet... um... I seem to have more calendar than wallet available. Glad I could help. And if I ever get kidnapped and wake up in Moorea, I'll make sure my captors bring me over for lunch. TIA, Raymond
  10. Kevin, I was going to post here earlier today and suggest you use a two line script: DSelectAll; SelectObj ( (FSZ >= 11) & (FSZ <= 12) ); but when I tried it I realized FSZ is broken, actually it never really worked. FSZ only works with integer point sizes. So I entered a bug report and reworked an old script of mine that should work for you. Try this: PROCEDURE SelectPtSizeRange; { Select all text objects in a range of point sizes. } { 25 Nov 2003 - Raymond J Mullin } { 08 Aug 2016 - Rewrite with ForEachObject. } CONST DefaultLo = '9'; DefaultHi = '11'; VAR Lower, Upper: Real; Procedure SelectIt(H :Handle); Var PtSize :Real; Begin PtSize := GetTextSize(H, 0); if (PtSize >= Lower) & (PtSize <= Upper) then SetSelect(H); End; { SelectIt } BEGIN DSelectAll; PtDialog('Select Text Between Point Sizes: X=Lower & Y=Upper', DefaultLo, DefaultHi, Lower, Upper); if not DidCancel then ForEachObject(SelectIt, InSymbol & (T=Text)); END; { SelectPtSizeRange } Run(SelectPtSizeRange); HTH, Raymond
  11. Matt, Thanks for standing on half your ground. Raymond
  12. Matt, I like the first half of your statement, but the second half disagrees with my observations, unless my measurements and conclusions are flawed. If a set of Loci are placed by script (meaning very accurately) around an elliptical path over an Oval of the same geometry, the Loci sit perfectly on the outline of the Oval across a very wide range of zoom levels (100% to 20,000,000%). If as you say, the oval is not displayed "absolutely perfectly", then that would imply the Loci are not displayed "absolutely perfectly" either, and share the same display distortions ovals do. Is this also true? Can you, or your "secret source", elaborate a little more, please? (Hmm – "secret source" – sounds like burger chain jargon. Where is this thread headed?) One moment while I get back on topic... If there is a distortion with the onscreen display, but you can draw Lines between the Loci on the Oval and get proper feedback through the OIP, and/or the Fixed and Floating Data Bars, AND Reshaper, as to their length, angle, dX and dY, and XY positions of their endpoints, AND those values agree with predicted measurements, is there really a distortion we need to worry about? The next thing I fear you'll tell me is the color of ovals on my monitor may be inaccurate. ;-) TIA, Raymond PS - I think the VW Oval should be renamed a Rodney Dangerfield loop, 'cause "it don't get no respect!"
  13. But Pete, you should be able to rely on Lines and Loci being drawn well on VW's cartesian grid at any zoom. About your test, I don't know what you mean by "join a line to the curve", if the curve is an Oval. I am unable to do that, since the oval is a closed object. Do you mean SNAP a line to an Oval or TRIM a Line with an Oval? Trim works, but Snap-to-Object for Ovals does not. I guessed at what you described (using TRIM) and got the opposite results. If you would like, I'd be happy to talk to you on the phone to compare notes and we should both spend my less of our "abundant spare time" on this topic. I'll send you my number offline. All the best, Raymond
  14. Kevin, look more closely. They are not equal, unless you clipped your Oval before comparing it to a Quarter Arc (QA) segment. When unconstrained, the QA tool draws a Polyline, not an Arc, and definitely not a quarter Oval or ellipse. To test if an Oval in VW is an Ellipse, you should plot points by placing Loci at positions determined algebraically from an ellipse formula using the same major and minor axes of a drawn Oval. If done correctly the Loci will perfectly match the Oval's path, showing the Oval to be a real Ellipse in VW. Zoom in to 500,000% and the Loci are still sitting perfectly on the Oval's curve on the screen. Compare that to a QA curve snapped to the same Oval (say, top-center on the oval to right-center on the oval.) The QA curve (now a polyline) is drawn farther out than the curve of the oval / ellipse. Like a trimmed Oval, the unconstrained QA curve can do no better than any other polyline. I'm going back into my hole now. Have fun. Raymond
  15. This conversation was held a decade or so ago on this forum, with the same outcome. Some people believed Ovals are ellipses and some did not. Without going into great detail, the term Oval in VW IS equivalent to the term Ellipse in math circles (or in math ovals, if you will). This can be tested with a script dropping any number of loci evenly around an elliptical path defined by a VW Oval's major and minor axes. For all digital purposes they are equivalent. They agree beautifully. When a VW Oval is clipped, it is converted to a Polyline (a path object). VW Polylines can be composed of any combination of straight, arc, and bezier segments, however it is impossible to exactly represent an ellipse (i.e., a VW Oval), wholly or in part, using these path components. This last statement is based on other people's work. I've read some proofs on this topic and I agree with them. If anyone wants to learn further how to test my statements, please contact me offline. Pete, I didn't use the Oval type above, because that would be the same as using a word in its own definition. As you suggest, it is entirely possible to have an oval's clipped path match a partial ellipse perfectly, but someone will have to submit an enhancement request for a different solution from the existing Polyline conversion, which can never be perfect. VW will need a new object type to achieve this. If a Circle clips to an Arc, perhaps an Oval will clip to an Orc. Forgive me, it's late and I see no obvious term for the requested shape. Let greater minds invent one. HTH, Raymond
  16. Hi Pete, I agree with you that oval segments CAN be represented accurately in a CAD environment, but in VW using the current set of available object types – Line, Arc, Bezier Segment, NURBS – they cannot be represented without some measurable error. There are no VW types available that give an exact equivalence to the Oval type. A series of points along an oval's curve (a Polygon) CAN be made to be as precise as needed (for all practical purposes) but it becomes "point heavy" quickly. Approximating an Oval with Arcs or Bezier segments has been proven by others to be inexact. There are some wonderful papers on the internet describing how to implement these approximations. I've read several and found them fascinating. On the recurring topic of Oval vs. Ellipse, as VW implements the Oval type it performs remarkably well as a perfect ellipse. It's CAD, it's digital, by that very nature it's not exact, but even LINES in CAD have holes in them if you try to specify too many digits. [ This reminds me of a discussion on this board with Petri, some 15 years ago. I do miss his presence still. :-) ] I know many people have their doubts about Oval/Ellipse equivalence in VW. That's okay. I know for what I need they are 100% interchangeable. There's plenty of room for opinions and split hairs here, and I don't need to convince anybody but myself, so we may agree to disagree. Respectfully, Raymond
  17. Donald, There is no exact way to represent a partial piece of an ellipse/oval after it has been trimmed. The path can be approximated by a set of Arcs (as you have seen), Bezier segments, or by a series of short straight Lines (a Polygon if they are connected). Each representation has errors. These can be minimized, but never completely removed. You're absolutely right, it is what it is. Raymond
  18. Black Background doesn't help? It's not as sexy as what Jim posted, but it is easier on the eyes for many types of drawing. I toggle back and forth all the time. Raymond
  19. Sam, You can use GOTO , which causes the execution to jump to the label. GOTO will not jump out of nested procedures, so you'll have to have a and a GOTO at each level to jump to the end of that level when some condition is TRUE. Declare labels at the top of the program or procedure as: LABEL ; EXAMPLE: procedure xyz; Label 88; Begin ... GOTO 88; ... 88: End; { xyz } From the VS Language Guide: The general syntax for a GOTO statement is: GOTO ; GOTO statements have several cautions which must be observed whenever using them: • GOTO statements can only transfer execution within the same procedure, function, or main body of a script. They cannot be used to jump between procedures or between scripts. • The destination of a GOTO statement must always be the beginning of a statement. • Jumping to statements that are contained within the structure of other statements can have undefined effects; the VectorScript compiler will not recognize this action as an error. Raymond
  20. For a script or Plug-in that will toggle the visibility of the WP Axes, see the following post in the "Resource Share - Vectorscript" section of the board. https://techboard.vectorworks.net/ubbthreads.php?ubb=showflat&Number=230437Post230437 Raymond
  21. Last week a question was raised on this board, "Is there a way to hide the display of the axes when working on a rotated plan?" https://techboard.vectorworks.net/ubbthreads.php?ubb=showflat&Number=230007#Post230007 Setting the Interactive Appearance Settings preference "General - Working Plane Axes Opacity" to zero does hide the axes in Rotated Plan View, but it also keeps them off when using the Working Plane tool, where their visibility is more useful. SO - to alleviate the need to manually set the "Working Plane Axes Opacity" preference each time drawing conditions change, I wrote the following script to toggle it between the current setting and zero. If the current setting IS zero the first time the script is run, the script will use a default value of 40%. Subsequent calls will toggle between 40% and 0%. If 40% is not the desired value, simply set the Working Plane Axes Opacity value manually and run the script again to toggle between that new value and zero. The current value is remembered when the script is first run and whenever the value is manually changed. For those who want to use this script as a Plug-in Menu Command, download the attached file and copy it into the Plug-ins folder inside your User Folder, then add it to any workspace. Assigning a hotkey is optional. The Plug-in is compiled in VW 2014 and will also work in subsequent VW versions. PROCEDURE ToggleWPAxes; { Toggle the Working Plane Axes Opacity between 0 and the current value. } { 15 Jul 2016 - Raymond J Mullin } CONST WPAxisOpacity = 1995; { Preference number } PgmName = 'ToggleWPAxes'; { SavedSetting Category name } SubCat = 'Opacity'; { Subcategory name } DefaultOpacity = 40; { any integer value from 1-100% } VAR Val, SavedVal :Integer; function GetSavedWPAxisOpacity(Pgm, Cat :String) :Integer; { return WP Axis Opacity if it is found in the SavedSettings file, else return the Default Opacity } Var Val :Integer; StrVal :String; Begin if GetSavedSetting(Pgm, Cat, StrVal) then begin Val := Str2Num(StrVal); if (Val < 0) then Val := 0 { ensure value is always in proper range } else if (Val > 100) then Val := 100; end else Val := DefaultOpacity; { value has not been stored, use default } GetSavedWPAxisOpacity := Val; End; { GetSavedWPAxisOpacity } BEGIN SavedVal := GetSavedWPAxisOpacity(PgmName, SubCat); Val := GetPrefInt(WPAxisOpacity); { current value } if (Val > 0) & (Val <> SavedVal) then { selective save } SetSavedSetting(PgmName, SubCat, concat(Val)); if (Val = 0) then Val := SavedVal { toggle values } else Val := 0; SetPrefInt(WPAxisOpacity, Val); { apply new value } END; Run(ToggleWPAxes); HTH, Raymond
  22. Howdy Patrick, That's mighty Texan of you ;-) I think you are on the right track with: vs.ForEachObject(). I didn't really look at how you got your "group_center", but you can easily extract a virtual BoundingBox with: X1 = vs.LeftBoundN("All") X2 = vs.RightBoundN("All") Y1 = vs.TopBoundN("All") Y2 = vs.BotBoundN("All") for all objects in the drawing, or use: X1 = vs.LeftBoundN("V") etc., to only process visible objects. then: Xc = (X1 + X2) / 2 Yc = (Y1 + Y2) / 2 (-Xc, -Yc) is the amount you will move everything, assuming the user origin was not moved. Otherwise, you'll have to do the math we did earlier. With different constraints, come different solutions. HTH, Raymond
  23. Martin, I knew the answer to your question was "YES" because my screen doesn't show them, but for the life of me I could not find how I had hidden them. So, after an hour of poking into every dark corner I could find, and there are a lot of them in VW, I started stepping through the Interactive Settings one at a time. When I got down to "General - Working Plane" it hit me like an invisible brick. I had set the "Axes Opacity" to 0. Move that slider all the way to the left. Axes Gone! Of course, they are gone for the Working Plane tool, too. Hope you don't mind. HTH, Raymond
  24. That makes sense. I almost always have "None" as my active class. That's something I would easily miss. Actually, all three scripts will suffer this problem, since they all work pretty much the same way. Nice catch, Patrick. If you want the script to be more fluid, save the active class at the beginning and restore it at the end. Try this expression to see if it works across language lines. vs.NameClass(vs.Index2Name(2)) I am curious if it will return 'Keine' in your version of VW. Please let me know as I cannot test it here. index 2 in the NameList is always "None" and index 3 is always "Dimension" My assumption is that when VW is ported to another language, this call will return "None" in the local language. If it works as I expect, there will be no need comment out lines for different international users. There is another mistake in the 3rd example: V = [-x-y for x,y in zip(Pcen-Orig)] # offset vector V = -Pcen-Orig should read: V = [-x-y for x,y in zip(Pcen, Orig)] # offset vector V = -Pcen-Orig Typo. There should be a comma between the arguments in "zip", and not a minus sign. Raymond
  25. In the previous script I took a more readable approach to presenting the variable elements. In this version I use some of Python's built in functionality. Note: the use of tuples and lists to represent "vectors" and the "zip" function to add the vector elements. In all three versions of this script, if the User Origin is not at the Absolute Origin, this script will adjust for that. # CenterOnOrigin # Moves everything on a design layer to the Origin, # then moves the User Origin to maintain the same XY readings. # 11 Jul 2016 - Raymond J Mullin # USE AT YOUR OWN RISK, and USE on a COPY of your data FIRST! import vs vs.SelectAll() vs.Group() # Orig, Pcen are tuples representing (X,Y) vectors Orig = vs.GetOrigin() Pcen = vs.HCenter(vs.FSActLayer()) V = [-x-y for x,y in zip(Pcen-Orig)] # offset vector V = -Pcen-Orig vs.HMove(vs.FSActLayer(), V[0], V[1]) vs.Ungroup() # optional, to retain the same x&y after the move vs.SetOrigin(V[0], V[1]); # remove to keep drawing center unchanged Raymond
×
×
  • Create New...