Author Topic: Updating model space display extents  (Read 9254 times)

0 Members and 1 Guest are viewing this topic.

shawndoe

  • Guest
Updating model space display extents
« on: March 17, 2010, 04:16:32 PM »
Hi,

I'm working on my first ARX routine.  It resizes the drawing frame so I can adjust it's aspect ratio.  This works fine, but my routine is called from inside a LISP.  I don't know how to cause the system variables to update, for a zoom extents before the LISP exits.  I only have the default model space viewport.  I suspect I need to change the model space viewport settings, but I'm not sure how.  I have posted my code so you can see what I am trying to do.

Code: [Select]
static void SetDwgWindow_SetWindow(void) {
int Width = 0; // 830
int Height = 0; // 564
acedGetInt (_T("\nEnter a new width in pixels for the drawing window: "), &Width);
acedGetInt (_T("\nEnter a new height in pixels for the drawing window: "), &Height);
CRect rect (0, 0, 2 * Width, 2 * Height);
CRect ChildRect (0, 0, Width, Height);
//
//
//
CWnd* DocFrame = acedGetAcadDwgView()->GetParent();
DocFrame->MoveWindow (ChildRect);
DocFrame->UpdateWindow ();
}//SetDwgWindow

Should I use the acdbViewport class for this?  I'll take any hint I can get.

Thanks for the help, and have a good one.
Shawn

LE3

  • Guest
Re: Updating model space display extents
« Reply #1 on: March 17, 2010, 05:35:09 PM »
Have you read/study about updateExt() ?

Here are the steps:
1. Define a AcDbViewTableRecord
2. You will need to extract the previous values of extmax() and extmin()
3. From the above values calculate AcGePoint2d's
4. Calculate/set the center point of the view setCenterPoint()
5. Define the height and width with setHeight() and setWidth()
6. Set the current view with acedSetCurrentView()
7. And update the extents with a call to updateExt() read about this and see what parameter fits better for your usage.

Good luck, ARX will require from you to get more involved.

shawndoe

  • Guest
Re: Updating model space display extents
« Reply #2 on: March 17, 2010, 08:45:00 PM »
Hi,

MP was that a stick you were poking at me?   :?  :wink:

Thanks again for your help LE.  Actually I am much more involved when I feel I have something to contribute, but truthfully I rarely need to ask a question, because I'm pretty good at searching out what I need.  It's just that there is a much more limited pool of information to search on for ARX. 

Code: [Select]
//
// Test of VP Reset
//
AcDbViewTableRecord View;
AcDbExtents ExtentsTest;
AcGePoint2d ExtentsMax_2d (ExtentsTest.maxPoint()[X], ExtentsTest.maxPoint()[Y]);
AcGePoint2d ExtentsMin_2d (ExtentsTest.minPoint()[X], ExtentsTest.minPoint()[Y]);
View.setCenterPoint (ExtentsMin_2d + (ExtentsMax_2d - ExtentsMin_2d) / 2.0) ;
View.setHeight (ExtentsMax_2d[Y] - ExtentsMin_2d[Y]) ;
View.setWidth (ExtentsMax_2d[X] - ExtentsMin_2d[X]) ;
//
//
acedSetCurrentView (&View, NULL);
acdbHostApplicationServices()->workingDatabase()->updateExt(TRUE);
//
// End of VP Reset
//

It is not zooming any differently, so clearly I am doing something wrong, though I don't get any errors or warnings during compile or when I run it.  Am I using updateExt() properly, what am I missing?

Thanks again for your help, as I get better I will try to help out here more.

Have a good evening.
Shawn

LE3

  • Guest
Re: Updating model space display extents
« Reply #3 on: March 17, 2010, 08:57:11 PM »
no need for the AcDbExtents
Code: [Select]
AcGePoint3d
max = acdbHostApplicationServices()->workingDatabase()->extmax(),
min = acdbHostApplicationServices()->workingDatabase()->extmin();
AcGePoint2d max_2d (max[X], max[Y]);
AcGePoint2d min_2d (min[X], min[Y]);
view.setCenterPoint (min_2d + (max_2d - min_2d) / 2.0);
view.setHeight(max_2d[Y] - min_2d[Y]);
view.setWidth (max_2d[X] - min_2d[X]);
acedSetCurrentView (&view, NULL);
acdbHostApplicationServices()->workingDatabase()->updateExt(TRUE);

