Jump to content
Developer Wiki and Function Reference Links ×

VW 2010 Door PIO causes crash when running script?


David L

Recommended Posts

I created VectorScript commands for numbering doors and windows in VW2009. The window numbering scripts work fine but the door numbering scripts cause VectorWorks 2010 to quit whenever they are run. The scripts are the same, except using door criteria in one and window criteria in the other. In fact, I took the window script and modified only the Criteria specification to work on doors and it started crashing when run.

(A sample drawing with scripts is attached)

The door tool appears to be unchanged from VW2009 and the scripts work fine in 2009 without crashing. You can try the 2009 version of file.

I would appreciate it if somebody can figure out what the problem is.

Link to comment

I have not isolated it yet, but it appears to be a crash due to trying to ResetObject with a nil handle;

I don't know why the window one does not crash and the door one does.

I don't mean to slam you, but the code can be cleaned up a lot. I will try to find some time to work on it tomorrow.

As a start, the first SetDoorNumber should probably be replaced with a simple GetPt. Other wise you don't get any handles on your first click.

Also, since you are limited to text that can be converted to a string, why all of the switching back and forth between text and number. Just use the number and convert to text when needed.

I think if you add a redraw you MIGHT be able to get the IDs to update before the end of the script.

Maybe some additional items tomorrow.

Link to comment

Pat, I appreciate the help. I'm sure all of the Vectorscripts I've created could be cleaned up, quite a bit. I have no programming background or training, so everything I've done is strictly constructed through a lot of reading of the Language Guide and the Function Reference and looking at examples of scripts, where I could find them.

My biggest problem is I know what I want to accomplish and I understand the basic constructs of the language, but finding the best or most efficient predefined procedures and functions to use is very difficult. Plus, the explanations of those procedures and functions are often quite cryptic for the uninitiated.

Typically if I can get something to compile and work as expected, I'm happy, regardless of how inelegant the code is.

Per the SetDoorNumber procedure, that was the first way I could figure out how to test if the object being clicked on was actually a door. While the script is running you can click on any object you want, but only clicking on a door will cause the number to increment.

Also, the SetRField( ) procedure requires a string and I couldn't figure our how to increment a text string (number), so I took a number, incremented it then converted it to text for use in the procedure, then back to a number to increment it, etc, etc. That?s the reason for the switching back and forth between text and number.

Getting the IDs to update, during execution, was another thing I tried to do, but was unsuccessful. I believe I posted a question on that, but got no solution. Seems like somebody said you could get IDs to update if it was a Tool, but making the numbering a Tool had other problems, so I left it at that.

I'm sure there are better ways to do these things, but I got what I wanted to work so I moved on.

BTW: The Door and Window tools, in VectorWorks, should have an automatic numbering function built in, so they could be aware of all of the other Door and Window PIOs in the drawing and automatically update their numbering when one is added or removed from a plan. On commercial projects I use an opening numbering system that is associated with the room number (Room-101 gets doors 101A, 101B, etc). That numbering system is also in the attached sample drawings. I would guess that system would be nearly impossible to implement in the Door and Window PIOs.

Thanks for the education.

Link to comment

David,

It definitely seems to be a bug in the ResetObject call on the door. I can make the same crash happen with the following script.

It appears that you can use a ForEachObject call with a reset there and ti does not crash. So if you have a reasonable number of doors you could go through and add update the numbers and then at the end of the script use a ForEachObject to reset every door in the drawing. It might take slightly longer, but probably not excessively.

Let me know if you need help setting the script up that way.

PROCEDURE Test;

VAR

???h1,h2 : HANDLE;

???pX,pY : REAL;

???dummyVar: INTEGER;

BEGIN

GetPt(pX,pY);

??WHILE GetPickObjectInfo(pX,pY,h1,h2,dummyVar) DO

BEGIN

?? ??ResetObject(h2);

GetPt(pX,pY);

??END;

END;

RUN(Test);

Link to comment

Pat,

I tried your script that isolates the ResetObject( ) procedure and it crashes VectorWorks every time. I tried several other things but none of them fixed the problem.

1. Set procedure to ResetObject(h) ? Resetting wall has no effect, does not change door ID.

2. Applied script above to doors placed in space (so they are not subhandles) ? No effect, does not change door ID.

3. Applied Door Numbering (Consec) script to doors placed in space ? Crashed VectorWorks.

4. Created default unstyled wall (in None class) and placed default door PIOs ? Crashed using original Door Numbering (Consec) script.

5. Replaced procedure ResetObject(h2) with ResetBBox(h2) ? No effect, does not change door ID.

(Revised test drawing is attached)

Evidently something was changed in the Door PIOs so they are not compatible with the ResetObject( ) procedure. You'd think the same problem would exist with Window PIOs?

I sent the original problem in as a Bug Submittal. Will advise tech support of this thread.

Link to comment

Yep either ResetObject or the Door PIO is broken.

I submitted a bug also.

