Jump to content
Jord Visser

Trouble with getting the right Crop position after viewport moves

Recommended Posts

Hi all,

 

I'm making a plug-in which needs knowledge of the exact viewport-crop position in relation to the plug-in position in the Annotation group of the viewport, when moving/rotating the viewport a problem occurs.

 

I attached a sample document & the .vso plugin.

How to replicate the problem:

 - Have a viewport with and crop object

- Place the plug-in in the annotation group of this viewport

- exit the annotation group

- move / rotate de viewport

 

	PROCEDURE CropDupeTest;
VAR
    result                                    :BOOLEAN; {temporary store for BOOL results}
	    objectName                                :STRING;
    objectHandle, recordHandle, wallHandle    :HANDLE;
    
    eventInfo, eventType                    :LONGINT;
    pluginObjectExists                        :BOOLEAN;
    
    pluginRotation                            :REAL;
    pluginPosition                            :VECTOR;
	    vpRotation                                :REAL;
    vpPosition                                :VECTOR;
    vpScale                                    :REAL;
    
    vpCropObject                            :HANDLE;
    bbHandle                                :HANDLE; {copy of crop object into plugin}
    
    x, y, z                                    :REAL;
    is3D                                    :BOOLEAN;
    
    userShowUnitMark                        :BOOLEAN;
    docUnitsPerInch                            :REAL;
	
PROCEDURE reDraw;
BEGIN
    Rect(-5m,-5m, 5m, 5m);
    Locus(0, 0);
    
    TextJust(2);
    TextVerticalAlign(3);
    
    MoveTo(0, 1m);
    CreateText('Plugin');
    
    MoveTo(0, -1m);
    CreateText('Origin');
    
    result := vsoStateGetPos( objectHandle, x, y, z, is3D );
    MoveTo(0, -2m);
    CreateText( Concat('Object movement=', result,'  offset=(x=', x, ', y=', y, ', z=', z, ') is3DMove=', is3D ) );    
    SetTextStyle(LNewObj, 0, GetTextLength(LNewObj), 2);
END;
	PROCEDURE setBaseVariables;
BEGIN
    vpCropObject := NIL;
END;
	PROCEDURE loadBaseInfo;
BEGIN
    GetSymLoc(objectHandle, pluginPosition.x, pluginPosition.y);
    pluginRotation := GetSymRot(objecthandle);
                    
    {not used}
    vpScale := GetObjectVariableReal(GetVPGroupParent(GetParent(objectHandle)), 1003);
    vpPosition.x := GetObjectVariableReal(GetVPGroupParent(GetParent(objectHandle)), 1024);
    vpPosition.y := GetObjectVariableReal(GetVPGroupParent(GetParent(objectHandle)), 1025);
    vpRotation := GetObjectVariableReal(GetVPGroupParent(GetParent(objectHandle)), 1026);
    docUnitsPerInch := GetPrefReal(152);
END;
	PROCEDURE loadCropObject;
BEGIN
    IF VPHasCropObject(GetVPGroupParent(GetParent(objectHandle))) THEN BEGIN
        vpCropObject := GetVPCropObject(GetVPGroupParent(GetParent(objectHandle)));
            
        bbHandle := ConvertToPolygon(vpCropObject, 30);
        HMove(bbHandle, -pluginPosition.x, -pluginPosition.y);
        HRotate(bbHandle,  0, 0, -pluginRotation);
    END;
END;
	BEGIN
    {Store & adjust user settings}
    userShowUnitMark := GetPref(163);
    SetPref(163, FALSE);
    PushAttrs;
    
    setBaseVariables;
    
    pluginObjectExists := GetCustomObjectInfo(objectName, objectHandle, recordHandle, wallHandle);
    vsoGetEventInfo(eventType, eventInfo);
    
    CASE eventType OF
        5: {kObjOnInitXProperties}
        BEGIN
            SetPrefInt( 590, 1 ); {varParametricEnableStateEventing, kParametricStateEvent_ResetStatesEvent}
            result := SetObjPropVS(18, TRUE); {kObjXPropAcceptStates}
            
            {fallback to ensure good redraw before export}
            result := SetObjPropVS(23, TRUE); {kObjXPropResetBeforeExport}
        END;
	        44: {kObjOnAddState}
        BEGIN
            eventInfo := vsoStateAddCurrent( objectHandle, eventInfo );
        END;
	        45: {kObjOnContextMenuInit}
        BEGIN
            {.......}
        END;
	        46: {kObjOnContextMenuEvent}
        BEGIN
            {.......}
        END;
	        3: {kParametricRecalculate}
        BEGIN
            IF pluginObjectExists THEN BEGIN
                IF NOT GetPref(531) THEN BEGIN
                    IF objectHandle <> NIL THEN BEGIN
                        IF NOT IsNewCustomObject(objectName) THEN BEGIN
                            SetObjectVariableBoolean(objectHandle, 800, TRUE); {Accept text styles}
	                            loadBaseInfo;
                            loadCropObject;
                            reDraw;
	                            IF vpCropObject <> NIL THEN BEGIN
                                {Temporary crop duplicate placement for visibility}
                                HMoveBackward(bbHandle, TRUE);
                                SetFPat(bbHandle, 0);
                                
                                {Clean up the crop duplicate after use}
                                {DelObject(bbHandle);}
                            END;
                        END;
                    END;
                END ELSE BEGIN
                    Rect(-1m, -1m, 1m, 1m);
                END;
            END;
	            vsoStateClear(objectHandle);
        END;
    END;
	    {Restore user settings}
    PopAttrs;
    SetPref(163, userShowUnitMark);
END;
Run(CropDupeTest);
	

[LT] Crop Dupe Test.vso

crop_dupe_test.vwx

Share this post


Link to post

I think i know what is happening.

I looks to me that the viewport logic first updates the annotation group before updating the crop object.
I think this is due to the fact that the annotation group is needed to create the selection group.

I'm going to try to save the state of the viewport within the plug-in and compare this on redraw to get to know if the parametrics of the viewport changed.

Are there any core developers over here whom can explain the inner workings of the viewport object?

Share this post


Link to post

From what I've seen myself trying out the plug-in I believe you are correct.
You even get the same behaviour when you edit the crop, your plug-in is always one step behind.

Assuming your findings are correct, you need an additional reset of the parent object, the viewport in this case:

Add a hidden parameter to your object, BOOLEAN default to FALSE. 

Whenever your code runs, load the value.
If it's 0 make it 1 and call a RESET to the parent object if it is a viewport. This will cause an additional reset of your object.
Since the value now is 1, make it zero again but don't reset the parent object or you end up in an endless loop.

In short, the viewport resets your object for the first time. Now your frame is at the wrong position. You then call a reset on the viewport. 
If lucky, the viewport now did recalculate it's other group properly. The second reset of your object now draws correctly and stops the loop.

This is far from ideal and there are other/better ways of doing this but I don't think such functionality is available for VS.
 

 

Edited by Hippocode

Share this post


Link to post

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.


 

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.

×
×
  • Create New...