pkohut

  • Guest
Re: Updating model space display extents
« Reply #4 on: March 18, 2010, 12:46:53 PM »
Hi,

I'm working on my first ARX routine.  It resizes the drawing frame so I can adjust it's aspect ratio.  This works fine, but my routine is called from inside a LISP.  I don't know how to cause the system variables to update, for a zoom extents before the LISP exits.  I only have the default model space viewport.  I suspect I need to change the model space viewport settings, but I'm not sure how.  I have posted my code so you can see what I am trying to do.

See if something in the file AcadIMouse.cpp is helpful.  This is pretty old, maybe VC6 and added mouse wheel zoom support for R14.  Can you believe I still get 5 or 6 requests a year to update this program? Anyways, I think it was last updated in 2000.

With this notice I hereby release it to the "Public Domain".

LE3

  • Guest
Re: Updating model space display extents
« Reply #5 on: March 18, 2010, 12:58:46 PM »
Hey Pablo,

For how long you been doing programming? - or more specific for AutoCAD based?

Are you the one that came up with the acis decoder? if I remember correctly was posted in Reni Urban, many moons ago.

Buen dia!

(Maybe it is time for those interviews made here some time ago for some of the swamp members)

pkohut

  • Guest
Re: Updating model space display extents
« Reply #6 on: March 18, 2010, 01:13:04 PM »
Hey Pablo,

For how long you been doing programming? - or more specific for AutoCAD based?

Are you the one that came up with the acis decoder? if I remember correctly was posted in Reni Urban, many moons ago.

Buen dia!

(Maybe it is time for those interviews made here some time ago for some of the swamp members)

I assume you're asking me?  Yes.  I'm getting old now but I think I started programming Autocad in '89 or '90.

LE3

  • Guest
Re: Updating model space display extents
« Reply #7 on: March 18, 2010, 01:19:37 PM »
Hey Paul,

I assume you're asking me?  Yes.  I'm getting old now but I think I started programming Autocad in '89 or '90.
Yes.

Wow! long time.

shawndoe

  • Guest
Re: Updating model space display extents
« Reply #8 on: March 18, 2010, 03:34:41 PM »
Just an update, 

The drawing comes up centered in the resized drawing window, but it's still seeing the old client window dimensions.  Pkohut has placed alot of info in front of me and I'm going to look through it before I come back with more questions. 

Below I am posting my code as it stands and a LISP snippet that shows how the ARX will be used.  If you try it you will see the problem.

Code: [Select]
static void SetDwgWindow_SetWindow(void) {
//
// Set Variables
//
// Client   Borders,Sliders,Ect.
int Width = 0; // ViewAreaWidth(802) + 28 = Width = 830
int Height = 0; // ViewAreaHeight(493) + 71 = Height = 564
acedGetInt (_T("\nEnter a new width in pixels for the drawing window: "), &Width);
acedGetInt (_T("\nEnter a new height in pixels for the drawing window: "), &Height);
CRect rect (0, 0, 2 * Width, 2 * Height);
CRect ChildRect (0, 0, Width, Height);
AcGePoint3d Min (0, 0, 0);
AcGePoint3d Max (830, 564, 0);
//
// Resize Document Frame
//
CWnd* DocFrame = acedGetAcadDwgView()->GetParent();
DocFrame->MoveWindow (ChildRect);
DocFrame->UpdateWindow ();
//
// Test of VP Reset
//
AcDbViewTableRecord View;
AcGePoint3d ExtentsMax = acdbHostApplicationServices()->workingDatabase()->extmax();
AcGePoint3d ExtentsMin = acdbHostApplicationServices()->workingDatabase()->extmin();
AcGePoint2d ExtentsMax_2d (ExtentsMax[X], ExtentsMax[Y]);
AcGePoint2d ExtentsMin_2d (ExtentsMin[X], ExtentsMin[Y]);
View.setCenterPoint (ExtentsMin_2d + (ExtentsMax_2d - ExtentsMin_2d) / 3.0) ;
View.setHeight (ExtentsMax_2d[Y] - ExtentsMin_2d[Y]) ;
View.setWidth (ExtentsMax_2d[X] - ExtentsMin_2d[X]) ;
//
//
acedSetCurrentView (&View, NULL);
acdbHostApplicationServices()->workingDatabase()->updateExt(TRUE);
//
// End of VP Reset
//
}//SetDwgWindow

