  # Julian Carr

Distributor

258

## Posts posted by Julian Carr

1. ### Script to change render mode to wireframe

Try this Max:

2. ### Point along 3D Poly

If you convert the 3D poly to a NURBs curve using ConvertToNURBS() then you should be able to use one of the NURBs calls like NurbsCurveEvalPt().

• 1
3. ### Decimal Feet to Feet & Ins

Thanks to everyone for your help with this. It was actually for a worksheet script to enable door thicknesses to be listed at smaller increments than the document units settings allowed. Below is the final code. I saved the script with the name 'WSFixDoorThickness' so the cell formula to use it would be:

=RUNSCRIPT('WSFixDoorThickness')

This replaced the standard:

=(Door.DoorThickness)

In Vw 2021, it would be possible to use RUNEDITSCRIPT() instead and so allow the door thickness to be modified from the worksheet too. It was beyond the remit of this little project however so currently it only reports door the thickness.

```{ FDT (Fix Door Thickness) - v1.0 - 27/10/2020 }
Procedure FDT;
VAR
gr1 : REAL;
gh1 : HANDLE;
gs1 : STRING;
Function Num2FandI(r1 : REAL) : STRING;
Const
kBase = 16;
VAR
DecPart:    REAL;
IntPart, FracPart:    LONGINT;
RetFract : STRING;
BEGIN
IntPart := TRUNC(r1);
DecPart := r1 - IntPart;
FracPart := Round(DecPart * kBase);
Num2FandI := Concat(IntPart, ' ',FracPart, '/', kBase, '"');
CASE FracPart OF
0: RetFract := '';
1: RetFract := '1/16';
2: RetFract := '1/8';
3: RetFract := '3/16';
4: RetFract := '1/4';
5: RetFract := '5/16';
6: RetFract := '3/8';
7: RetFract := '7/16';
8: RetFract := '1/2';
9: RetFract := '9/16';
10: RetFract := '5/8';
11: RetFract := '11/16';
12: RetFract := '3/4';
13: RetFract := '13/16';
14: RetFract := '7/8';
15: RetFract := '15/16';
16: BEGIN
IntPart := IntPart + 1;
RetFract := '';
END;
END;
Num2FandI:=Concat(IntPart, ' ',RetFract, '"');
END; { Num2FandI }
BEGIN
gh1 := WSScript_GetObject;
gs1 := GetRField(gh1, 'Door', 'DoorThickness');
IF ValidNumStr(gs1, gr1) THEN WSScript_SetResStr(Num2FandI(gr1));
END;
Run(FDT);```

• 1
4. ### Decimal Feet to Feet & Ins

Anyone have a routine for converting decimal inches into fractions, irrespective of the document unit settings? For example:

1.375 -> 1 3/8"

1.188 -> 1 3/16"

1.75 -> 1 3/4"

1.5 -> 1 1/2"

4.25 -> 4 1/4"

Thanks!

5. ### Determining String Array Quantity

Thanks Josh. This enabled me to discover that the array size is fixed at 20, which means you can only apply a maximum of 20 tags to an object.

6. ### Determining String Array Quantity

The function GetObjectTags() returns a string array of all the tags attached to a class, layer or other object that supports tags (not to be confused with Data Tags). Once you have the string array, how can you extract each tag when you don't know the separator or quantity of strings? The separator is likely to be a line feed or carriage return, but could be different on each platform.

One way would be to keep extracting strings s, s, s, etc until there was an error, but that seems crude. Any ideas?

7. ### {Error: Expected BEGIN} {Error: Expected a RUN statement at the end of the script}

You cannot do this:

AlrtDialog:    STRING;

because you are declaring a procedure as a string. Either delete that line or try this:

AlrtDialog2:    STRING;

Either way it will work.

8. ### {Error: Expected BEGIN} {Error: Expected a RUN statement at the end of the script}

Two things wrong.

1. N should be an integer not a string.

2. AlrtDialog cannot be used as a string because it is a reserved word being a procedure.

• 1
9. ### point in parametric object inside other object boundary?

You need to get the insertion point of the PIO using GetSymLoc() then add the internal offset within the PIO to that.

