Jump to content


  • Content Count

  • Joined

  • Last visited

Everything posted by MullinRJ

  1. MullinRJ

    Dimension Class

    Dan, I will have to play with the tool a bit before I can commit a solution to you. The offset tool is not one I use very much. Looking at the VS commands, I don't see a general Offset command. There is a new OffsetPoly command in VW10, which may make coding a new tool possible. Can you tell me on which object types you use the tool? OK, I've played a bit. I notice the tool works nicely on Lines, Arcs, Ovals, Rects, and Polys; but Polylines suffer from too many new points being created, and RoundRects, not so hot, at least on VW852. It should be possible to do what you want with a script, but it will depend on the object types you want to offset. Now, I did notice that if you select multiple objects and set an offset distance, then each time you click, the next selected object gets offset by the preset amount. It's not the most elegant feel for a tool, but it might be useful in some applications. However, if you click too many times, it comes back through the list again - not what I would want it to do. Just out of curiosity, have you tried this modality? Raymond
  2. MullinRJ

    Dimension Class

    To get your desired result, you could always run a script... I have one here... ************* procedure RenameDimClass; { Change the class name for all objects in the DIMENSION class. } Procedure NewClass(H :Handle); Begin SetClass(H, 'A-ANNO-DIMS'); End; { NewClass } BEGIN ForEachObject(NewClass, C='Dimension'); END; Run(RenameDimClass); ************* If you make this a Plug-In Menu, and add it to your workspace, it will be available all the time. This script will not change the class of dimensions that are embedded in Symbols, but it will work on dimensions that are grouped. If you need to enter Symbols, just ask, I can show you how to do that too. HTH, Raymond
  3. MullinRJ


    axiom, This script is not elegant, but it will give you the FontID of the first selected object, if it is of type TEXT. For scripting questions, you would do better to post them in the VectorScript section of the board. I would not have seen your question in the LANDMARK section had the title not caught my eye on the main topic page. HTH, Raymond Procedure GetFID; { Get a text object's Font ID. } VAR TxtHnd: Handle; BEGIN TxtHnd := FSActLayer; if (TxtHnd<>nil) and (GetType(TxtHnd)=10) then Message('FID = ', GetTextFont(TxtHnd, 0)); END; { End GetFID } Run(GetFID);
  4. MullinRJ

    losing the handle after clip surface..

    You are very welcome and I'm glad I could help. Have a great New Year! Raymond
  5. MullinRJ

    losing the handle after clip surface..

    For even tighter code, the calling procs can be written like this, Rect(1.5, 1, 3.5, 0); KlipSurface(hl, lnewobj, False); KlipSurface(hr, lnewobj, True); if procedure KlipSurface is defined like this, Procedure KlipSurface(var H1 :Handle; H2 :Handle; DelTrimObj :Boolean); HOWEVER, the first way of defining KlipSurface is safer. BECAUSE, if procedure KlipSurface (defined the second way) is called with two user defined handle variables AND DelTrimObj is set to TRUE, then the object referenced by H2 gets deleted, and H2 is set to NIL, but the NIL value is not passed back to the calling procedure. So, Rect(1.5, 1, 3.5, 0); hn := lnewobj; KlipSurface(hr, hn, True); will result in 'hn' being defined incorrectly after the call. If you are careful in your programming skills, then the shorter code looks and reads better, just be careful of the side effects. Happy New Year. HTH, Raymond
  6. MullinRJ

    losing the handle after clip surface..

    Jason, You can get the handle to the new surface with a little finesse. Since it is not obvious where the new object is in the active layer, it is necessary to count the position (N) of the pre-clipped object, and then reassign the handle to the Nth object after clipping. The procedure KlipSurface, in the modified code below, can be used in place of ClipSurface. For tidiness sake, I also added a boolean to the call to delete the clipping object, if so desired. It is assumed that H1 points to an object on the active layer for this procedure to work. If H1 points to an object on another layer, or H1 is NIL, it should do nothing. I hope this helps. Raymond PROCEDURE Notcher; VAR hl, hr, hn :HANDLE; Procedure KlipSurface(var H1, H2 :Handle; DelTrimObj :Boolean); { Clip surface of object pointed to by H1, by object pointed to by H2. } { Return a handle to the new surface in H1. If DelTrimObj is true, } { then delete the trimming object. } Var I, J :Integer; TmpHnd :Handle; Begin { Find position of handle H1 in the stacking order. } I := 0; TmpHnd := LActLayer; while (TmpHnd<>H1) & (TmpHnd<>nil) do begin I := I + 1; TmpHnd := PrevObj(TmpHnd); end; { while } if (TmpHnd<>nil) then begin clipsurface(H1, H2); { Recover handle H1 } H1 := LActLayer; for J := 1 to I do H1 := PrevObj(H1); { Delete trimming object? } if DelTrimObj then DelObject(H2); end; { if (TmpHnd<>nil) } End; { KlipSurface } BEGIN Rect(0, 2, 2, 0); {*first rectangle*} hl := lnewobj; Rect(3, 2, 5, 0); {*SECOND rectangle*} hr := lnewobj; Rect(1.5, 2, 3.5, 1.5); {*Clipper*} hn := lnewobj; KlipSurface(hr, hn, False); KlipSurface(hl, hn, True); Rect(1.5, 1, 3.5, 0); {*next clipper*} hn := lnewobj; KlipSurface(hl, hn, False); KlipSurface(hr, hn, True); END; Run(Notcher);
  7. MullinRJ

    Holiday Wishes To All

    I would like to extend my warmest wishes for this holiday season to all who participate on this board. You have made a big difference in my appreciation for this wonderful product. I especially wish to thank Katie, the two Roberts, Jeff, and the rest of the NNA staff who go well beyond the 9-5 grind to make our lives better. May all your holidays be joyous, your families healthy, and this New Year the best one yet. Happy Holidays, Raymond Mullin
  8. MullinRJ

    Can you help, I'm just getting started.

    << Can I give a group a handle? >> A GROUP is just another object, but it contains objects within it. You can ascertain an objects type by using the GETTYPE(hnd :Handle) function. It will return an integer representing the type of the object currently pointed to by the variable 'hnd'. Group is #11 in the list of object types. The numbers are listed in << Can I give objects dotted linestyles? >> Once you have a handle to your line, set line style and weight using: SetLS (hnd : Handle; LS : Integer); { sets line pattern, LS is between 0 & 71 } SetLS (hnd : Handle; LS : Integer); { sets line style, LS is between -8 & -1 } SetLW (hnd : Handle; LW : Integer); { sets line weight, LW is between 0 & 255 } SetPenFore (hnd : Handle; R,G,B : Longint); { sets foreground line color, R,G,B are between 0 & 65535 } SetPenBack (hnd : Handle; R,G,B : Longint); { sets background line color, R,G,B are between 0 & 65535 and is needed for PATTERNED lines } As you get comfortable getting handles to objects in lists, try using the procedures ForEachObject, ForEachObjectInLayer, & ForEachObjectInList. They will save you a lot of programming if you want to find objects that may be nested in groups or symbols. Though they may be hard to learn at first, you need only come back to this board for even longer diatribes on the subject. Have fun programming. HTH, Raymond PS - If you haven't downloaded the VS Function Reference guide you need to do so. Pick your flavor, Mac or PC, on page Documentation.
  9. MullinRJ

    Can you help, I'm just getting started.

    If you haven't already seen one yet, here is a simple loop that will traverse a list of selected objects on the active layer. The I variable is incremented each time through the loop and displayed in a Message at the end. ************** Procedure ListWalk; VAR hnd : Handle; I :Integer; BEGIN I := 0; { initialize counter } hnd := FSActLayer; { get first object in list } while (hnd <> nil) do begin { test for end of list here } { do things of interest here } I := I + 1; hnd := NextSObj(hnd); { get next Selected object in list } end; { while } If (I=1) then Message ('There is 1 selected object on this layer.') else Message ('There are ', I, ' selected objects on this layer.'); END; Run (ListWalk); ************** continued...
  10. MullinRJ

    Can you help, I'm just getting started.

    justin1974, There is very little you can't do with VectorScript. On the flip side, the really intricate stuff can take a good while to develop. << Does each object have to have its own handle? >> Yes, actually, each object already has a handle which is nothing more than a unique number (an internal address) that is maintained by the software. Your program needs to get handles to the objects before you can do anything to those objects with the VS handle calls. Think of each object on a layer as stacked one on top of another, until you get to the last object created, which is on top of all the others on that layer. It doesn't have to be drawn on top of anything else, but a list of each object is maintained, and that list is ordered. Each layer is actually a doubly-linked list of objects. That means if you have the handle to any object in the list then you can get the handle to the Previous and/or Next object in the list. A CAD file is a giant list of lists. Getting a handle to an object is easy, but knowing what object you have a handle to requires a little care. To get a handle in your program, consider using one of the following commands where 'hnd' is a variable declared as 'HANDLE'. VAR hnd : HANDLE; hnd := FSActLayer; { this is how it's used. } FSActLayer - very popular, gets handle to the First Selected object on the Active Layer. FActLayer - gets handle to the First object on the Active Layer , selected or not. LSActLayer - gets handle to the Last Selected object on the Active Layer. LActLayer - gets handle to the Last object on the Active Layer , selected or not. LNewObj {This one is also very useful as it returns a handle to the Last newly created object on the layer } To get the NEXT or PREVIOUS object in the list, use NextObj or PrevObj respectively. hnd := NextObj(hnd); { This is how it is used } Notice that 'hnd' is passed as an argument to NextObj as that tells NextObj what list you are in and which way you want to go. NEXT takes you toward the top (end) of the list, and PREV takes you to the bottom (front) of the list. When you run out of objects in the list you are traversing NextObj and PrevObj will return the value NIL (a fancy name for zero) to indicate there are no more objects. Further calls to NextObj or PrevObj will result in a runtime error. continued...
  11. MullinRJ

    Object snap - can you turn off "object" only?

    P Retondo, Do you have Snap-to-Surface on at the same time? I have noticed inadvertent snapping, but only when I had multiple constraints on at the same time. If it happens when you only have the Snap-to-Object constraint selected, then you do have a problem. Best wishes, Raymond
  12. MullinRJ


    I ran into this before. I believe I used LObject for the Last Object in the document. Your duplicated object should be the last object until another is created. HTH, Raymond
  13. MullinRJ


    Sorry, on second thought, I believe it was LActLayer for the last object on the active layer. When dupliated, your new object will be on top, and therefore the last object on the active layer. HTH, Raymond
  14. MullinRJ

    thank you

    Thanks, Ionw. I see the difference now. So now Option-Drag is consistent in its treatment of PIO's inserted in walls and the way it affects all other objects. Yes, I can see where that would be a big improvement. Thanks for clarifying. Raymond
  15. MullinRJ

    search criteria

    Amazingly enough, I could not find this info in any of the VS References either, so I typed what I could find here. The list should have more entries due to VW advances, but this should get you started. Sorry, tabs don't make it to the BB. You can replace the ' - ' string to a TAB to get a better view Best wishes, Raymond Criteria Name - Code - Example Arrowhead - AR - (AR=1) Class Name - C - (C='aClassName') Every Object - All - A(All) Fill Background - FB - (FB=1) Fill Foreground - FF - (FF=2) Fill Pattern - FP - (FP=3) Layer Name - L - (L='aLayerName') Line Style - PP - (PP=2) Line Weight - LW - (LW=10) Object Name - N - (N='anObjectName') Object Record - R - (R IN ['aRecordName']) Object Type - T - (T=Rect) Pen Background - PB - (PB=White) Pen Foreground - PF - (PF=Black) Pen Pattern - PP - (PP=4) Selected Status - Sel - (SEL=TRUE) Symbol Name - S - (S='aSymbolName') Visibility - V - (V=TRUE) Object Types are as follows: Line - Line Rectangle - Rect Oval - Oval Polygon - Poly Arc - Arc Freehand line - FHand 3D Locus - Locus3D Text - Text Group - Group Quarter Arc - QArc Rounded rectangle - RRect PICT - PICT BMP - BMP Symbol - Symbol 2D Locus - Locus Worksheet - SprdSheet Polyline - Polyline Extrude - Xtrd 3D Polygon - Poly3D Layer link - LayerLink Sweep - Sweep Multiple extrude - MXtrd Mesh - Mesh Dimension - Dimension Wall - Wall Light - Light Roof / Floor - Slab
  16. MullinRJ

    thank you

    Ionw, I hate to burst your bubble, but Option-Click and Option-Drag for creating duplicates have been around for a long time. They also work on multiply selected objects. After selecting a group of objects, Option-Click or Option-Drag on any one of them and the group is duplicated. The only down side I can think of is that this feature can confuse someone who is not used to using it. I use Option-Drag in conjunction with the Duplicate shortcut (Cmd-D or Alt-D). After duplicating and offsetting the first object, press Cmd-D to repeat the process N times. It's a quick way to duplicate an array of objects. This works until you click elsewhere and then Cmd-D reverts to its default mode. Happy cloning, Raymond
  17. If you keep this up, I'll end up telling you all my secrets... Best wishes, Raymond Procedure GetObjsFromLayer(Lair :String); { Copies all objects from layer LAIR to the active layer. } { Use Cut command if you want to move objects instead. } Var LName :String; Begin LName := GetLName(ActLayer); Layer(Lair); SelectAll; DoMenuTextByName('Copy', 0); Layer(LName); DoMenuTextByName('Paste In Place', 0); End; { GetObjsFromLayer } GetObjsFromLayer{'aLayerName'); { Calling Syntax }
  18. MullinRJ

    Hex Bolt (Inch) Code

    I'm not sure if there are any differences when accessing files from Plug-Ins, but here is a script that will read and write prefs to a tab delimited text file. Sorry about the loss of indentation, it is a victim of this BB. HTH, Raymond Procedure SaveToFile; { Read variables from file. Save new variables if they change. This example saves 2 Reals and an Integer to a tab delimited text file. } CONST FileName = 'RAM Disk:Defaults'; Tb = chr(9); { TAB character } VAR SaveDefaults :Boolean; Int, SavedInt :Integer; X, Y, SavedX, SavedY :Real; Function GetDefaults :Boolean; { Get defaults from file or create them if file does not exist. In VW8.5.2 (Mac), a Caution Dialog appears when the Pref file does not exit, but a new file is created anyway. Clear the dialog and continue. } VAR B :Boolean; Begin Open(FileName); if (GetLastFileErr=0) & not EOF(FileName) then begin Readln(SavedX, SavedY, SavedInt); B := False; end else begin { Initialize defaults if Pref file does not exist } SavedX := 6.5; SavedY := 3.8; SavedInt := 3; B := True; end; Close(FileName); GetDefaults := B; { Will force Pref file to be saved when true } End; { End GetDefaults } Procedure SetDefaults; { Rewrite the Pref file with new values. } Begin Rewrite(FileName); Writeln(X:6:3, Tb, Y:6:3, Tb, Int:1); Close(FileName); End; { End SetDefaults } BEGIN SaveDefaults := GetDefaults; { Read in saved variables } PtDialog('Enter a coordinate. Values must fit on drawing.', num2str(3, SavedX), num2str(3, SavedY), X, Y); if not DidCancel then begin Int := IntDialog('Enter an integer value:', num2str(0, SavedInt)); if not DidCancel then if SaveDefaults | (X<>SavedX) | (Y<>SavedY) | (Int<>SavedInt) then begin { Save prefs and BEEP } SetDefaults; SysBeep; end; end; END; { End SaveToFile } Run(SaveToFile);
  19. MullinRJ

    crashing issues

    If turning off the hatch cured the symptoms, I wouldn't even think of suggesting you poke around with the fonts. Raymond
  20. MullinRJ

    crashing issues

    Joe, Welcome back from spectre land. Here's another shot in the dark. Do you think it may be font related? Do you have differences in the fonts on the two platforms? It's funny you reappeared today. The hyperlinks are changing color on the BB when they are read where they never changed before. It makes it a lot easier to read now. Best wishes, Raymond
  21. MullinRJ

    crashing issues

    Joe, Have you sent the file to any friend(s) and let them try it on their system? If the problem is in the file, it should cause problems on another system, but if the problem is on your computer, the file should open elsewhere. If you would like, I could try it on my machine for you. I am very unbusy right now and can offer you a good bit of my time. I am also running VW 8.5.2 on a G4/500 MHz DP, OS 9.0.4 with 1GB RAM. Good luck, Raymond
  22. MullinRJ

    Lock/Unlock toggle key?

    This has come up several times before. Though there is no direct way to query VS for the Locked attribute, you can use the following function to get the answer. The concept is, if it moves, it's unlocked. Function IsLocked(Hnd: Handle) :Boolean; { Determine LOCKED? by moving object, if it does not move it is locked. } VAR x1, y1, x2, y2, x3, y3 :Real; Begin GetBBox(Hnd, x1, y1, x2, y2); { Get position in (X1, Y1) } HMove(Hnd, 1, 0); { try to move it } GetBBox(Hnd, x2, y2, x3, y3); { Get new position in (X2, Y2) } HMove(Hnd, -1, 0); { if it moved, move it back } IsLocked := x1 = x2; End; { End IsLocked } HTH, Raymond
  23. MullinRJ

    Polygon vs. Polyline

    How many points are in your single segment polylines? 2? I tried creating a 3 point Polyline and deleting the middle point. It worked, and it still stayed a Polyline with 2 points. How goes it in your PIO? Raymond
  24. MullinRJ

    Polygon vs. Polyline

    If all the points between BeginPoly and EndPoly are created with LineTo, then the object type will default to Polygon (but you already know this). Try adding a dummy CurveTo point as your second point and then delete it immediately after you issue the EndPoly. The type will stay as a PolyLine. I tried adding a Dummy Point as the last point, but deleting it closed the Poly, which may, or may not affect your routine. Also, if you add it as the second point, you always know where it is and can delete it without having to calculate the size of the Poly. Here's a simple example that leaves the type as PolyLine. I tried it as a stand alone script in 8.5.2, but not as a PIO, and it worked. It should still work in 9.5. BeginPoly;MoveTo(-1.2, 1.9);CurveTo(0, 0); { Dummy point }LineTo(1.9, 1);LineTo(0.1, -0.8);LineTo(0.8, -1);LineTo(3.6, 1.4);EndPoly;DelVertex(LObject, 2); HTH,Raymond
  25. MullinRJ

    Previous View

    He may have, but he was using a PI substitute (22/7 = 3.142857...), so his area calculations will a tad large. 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.