LISP snippet

(defun C:Test ()
(command "SetWindow" "830" "564")
(command "._Zoom" "Extents")
(getstring "Press any key to continue: ")
); Defun

Thanks again for your help.
Shawn

LE3

  • Guest
Re: Updating model space display extents
« Reply #9 on: March 18, 2010, 05:36:42 PM »
Do not know if this is what you want to do/have - give it a try and see if works.
Code: [Select]
static void zoomExtents()
{
AcDbViewTableRecord view;
AcGePoint3d max = acdbHostApplicationServices()->workingDatabase()->extmax(),
min = acdbHostApplicationServices()->workingDatabase()->extmin();
AcGePoint2d max_2d (max[X], max[Y]);
AcGePoint2d min_2d (min[X], min[Y]);
view.setCenterPoint (min_2d + (max_2d - min_2d) / 2.0);
view.setHeight(max_2d[Y] - min_2d[Y]);
view.setWidth (max_2d[X] - min_2d[X]);
acedSetCurrentView (&view, NULL);
acdbHostApplicationServices()->workingDatabase()->updateExt(TRUE);
}

static void SetDwgWindow_SetWindow(void) {
//
// Set Variables
//
// Client Borders,Sliders,Ect.
int Width = 0; // ViewAreaWidth(802) + 28 = Width = 830
int Height = 0; // ViewAreaHeight(493) + 71 = Height = 564
acedGetInt (_T("\nEnter a new width in pixels for the drawing window: "), &Width);
acedGetInt (_T("\nEnter a new height in pixels for the drawing window: "), &Height);
CRect rect (0, 0, 2 * Width, 2 * Height);
CRect ChildRect (0, 0, Width, Height);
AcGePoint3d Min (0, 0, 0);
AcGePoint3d Max (830, 564, 0);
//
// Resize Document Frame
//
CWnd* DocFrame = acedGetAcadDwgView()->GetParent();
DocFrame->MoveWindow (ChildRect);
DocFrame->UpdateWindow ();

zoomExtents();

DocFrame->SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0L);
DocFrame->SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0L);
DocFrame->SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0L);

}//SetDwgWindow
 

shawndoe

  • Guest
Re: Updating model space display extents
« Reply #10 on: March 18, 2010, 08:42:44 PM »
No luck,

Your code works just as I described for my version.  It looks like you isolated the Zoom portion of the code, and added commands to run the window through its states.  Unfortunately, this does not force an update of some or all Acad system variables relating to document/client window size.  The extents of my drawing have not changed, but the extents of the window have.

I think this has been an issue for a long time.  If you set the screensize system variable in LISP, the window will immediately resize, but a Zoom will fail, because it is using data that should have been updated, but won't be until you leave LISP.  it seems like AutoCAD is holding the variable changes, related to the window resize, in a buffer until after all ARX, VBA, and LISP routines have finished.  I have to believe there is so way to force those updates to occur.  I think the code pkohut gave my will have the same problem, but there is a lot of code to look at (for a novice).

Try resizing a drawing window in LISP and using the ARX you gave me, and let me know what you think.

Thanks again to both of you.  I try to reserve my posting for the toughest problems, but I was really hoping to not be this much of a pain.

Have a good evening.
Shawn

Have a good one,


LE3

  • Guest
Re: Updating model space display extents
« Reply #11 on: March 18, 2010, 08:54:43 PM »
I am in other channel now, and got little time to spent more into testing... and also my lisp skills are out of date.

Maybe, what you can do is to provide with more details, images, animated images, etc... more sample/portions of code and other might be interested to lend a hand.