• 1
10. ### point in parametric object inside other object boundary?

You could try :
PtInPoly(pX, pY : REAL; h : HANDLE):BOOLEAN;

11. ### Page Size

You cannot access the printer settings in Vectorscript. There may also be a physical limit on the page dimensions in the OS. At least that used to be the case.

12. ### Page Size

This is what I use to get the page dimensions. Note it works on the active layer so you have to store the active layer name, switch to the layer you are querying, then back again on completion. Also note it is returning mm:

Procedure GetDrawingSizeRect2(VAR dx1, dy1, dx2, dy2 : REAL; VAR PageWdth, PageHght : INTEGER);
VAR
s1, s2 : STRING;
r1 : REAL;
BEGIN
IF NOT IsNewCustomObject(gPIOName) THEN BEGIN
s2 := GetLName(ActLayer);
s1 := GetLName(GetLayer(ghParm));
IF (s1 <> '') & (GetType(GetObject(s1)) = 31) THEN Layer(s1) { switch layers so that GDSR() measures active layer (for use with RIP command }
ELSE s1 := '';
END;
GetDrawingSizeRect(dx1, dy1, dx2, dy2);
r1 := GetLScale(ActLayer); { use this here instead of gLScale because GetDrawingSizeRect() is using the active layer, not the PIO layer }
IF s2 <> '' THEN Layer(s2);
PageWdth := Abs(dx2 - dx1) / r1 * 25.4 / gUPI; { page width in mm } { use gLScale here so that comparisons are in real world sizes, not scaled }
PageHght := Abs(dy2 - dy1) / r1 * 25.4 / gUPI; { page height in mm }
END;

You can use SetDrawingRect() to set the page size, though you need to consider that the drawing size rectangle represents the printable area for the currently selected printer, not the actual page size. I have a routine that tries to match the drawing size rectangle to the metric or imperial page size. Here's part of it:

CONST

kPS1m = 148; { ISO Sizes including Super A3 }
kPS2m = 210;
kPS3m = 297;
kPS4m = 420;
kPS5m = 594;
kPS6m = 841;
kPS7m = 1189;
kPS8m = 707;
kPS9m = 1000;
kPS10m = 1414;
kPS11m = 330; { 13" Super A3 }
kPS12m = 483; { 19" Super A3 }

kPS11i = 229; { 9" } { US Arch Sizes }
kPS12i = 305; { 12" }
kPS13i = 457; { 18" }
kPS14i = 610; { 24" }
kPS15i = 914; { 36" }
kPS16i = 1219; { 48" }

kPS17i = 216; { 8.5" } { ASME Sizes }
kPS18i = 279; { 11" }
kPS19i = 432; { 17" }
kPS20i = 559; { 22" }
kPS21i = 864; { 34" }
kPS22i = 1118; { 44" }

CASE gPageFormat OF { if possible, set page size string from found page dimensions }
1: BEGIN { ISO }
IF ((PageWdth = kPS2m) & (PageHght = kPS1m)) | ((PageWdth = kPS1m) & (PageHght = kPS2m)) THEN PageSize := 'A5'
ELSE IF ((PageWdth = kPS3m) & (PageHght = kPS2m)) | ((PageWdth = kPS2m) & (PageHght = kPS3m)) THEN PageSize := 'A4'
ELSE IF ((PageWdth = kPS4m) & (PageHght = kPS3m)) | ((PageWdth = kPS3m) & (PageHght = kPS4m)) THEN PageSize := 'A3'
ELSE IF ((PageWdth = kPS5m) & (PageHght = kPS4m)) | ((PageWdth = kPS4m) & (PageHght = kPS5m)) THEN PageSize := 'A2'
ELSE IF ((PageWdth = kPS6m) & (PageHght = kPS5m)) | ((PageWdth = kPS5m) & (PageHght = kPS6m)) THEN PageSize := 'A1'
ELSE IF ((PageWdth = kPS7m) & (PageHght = kPS6m)) | ((PageWdth = kPS6m) & (PageHght = kPS7m)) THEN PageSize := 'A0'
ELSE IF ((PageWdth = kPS9m) & (PageHght = kPS8m)) | ((PageWdth = kPS8m) & (PageHght = kPS9m)) THEN PageSize := 'B1'
ELSE IF ((PageWdth = kPS10m) & (PageHght = kPS9m)) | ((PageWdth = kPS9m) & (PageHght = kPS10m)) THEN PageSize := 'B0'
ELSE IF ((PageWdth = kPS12m) & (PageHght = kPS11m)) | ((PageWdth = kPS11m) & (PageHght = kPS12m)) THEN PageSize := 'Super A3'
ELSE FlagCustom := True;
END;
2: BEGIN { US Arch }
IF ((PageWdth = kPS12i) & (PageHght = kPS11i)) | ((PageWdth = kPS11i) & (PageHght = kPS12i)) THEN PageSize := 'US Arch A'
ELSE IF ((PageWdth = kPS13i) & (PageHght = kPS12i)) | ((PageWdth = kPS12i) & (PageHght = kPS13i)) THEN PageSize := 'US Arch B'
ELSE IF ((PageWdth = kPS14i) & (PageHght = kPS13i)) | ((PageWdth = kPS13i) & (PageHght = kPS14i)) THEN PageSize := 'US Arch C'
ELSE IF ((PageWdth = kPS15i) & (PageHght = kPS14i)) | ((PageWdth = kPS14i) & (PageHght = kPS15i)) THEN PageSize := 'US Arch D'
ELSE IF ((PageWdth = kPS16i) & (PageHght = kPS15i)) | ((PageWdth = kPS15i) & (PageHght = kPS16i)) THEN PageSize := 'US Arch E'
ELSE FlagCustom := True;
END;
3: BEGIN { ASME }
IF ((PageWdth = kPS18i) & (PageHght = kPS17i)) | ((PageWdth = kPS17i) & (PageHght = kPS19i)) THEN PageSize := 'ASME A'
ELSE IF ((PageWdth = kPS19i) & (PageHght = kPS18i)) | ((PageWdth = kPS18i) & (PageHght = kPS19i)) THEN PageSize := 'ASME B'
ELSE IF ((PageWdth = kPS20i) & (PageHght = kPS19i)) | ((PageWdth = kPS19i) & (PageHght = kPS20i)) THEN PageSize := 'ASME C'
ELSE IF ((PageWdth = kPS21i) & (PageHght = kPS20i)) | ((PageWdth = kPS20i) & (PageHght = kPS21i)) THEN PageSize := 'ASME D'
ELSE IF ((PageWdth = kPS22i) & (PageHght = kPS21i)) | ((PageWdth = kPS21i) & (PageHght = kPS22i)) THEN PageSize := 'ASME E'
ELSE FlagCustom := True;
END;
END;

13. ### Flipped Symbols in Walls

GetSymRot(ghParm) and IsObjectFlipped(ghParm) need to be used in combination to get the flip status. I doubt whether you can find something that will flip a symbol however.

14. ### pref # for Automatic Drawing Coordination

To date I have only ever read this value and never tried to write to it. That said, this seems to work for toggling the setting on or off using Vectorscript:

SetPref(544, NOT GetPref(544));

Perhaps someone else with Python knowledge can spot something in your script.

15. ### pref # for Automatic Drawing Coordination

Try GetPref(544).

16. ### Upper Case String to Title Caps

Anyone have a lazy script that will convert an upper case string to title caps or even just lower case? Just trying to avoid reinventing the wheel.

TIA,

Julian

17. ### User input and alterations while running script

In my experience, user input interruptions in Vectorscript are very very limited and often unreliable, and I suspect it would be the same in Python. You really need to go to the SDK for things like this.

• 2
18. ### Extending a line from it's center

While is seems logical to try and emulate how you work with the mouse to select objects then edit them in some way, if you want to get into scripting then you'll find it much easier to work with handles. And the single most useful call for this is ForEachObject(), because it uses criteria to choose what gets processed. This can be object type, class, layer, colour, selection state, etc. Using FEO would look something like this:

Procedure T;
VAR
grNewLen : REAL;

Procedure DoIt(h1 : HANDLE);
VAR
rCenterX, rCenterY : REAL;
rScaleFactor : REAL;
rExistLen : REAL;
BEGIN
HCenter(h1, rCenterX, rCenterY);
rExistLen := HLength(h1);
rScaleFactor := (rExistLen + grNewLen) / rExistLen;
HScale2D(h1, rCenterX, rCenterY, rScaleFactor, rScaleFactor, False);
END;

BEGIN { main }
grNewLen := RealDialog('New Length?', '2');
IF NOT DidCancel THEN ForEachObject(DoIt, (T = Line));
Redraw;
END;
Run(T);

19. ### Extending a line from it's center

Pat is right. Scaling the line using HScale2D is the way to go and it is easy enough:

Procedure T;
VAR
h1 : HANDLE;
rCenterX, rCenterY : REAL;
rScaleFactor : REAL;
rExistLen, rNewLen : REAL;
BEGIN
h1 := FSActLayer;
HCenter(h1, rCenterX, rCenterY);
rExistLen := HLength(h1);
rNewLen := RealDialog('New Length?', Concat(rExistLen));
rScaleFactor := rNewLen / rExistLen;
HScale2D(h1, rCenterX, rCenterY, rScaleFactor, rScaleFactor, False);
Redraw;
END;
Run(T);

20. ### VS SetColorButton does not seem to work

Yes, in an old PIO. It still works in 2020. Here is the code:

Function GetColourIndex(CurrentIndex : INTEGER) : INTEGER;
VAR
DialogID, DlogResult : INTEGER;

Function Define_Dialog: INTEGER;
VAR
dialogID : INTEGER;
BEGIN
dialogID := CreateLayout('Choose Colour', False, 'OK', 'Cancel');
CreateGroupBox(dialogID, 4, '', False);
CreateControl(dialogID, 5, 2,'',0);
SetFirstLayoutItem(dialogID, 4);
SetBelowItem(dialogID, 4, 5, 5, 0);
Define_Dialog := dialogID;
END;

Procedure Drive_Dialog(VAR item:LONGINT; data:LONGINT);
VAR
red, green, blue : LONGINT;
BEGIN
CASE item OF
SetupDialogC: BEGIN
ColorIndexToRGB(CurrentIndex, red, green, blue);
SetColorButton(DialogID, 5, red, green, blue);
END;
1: BEGIN
GetColorButton(DialogID, 5, red, green, blue);
RGBToColorIndex(red, green, blue, GetColourIndex);
END;
2: GetColourIndex := CurrentIndex;
END;
END;

BEGIN
DialogID := Define_Dialog;
IF VerifyLayout(DialogID) THEN DlogResult := RunLayoutDialog(DialogID, Drive_Dialog);
END;

21. ### Image background for CreateLayout

There is no official way to do it, however if you used CreateImageControl2() to insert the image as the first item in the dialog, you could probably then use SetBelowItem() with a large negative Y value to place the next item over the image and subsequent items below that. You will need to create a VWR file to store the image, which is simply a zip file of the image or images (without a parent folder), which you then just change the file suffix from .zip to .vwr.  If your zip/vwr file was called MyImages.vwr, and the image in there was called image1.png (use png images), then the call to place the image would be something like this:

CreateImageControl2        (Dialog1, ItemID, 500, 400, 'MyImages/image1.png');

The VWR file lives in the Plug-ins folder and 500/400 is the pixel size you want the image to appear in the dialog. Just make sure to preserve the image proportions. For example, this would work if the actual image was 1000 x 800 pixels, or 1500 x 1200, etc.

22. ### Replacement command for deprecated SetWallHeights()

SetWallCornerHeights() might work.

• 1
23. ### Sheet Layer Number and Name Export

Thanks a lot Pat and Ray. I cobbled something together from what you sent.

24. ### Sheet Layer Number and Name Export

Anyone have a script handy that will export a list containing sheet layer names and numbers?

TIA.

25. ### Detect document zoom change in PIO

I guess the first question is why does your PIO need to reset when the zoom level changes? Generally this should not be necessary. Ignoring that for the moment, if this were possible it could only work in an event enabled PIO using SetObjPropVS(). I don't have the full list at hand, but this is the function that allows PIOs to reset if there are layer scale or layer elevation changes, for example.