I just tried my idea about using a ForEachObject to reset all the doors and it crashes VW also.

I guess you are out of luck for now.

Weirdass inconvenient workaround. Take the ResetObject out of the script. Run the script and click on the doors to number them. Select the doors that have been numbered. Go to the OIP and toggle off and then back on the check box for On Schedule. The updated door numbers will show.

Link to comment

That?s interesting. I inserted your script above into my script and it still crashes. Maybe I don't fully understand how handles are passed (that was one of the hardest concepts for me to get a handle on ;-)

I thought this would generate a new handle to the door PIOs, But it doesn't work inside this script.

PROCEDURE NumberDoorsConsecutive;

VAR

???numberStr : STRING;

???h,h2 : HANDLE;

???pX,pY : REAL;

???doorNumber,dummyVar : INTEGER;

PROCEDURE SetDoorNumber;

BEGIN

GetPt(pX,pY);

??{### Test if clicked object is a DOOR, skip incrementing number if not DOOR ###}

??IF GetRField(h2,'Door','DoorWidth') <> '' THEN BEGIN

????SetRField(h2,'Door','IDLabel',numberStr);

????{ResetObject(h2);?????????}

????doorNumber := Str2Num(numberStr); {convert number string to number}

????numberStr := Num2Str(0, doorNumber + 1); {increment number then convert number to string}

??END;

END;

PROCEDURE DoIt(h3:Handle);

Begin

ResetObject(h3);

End;

BEGIN

{### Ask for starting number ###}

numberStr := StrDialog('Enter and INTEGER to start numbering:','101');

Message('Click in empty space to end Door numbering');

SetDoorNumber;

??{### Repeat process until there is NO object at the clicked location ###}

??WHILE GetPickObjectInfo(pX,pY,h,h2,dummyVar) DO BEGIN

????SetDoorNumber;

??END;

ClrMessage;

ForEachObject(DoIt,((PON='Door')));

END;

RUN(NumberDoorsConsecutive);

Link to comment

You can't really generate a "NEW" handle to an object. Each object has a handle. You can assign that handle to as many "NEW" variables as you want, but you still only have one handle.

Think about a book in a library. It has a unique number (eg. 306.7DIA) that call number is the handle that you use to go and find the book (object) when you need it. You don't have to move the entire book, just the handle as you can use the handle to find the book. It does not matter if the librarians rearrange the library, as long as you can find the 306 shelf, you can find the book.

The analogy breaks down slightly when you talk about duplicating object. But even then a second copy of a book typically has an exact call number (eg. 306.7DIA cp.2)

When you duplicate an object the duplicate has a new and unique handle totally separate from the original object.

As I said in an earlier post, it is a strange bug. If you run the reset in a total separate procedure it does not crash VW. If you put it in the same procedure as the SetRField, it does crash.

Hopefully it will be fixed soon.

Link to comment
Guest Frank Brault

A temporary solution might be to check if the handle is nil before running the ResetObject() call:

Procedure DoIt(H1:Handle);
Begin
If H1 <> NIL then ResetObject(H1);
End;

If it still crashes, that would tell you something that you don't know yet.

Link to comment

Frank,

At first I thought that GetRfield may have been the problem because h2 is nil on the first pass of SetDoorNumber.

But I reworked the script so that it checks for a nil handle. I used the debugger to step into each line of code and it completes without any errors. VW crashes after the script completes and it tries to reset the door PIO.

PROCEDURE NumberDoorsConsecutive2;

{DEBUG}

VAR

?? numberStr : STRING;

h,h2 : HANDLE;

pX,pY : REAL;

done: BOOLEAN;

doorNumber,dummyVar : INTEGER;

FUNCTION IsDoor(doorHdl: HANDLE): BOOLEAN;

VAR

lastRec: INTEGER;

recHdl: HANDLE;

recName: STRING;

BEGIN

lastRec:= NumRecords(doorHdl);

recHdl:= GetRecord(doorHdl,lastRec);

recName:= GetName(recHdl);

IF recName = 'Door' THEN

IsDoor:= TRUE

ELSE

IsDoor:= FALSE;

END;

PROCEDURE SetDoorNumber;

BEGIN

numberStr := Num2Str(0, doorNumber); {convert number to string}

SetRField(h2,'Door','IDLabel',numberStr);

ResetObject(h2);

doorNumber := doorNumber + 1; {increment door number}

END;

BEGIN

{### Ask for starting number ###}

doorNumber:= IntDialog('Enter and INTEGER to start numbering:','101');

IF NOT DidCancel THEN

BEGIN

Message('Click in empty space to end Door numbering');

done:= FALSE;

REPEAT

GetPt(pX,pY);

IF GetPickObjectInfo(pX,pY,h,h2,dummyVar) & (h2 <> NIL) THEN

BEGIN

IF IsDoor(h2) THEN

SetDoorNumber;

END

ELSE

done:= TRUE;

UNTIL done;

ClrMessage;

END;

END;

RUN(NumberDoorsConsecutive2);

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...