Ps> your code was not updating the background, that's why I added the send messages calls... sorry can't be of more help here.

pkohut

  • Guest
Re: Updating model space display extents
« Reply #12 on: March 18, 2010, 09:01:24 PM »
No idea if it will work or not, but try adding the code in red


Code: [Select]
static void SetDwgWindow_SetWindow(void) {
[color=red]AcTransaction * pTrans = actrTransactionManager->startTransaction();
actrTransactionManager->enableGraphicsFlush(kTrue);[/color]

int Width = 0; // 830
int Height = 0; // 564
acedGetInt (_T("\nEnter a new width in pixels for the drawing window: "), &Width);
acedGetInt (_T("\nEnter a new height in pixels for the drawing window: "), &Height);
CRect rect (0, 0, 2 * Width, 2 * Height);
CRect ChildRect (0, 0, Width, Height);
//
//
//
CWnd* DocFrame = acedGetAcadDwgView()->GetParent();
DocFrame->MoveWindow (ChildRect);
DocFrame->UpdateWindow ();
[color=red]        actrTransactionManager->queueForGraphicsFlush();
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
actrTransactionManager->endTransaction();[/color]

}//SetDwgWindow

shawndoe

  • Guest
Re: Updating model space display extents
« Reply #13 on: March 19, 2010, 03:33:47 PM »
Still a no go...

I am going to post some screen shots of AutoCAD so you can see what I am trying to do.  I have posted all my ARX code, and the LISP snippet I posted was to demonstrate the problem.

Below you can see the drawing in the client window as it was on opening the drawing.  I moved it off center a little to hide some of the titleblock. 



Below is the result of running the routine as shown by Pkohut.  Functionally this is equivlent to setting the SCREENSIZE sysvar.  However, when you set the SCREENSIZE sysvar in LISP, VBA, or ARX, the window size will update immediately, but the data used for drawing to pixel transformations won't update until the you are back at the command prompt.  In ARX I think there is a way around this, but I don't know what it is.  I suspect that acedCoordFromPixelToWorld or it's related functions might do it, but I'm not sure how to use them.  It's interesting to note that the drawing while not fit to the window is properly centered.



If there is any other data I can get for you let me know.

Thanks again for all the effort.
Shawn

LE3

  • Guest
Re: Updating model space display extents
« Reply #14 on: March 19, 2010, 11:23:44 PM »
Got a chance to play.-
(MYVIEW is just the same lisp of yours with a different name)

edit: the animated image was not properly shown, and was removed - will try to make a new one when I get a chance.

added: a zip with the animated image...

1. The first MYVIEW call and autocad with two documents open and noticed the results (using your original code and also the other one by Paul).
2. Second call of MYVIEW and a single document open.
3. Third call of MYVIEW and single document open and the code below - if I use the zoomExtents() function inside the arx it does the zoom, the one from the lisp not.
Code: [Select]
static void SetDwgWindow_SetWindow(void)
{
//
// Set Variables
//
// Client Borders,Sliders,Ect.
int Width = 0; // ViewAreaWidth(802) + 28 = Width = 830
int Height = 0; // ViewAreaHeight(493) + 71 = Height = 564
acedGetInt (_T("\nEnter a new width in pixels for the drawing window: "), &Width);
acedGetInt (_T("\nEnter a new height in pixels for the drawing window: "), &Height);
CRect rect (0, 0, 2 * Width, 2 * Height);
CRect ChildRect (0, 0, Width, Height);
AcGePoint3d Min (0, 0, 0);
AcGePoint3d Max (830, 564, 0);
//
// Resize Document Frame
//
CWnd* DocFrame = acedGetAcadDwgView()->GetParent();
DocFrame->MoveWindow (ChildRect);
DocFrame->UpdateWindow ();

//zoomExtents();

acedGetAcadDwgView()->Invalidate();
acedGetAcadDwgView()->UpdateWindow();
DocFrame->SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0L);
DocFrame->SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0L);
DocFrame->SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0L);
DocFrame->MoveWindow (ChildRect);

}//SetDwgWindow
« Last Edit: March 19, 2010, 11:37:51 PM by LE3 »