Author Topic: Updating model space display extents  (Read 9271 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 »

pkohut

  • Guest
Re: Updating model space display extents
« Reply #15 on: March 19, 2010, 11:35:56 PM »
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.

Can you post a VC project with the minimal amount of code that demonstrates the problem.  Also, what system variable do you think are suspect?

pkohut

  • Guest
Re: Updating model space display extents
« Reply #16 on: March 20, 2010, 12:42:30 AM »
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.

Clarify, are you saying that the ARX call of zoomExtents() *always works* and the one called in lisp does not?  I watched the GIF but could not follow what you are trying to show.  What are the pass fail results for items 1, 2, 3?  Sorry for being dense here, maybe it cause I finally read the whole thread carefully, have not tested any code, and am still confused.

LE3

  • Guest
Re: Updating model space display extents
« Reply #17 on: March 20, 2010, 11:35:40 AM »
-The zoomExtents() (posted on reply#9) is a custom made function and it was used in of the tests and after changing the document view size it does a full zoom extents, if you try the code in the lisp after the view size change it is using the built-in zoom extents and that one (at least here it simple does not do an extents).

-On item one, if you have two documents open, and then the arx routine it is called, it won't paint the title bar of the changed doc view, nor the upper right corner icons/buttons.

-On item two, if is there a single doc open and the arx routine it is called it happen the same, but also the full previous view (maximized) it won't be repaint, so the background on autocad will still have the same view twice.
-On the third one, it does the repaint and avoids the previous issues mentioned above, the only issue still is that if the built-in zoom extents command it is used from the lisp routine it won't do it right.

-On fourth - I am like you confused too.

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.

Clarify, are you saying that the ARX call of zoomExtents() *always works* and the one called in lisp does not?  I watched the GIF but could not follow what you are trying to show.  What are the pass fail results for items 1, 2, 3?  Sorry for being dense here, maybe it cause I finally read the whole thread carefully, have not tested any code, and am still confused.

pkohut

  • Guest
Re: Updating model space display extents
« Reply #18 on: March 20, 2010, 12:14:10 PM »
How about letting your routine sleep for a millisecond so the OS and potentially Autocad has a time slice to make some screen updates?

shawndoe

  • Guest
Re: Updating model space display extents
« Reply #19 on: March 20, 2010, 07:15:24 PM »
Hi,

The two screen shots I posted were a before and an after of just the ARX SetWindow() and zoomExtents().  I believe that if we get it to work in the ARX it will work when you zoom from the LISP. 

Really beyond the code posted everything else is an out of the box ObjectArx Wizard setup with MFC support.  I'm running 2010 and Visual Studio 2008 Pro on a fresh XP machine.  I can post my LISP code, but really I don't think it is the issue,  the snippet I post uses a Zoom Extents in place of the third party publish function (Tririga Cad Integrator if anybodies interested) the results are the same. 

The publish function zooms to extents in the drawing window, creates a DWF of the display, then attaches a bunch of database links to the DWF, and finally uploads it to our server.  At the root of this is a need to get the aspect ratio of the client window the same as the titleblock, so I don't have any dead space around edges of the DWF throwing off the scale.

(1)  I had not noticed the lose of the window buttons on the title bar from the LISP, but I wasn't looking so might have missed it.  I'll check on that when I'm back in front of my machine at work, unfortunately my remote access is down. 

(2)  I didn't see that, but I run with Drawing1 in the background most of the time.  I'll check that as well.  I did see that when I sized the client window directly instead of the frame.

(3)  I was looking at the zoomExtents() results and I don't think it does zoom properly.  A section on top and bottom seemed cut off to me.  It's as if it shifts the old window view and centers it in the new window. 

(4)  I'm pretty confused my self, I'm just used to it.   :-D  It's like there is a buffer that is loaded from the system variables at the start of a routine be it LISP, VBA or ARX, and it is not updated when the system variables change.  As a result we can change system variables like VIEWSIZE, but the buffer data remains unchanged.  When you reach the command prompt the buffer is flushed, or refreshed at the start of the next operation.  We need to find a refresh the data in that buffer with the new values.  That's why I had such high hopes for Paul's enableGraphicFlush().

I don't think a time delay will do anything, I have tried that in LISP and VBA.

Thanks again for your efforts, and have a good weekend.
Shawn

frtfff

  • Bull Frog
  • Posts: 214
Re: Updating model space display extents
« Reply #20 on: March 21, 2010, 08:49:30 AM »
Good code. :kewl:

shawndoe

  • Guest
Re: Updating model space display extents
« Reply #21 on: March 23, 2010, 05:09:22 PM »
OK,

Really? good code...  :P  Posting the full project is embarrassing it reveals just what a noob I am at ARX.  Never the less the full project is posted.  All my code resides in acrxEntryPoint.cpp, and has been redone with subfunctions.  I added some diagnostic functions, as I have yet to be able to run in debug without a complete lock up or fatal error from AutoCAD.  The code compiles with no errors or warnings.

Might as well a formating lessons now.  Should my code be in a separate file included in the acrxEntryPoint, or is where it is correct?  It feels like it should be elsewhere.

I've spent some time trying to research the problem a bit more, and I was checking out the acgs class.  I found acgsGetDisplayInfo(), it returns the drawingWidth, and drawingHeight, as well as aspect ratio for the display Frame.  Its values are the same as held in the screeensize sysvar.  If you look at the results of a run you will see that after the drawing window is resized, the drawingHeight, and drawingWidth remain unchanged.

I have yet to find a way to change that value.  I am sure it is held in a buffer, but where and how to access it is still an open question.  I tried switching between a 3d view and the back to 2D, but that doesn't seem to have triggered the update. My experiments at setting the drawingWidth and drawingHeight are in SetWindowTestCode().

I'll take any suggestions I can get.

Thanks again, and have a good one.
Shawn

pkohut

  • Guest
Re: Updating model space display extents
« Reply #22 on: March 23, 2010, 05:18:16 PM »
OK,

Really? good code...  :P  Posting the full project is embarrassing it reveals just what a noob I am at ARX.  Never the less the full project is posted.  All my code resides in acrxEntryPoint.cpp, and has been redone with subfunctions.  I added some diagnostic functions, as I have yet to be able to run in debug without a complete lock up or fatal error from AutoCAD.  The code compiles with no errors or warnings.

Might as well a formating lessons now.  Should my code be in a separate file included in the acrxEntryPoint, or is where it is correct?  It feels like it should be elsewhere.

I've spent some time trying to research the problem a bit more, and I was checking out the acgs class.  I found acgsGetDisplayInfo(), it returns the drawingWidth, and drawingHeight, as well as aspect ratio for the display Frame.  Its values are the same as held in the screeensize sysvar.  If you look at the results of a run you will see that after the drawing window is resized, the drawingHeight, and drawingWidth remain unchanged.

I have yet to find a way to change that value.  I am sure it is held in a buffer, but where and how to access it is still an open question.  I tried switching between a 3d view and the back to 2D, but that doesn't seem to have triggered the update. My experiments at setting the drawingWidth and drawingHeight are in SetWindowTestCode().

I'll take any suggestions I can get.

Thanks again, and have a good one.
Shawn

I'm not on a Windows box to look at the code under VS or have any ARX documentation, but why in zoomExtents is view not a pointer? You need to get the view your interested in somehow (again no docs in front of me).  What you've done is created an instance of view, but it's not associated with a view in Autocad.

pkohut

  • Guest
Re: Updating model space display extents
« Reply #23 on: March 23, 2010, 05:27:56 PM »
OK,
I added some diagnostic functions, as I have yet to be able to run in debug without a complete lock up or fatal error from AutoCAD.  The code compiles with no errors or warnings.

Are you getting an exception when you press F5 to start the Autocad session?  If so just hit F5 again (maybe more than once), till the Autocad comand line is available.

I'm also not seeing your include or lib settings for the ObjectARX sdk in the vcproj file.  Maybe you've got them set globally for VS??

shawndoe

  • Guest
Re: Updating model space display extents
« Reply #24 on: March 23, 2010, 07:47:38 PM »
Hi,

When attempting to debug the first thing I notice is that not all the menus show up, only File, Window, and Help.  I reach the AutoCAD command line, but as soon as I load and start the ARX function it locks up.  My ignorance may be showing again. 

I do have the inc and lib paths set globally.  Am I better off not doing that, or does it matter?

I'm still getting the hang of pointers and how to use them.  Having created an instance of view, I'm not quite sure how to use it.  I also believe that creating a view without dealing with the stored pixel dimensions, as returned by acgsGetDisplayInfo(), will fail when Zoom Extents is call from the LISP.

Thanks again, you both have really given me a good start in ARX, I only feel overwhelmed about half the time now.  :)

Have a good one.
Shawn

pkohut

  • Guest
Re: Updating model space display extents
« Reply #25 on: March 23, 2010, 08:01:12 PM »
I'm still getting the hang of pointers and how to use them.  Having created an instance of view, I'm not quite sure how to use it.  I also believe that creating a view without dealing with the stored pixel dimensions, as returned by acgsGetDisplayInfo(), will fail when Zoom Extents is call from the LISP.

You don't want to create an instance of AcDbViewTableRecord, you want to get the pointer to one of the table records already maintained by Autocad.

edit: after looking at the AcadIMouse code I see that statement isn't correct. Look in the SDK documentation for acedSetCurrentView, code follows next post.
« Last Edit: March 23, 2010, 08:28:25 PM by pkohut »

pkohut

  • Guest
Re: Updating model space display extents
« Reply #26 on: March 23, 2010, 08:13:26 PM »
AcDbViewTableRecord * pViewRcd = new AcDbViewTableRecord;
pViewRcd->setALL_PROPERTIESS_YOU_WANT/NEED();
.
.
.
acedSetCurrentView(pViewRcd, NULL);

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6926
  • AKA Daniel
Re: Updating model space display extents
« Reply #27 on: March 24, 2010, 04:50:47 AM »
Weird, it seems that acad does not want to update until after the command has finished
I tried all what I could think of.. no luck


Code: [Select]
(defun c:test () (setwindow 500 500) (vla-zoomextents (vlax-get-acad-object)))

  static int ads_setwindow(void)
  {
    struct resbuf *pArgs =acedGetArgs ();
    int width, height;
    if(pArgs)
      width = pArgs->resval.rint;
    if((pArgs = pArgs->rbnext))
      height = pArgs->resval.rint;
    CRect ChildRect (0, 0, width, height);
    CWnd* DocFrame = acedGetAcadDwgView()->GetParent();
    DocFrame->SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0L);
    DocFrame->MoveWindow (ChildRect);
    acedRetVoid () ;
    return (RSRSLT) ;
  }
« Last Edit: March 24, 2010, 05:45:22 AM by Daniel »

LE3

  • Guest
Re: Updating model space display extents
« Reply #28 on: March 24, 2010, 10:39:46 AM »
will try to play again on this later this afternoon, but why if it works by using the arx zoom extents function....
as in the Reply #14 and removing the zoomExtents(); that it is on Reply #9

As per my previous tests here, but will double check as said later today...

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6926
  • AKA Daniel
Re: Updating model space display extents
« Reply #29 on: March 24, 2010, 10:47:46 AM »
Luis, yours did not work for me either, when applied from a single command. I tried using other command flags but no go  :mrgreen:
« Last Edit: March 24, 2010, 10:54:54 AM by Daniel »

LE3

  • Guest
Re: Updating model space display extents
« Reply #30 on: March 24, 2010, 11:05:54 AM »
Luis, yours did not work for me either, when applied from a single command. I tried using other command flags but no go  :mrgreen:

could be.... got to go now.... will see it was working here  :-(

owenwengerd

  • Bull Frog
  • Posts: 439
Re: Updating model space display extents
« Reply #31 on: March 24, 2010, 01:28:52 PM »
If AutoCAD updates the needed internal state when a command ends, then there is your answer: execute a command to update the state.

shawndoe

  • Guest
Re: Updating model space display extents
« Reply #32 on: March 24, 2010, 04:55:07 PM »
Hi,

First Owen, your websight and your knowledge have been very helpful to me over the years, and I wanted to thank you.

I don't think AutoCAD is updating at the end of a command, but on the return to the command line.  It creates the buffer (for graphic related vars?) when you leave the command line for any LISP, VBA, or ARX/Native command.  AutoCAD will continue to get data from that buffer as long as any of these is open, even if it is in a separate drawing. 

In my case what this means is I have a batch routine I run from Drawing1.  AutoCAD creates a buffer as soon as you start the batch LISP in drawing1.  The LISP opens a set of drawings one at a time, and executes my LISP in S::StartUp. When the work drawing loads, the data has already been placed in a buffer for that drawing.  Normally AutoCAD would update the data in that buffer after AcadDoc.lsp etc. finish, and the drawing is ready for user input.  In my case, at this point focus shifts back to Drawing1 where we are still in LISP.

What I have found using vla-SendCommand and other tricks is that, while LISP execution has finished in the work drawing it continues in Drawing1, so the data in the buffers remains there for BOTH drawings.  If you save and close the work drawing before leaving LISP AutoCAD will save any changes you may have made to the database, but whatever changes occurred to that buffer data will be lost.  This means that while I can resize a drawing window, I can't get AutoCAD to acknowledge the change, or save it.  I had similar results with VBA.

Now you know why I am tackling an ARX project even though I still need to work on my C++ skills a bit more.  Still, I'm learning alot, working a difficult problem, while doing something useful, and that's the best kind of learning.  It sticks

Have a good one, and thanks again.
Shawn

owenwengerd

  • Bull Frog
  • Posts: 439
Re: Updating model space display extents
« Reply #33 on: March 24, 2010, 05:37:38 PM »
I appreciate the kind words.

Without spending more time understanding the problem I don't have any specific advice, but I would solve this problem by reverse engineering what triggers the cached data to be updated, then doing whatever needs to be done to flip the switch that triggers it. If the switch is "complete all pending commands", then that is what your code has to do (or at least simulate). It's possible that having the ObjectARX (and VBA) ability to run in the application context could prove useful, but I'd bet that it can be done just as well via lisp.

pkohut

  • Guest
Re: Updating model space display extents
« Reply #34 on: March 24, 2010, 06:21:29 PM »
Don't know if it's just me or what, but I have had a heck of a time trying to follow your descriptions.

It would probably be better to describe the work your trying to accomplish rather than side effects of Autocad and the interaction with your routine.

However, your latest description raises these questions (I'm confused and stepping aside) -
Are you trying to send data back and forth between drawings, with some sort of inter process communication?
What does the send command look like?
What is this mystery buffer?
Can't the data be persisted to a file instead of the mystery buffer?
Batch routine == lisp routine?
What about running a script instead of the batch (lisp) routine? Create on the fly if needed?

LE3

  • Guest
Re: Updating model space display extents
« Reply #35 on: March 25, 2010, 03:19:27 PM »
Quote
(I'm confused and stepping aside)


x2

shawndoe

  • Guest
Re: Updating model space display extents
« Reply #36 on: March 25, 2010, 08:19:42 PM »
Hi,

The Tririga publish to server function is at the root of why I need to change the window size.  The publish function zooms to extents in the drawing window, creates a DWF of the display, then attaches a bunch of database links to the DWF, and finally uploads it to our server.  At the root of this is a need to get the aspect ratio of the client window the same as my titleblock. I can't have any dead space around edges of the DWF throwing off the scale when the DWF printed out.  That is why I used that little test LISP that used SetWindow, and zoomed to extents, because that is what the publish function does before creating the DWF.

I hope this helps explain what I am trying to do, and why I'm fighting so hard with the window size setting.  I have only found 2 problems that I could not solve using a LISP at StartUp, the first is user input at the command line, and the second is this window issue.

The only data transfers are done using vl-bb-set/ref.  I don't send commands to the work drawing usually. I have experimented with doing so, to set the window size, after StartUp.  All attempts to use vla-SendCommand from the work drawing in StartUp, or from Drawing1 after the work drawing open and return, failed.  You can see verious attempts at it in the code below.

The desciption of a command in the MDI terminology is also descriptive of when updating the window size fails.  The "Mystery Buffer" is something that I think is created when AutoCAD executes a command as defined in the MDI terminology.  I'm honestly not sure what this buffer is called, but I'm certain it exists. 

I don't think AutoDesk would write a file everytime you run a command.  It just seems like a lot of effort for something done that often, and that could be held in memory with less overhead.

I have tried to avoid doing batch runs with scripts because it always felt like a kludge to me.

I will try to describe how my LISP routine works.  I'm going to post snippets of code because I don't think anybody wants to see dialogue box handling or string parsing.

(1) Start SDMU Batch LISP. (Code not shown)
    (1a) Start dialogue box.
        (1a.1) Set drawing directory and drawing name wildcard filters. (accepts .lnk)
        (1a.2) Select sub-directory processing mode. (Root, 1st Level, All)
        (1a.3) Select preset LISP files to be run. (radio buttons)
        (1a.4) Allow user to select a LISP from file dialogue if needed.
    (1b) Select directory for processing.

(2) Store collected LISP routines and aurgument data (vl-bb-set/ref)
   
(3) Collect Directory and FileList data.

(4) Begin processing directories.
    (4a) Supply directory, fileList, and savemode to DrawingActivator.
    (4b) DrawingActivator cycles through all drawings in the Filelist
    (4c) Drawings are opened but not set active.
    (4d) Drawings opened using the code snippet below
        (4d.1) Drawing open
        (4d.2) Windowresize experiments
        (4d.3) Close and save if set.
        (4d.4) Release drawing handle.

Code: [Select]
;
; *************************************  Open Drawing  **************************************
;
        (if (and
               (findfile FileString)
;               (<= (DwgFileVersion FileString) 18)
            );and
           (progn
;
; Normal Operation
;
;              (vl-bb-set 'BaseDwg (vla-get-activedocument (vlax-get-acad-object)));
              (vl-bb-set 'WrkDwg (setq WrkDwg (vla-open (vla-get-documents (vlax-get-acad-object)) FileString)));
;
; Other Operations on Work Drawing (window resizing)
;
              (princ "\nZoom Dwg1")(print)
;              (vla-zoomextents WrkDwg)
;              (princ "Zoom WrkDwg")(print)
;              (vla-sendcommand WrkDwg "Zoom Extents (vla-activate (vl-bb-ref 'BaseDwg))\r")
;              (vla-sendcommand WrkDwg "(ACADWindowSize 830 564 (vl-bb-ref 'WrkDwg)) (vla-activate (vl-bb-ref 'BaseDwg))\r")
              (princ "WindowResize")(print)
              (vla-put-width WrkDwg 1254)
              (vla-put-height WrkDwg 846)
;              (vla-sendcommand WrkDwg "Zoom Extents (vla-activate (vl-bb-ref 'BaseDwg))\r")
;              (vla-zoomextents WrkDwg)
;              (princ "Reset Zoom")(print)
;              (vla-sendcommand WrkDwg "(c:cipublish)(wait) (vla-activate (vl-bb-ref 'BaseDwg))\r")
;              (vla-sendcommand WrkDwg "Zoom Extents (vla-activate (vl-bb-ref 'BaseDwg))\r")
              (princ "Publish")(print)
;              (vla-sendcommand WrkDwg "(c:ciPublish) \r")
              (wait)
;
; ********************************  Save and Close Drawing  *********************************
;
              (if (and (= SaveMode T)
                       (/= (vl-bb-ref 'Error) File)
                  );and
                (progn
                   (vla-save WrkDwg)
                   (wait)
                   (vla-close WrkDwg :vlax-false)         ; If T save on close for batch republish
                   (princ "\nDrawing saved by SDMU. ")
                ); progn If
                (progn
                   (vla-close WrkDwg :vlax-false)        ; Else do not Save on close for batch republish
                   (princ "\nDrawing not saved by SDMU. ")
                ); progn else
        );if
        (wait) ; Wait for Active Commands to finish
      (vl-bb-set 'Error nil)
;
;  *******************************  Release Drawing Handle  *********************************
;
              (vlax-release-object WrkDwg) ; Release WrkDWG Object Pointer to complete close.
          (gc)
          (prompt "\nDrawing Complete.")(print)
       ); progn If
       (progn
          (write-line (strcat file " " (RawDate) ": Unable to open drawing.") BatchLog)
          (princ "\nInvalid Shortcut Path")
       ); Progn Else
        ); If FileString

(5) Focus shifts to newly opened drawing.
    (5a) Drawing goes through normal loading process.
    (5b) Execution reaches S::STARTUP

(6) S::STARTUP
    (6a) Set my default preferrences (Always runs, not part of Batch)
    (6b) Retrieve LispRunList using vl-bb-ref (may contain more then one LISP)
    (6c) Conditional check for which routines to run.
        (6c.1) Load and run selected preset LISP routines (Clean, Setlayers, Plot, etc.)
        (6c.2) Load and run any LISP choosen by the user from file dialogue. (Publish function run here)
    (6d) See code below for LISP loading and execution.
   
Code: [Select]
(defun-q BatchHandler ( / LispRunList   RunLisp   NewLaData   MainFunc)
(vl-load-com)
(setvar "REGENMODE" 1)
(setenv "CmdHistLines" "2048")
(setvar "LOGFILEMODE" 1)
;
; ********************************  If Drawing1 Load SDMU  **********************************
;
(if (= (getvar "dwgname") "Drawing1.dwg")
    (progn
       (load "g:\\SHS\\ENTERPRISES\\Housing Systems Initiatives\\Space_CAD\\cad\\cad drawings\\PHASE 3 CAD Planning\\HPPS Code\\Shawn's Routines\\Batch Routines Revised\\ODv4-7.lsp")
       (print)(prompt "Stanford Drawing Maintanence Utility Loaded: ")(print)
;       (command "._Point" '(0 0 0))
;       (command "._Erase" '(0 0 0) "")
;       (vl-bb-set 'Debug "Yes")
    ); progn
); if
;
; *********************************  Retrieve Run List  *************************************
;
(setq LispRunList (vl-bb-ref 'BPRun))
(DandD (reverse '("LispRunList")) "All Selected BP Lisps" "Yes")
;
; *****************************  Execute Run List If /= nil *********************************
;
(if (/= LispRunList nil)
  (command "._Model")
)
(foreach Routine LispRunList
  (setq RunLisp (car Routine))
  (cond ((= RunLisp "9Plot")
           
            (load "g:\\SHS\\ENTERPRISES\\Housing Systems Initiatives\\Space_CAD\\cad\\cad drawings\\PHASE 3 CAD Planning\\HPPS Code\\Shawn's Routines\\Batch Routines Revised\\Plot All.lsp")
            (print)(princ Routine)(Print)
;            (load "g:\\SHS\\ENTERPRISES\\Housing Systems Initiatives\\Space_CAD\\cad\\cad drawings\\PHASE 3 CAD Planning\\HPPS Code\\Shawn's Routines\\Batch Routines Revised\\Plot All Drawings.lsp")
            (PlotBatch (nth 1 Routine)(nth 2 Routine))
;            (PlotBatch (nth 1 (car (vl-bb-ref 'BPRun)))(nth 2 (car (vl-bb-ref 'BPRun))))
            (wait)(Print)(Prompt "Bible Sheet Printed. ")(print)
        )
        ((= RunLisp "8BlockCounter")
            (load "g:\\SHS\\ENTERPRISES\\Housing Systems Initiatives\\Space_CAD\\cad\\cad drawings\\PHASE 3 CAD Planning\\HPPS Code\\Shawn's Routines\\Block Counter.lsp")
            (C:CntBlk)
            (wait)(Print)(Prompt "BlockList: Complete")(print)
        )
        ((= RunLisp "7LayerList")
            (load "g:\\SHS\\ENTERPRISES\\Housing Systems Initiatives\\Space_CAD\\cad\\cad drawings\\PHASE 3 CAD Planning\\HPPS Code\\Shawn's Routines\\LayerList1-4.lsp")
            (setq NewLaData (C:lltest))
            (wait)
            (vl-bb-set 'MasterLayerData NewLaData)
            (Print)(Prompt "LayerList: Complete")(print)
        )
        ((= RunLisp "6SetLayer")
            (command "_.Layer" "Off" "*" "Thaw" "*" "Freeze" "Defpoints,A-SH-FLOR-FIN" "")
            (SetLayers (cadr Routine) 'LayerOn "True")
            (wait)(Print)(Prompt "Layers Set")(print)
;            (alert "waiting")
        )
        ((= RunLisp "5Select")
            (load (cdr Routine))
            (print)
            (prompt (setq MainFunc (nth 0 (reverse (princ (GetSubFuncs (cdr Routine)))))))
;            (print)(alert MainFunc)(Print)
            (eval (list (read MainFunc)))
            (wait)
            (Print)(Prompt "Selected LISP Run Complete. ")(print)
        )
        ((= RunLisp "4MspaceLayout")
            (load "g:\\SHS\\ENTERPRISES\\Housing Systems Initiatives\\Space_CAD\\cad\\cad drawings\\PHASE 3 CAD Planning\\HPPS Code\\Shawn's Routines\\Batch Routines Revised\\MspaceStdLayout-v31d.lsp")
            (C:MspaceStdLayout)
            (wait)
            (Print)(Prompt "TitleBlock Insertion. ")(print)
        )
        ((= RunLisp "3Purge")
            (Command "._Purge" "Blocks" "" "No")
            (Wait)
            (Command "._Purge" "Layers" "" "No")
            (Wait)
        )
        ((= RunLisp "2LayerScrub")
            (load "g:\\SHS\\ENTERPRISES\\Housing Systems Initiatives\\Space_CAD\\cad\\cad drawings\\PHASE 3 CAD Planning\\HPPS Code\\Shawn's Routines\\Layerscrubv1-1.lsp")
            (C:lscrub)
            (Print)(Prompt "Layer Scrub: Complete")(print)
        )
        ((= RunLisp "1BOtoL0")
            (load "g:\\SHS\\ENTERPRISES\\Housing Systems Initiatives\\Space_CAD\\cad\\cad drawings\\PHASE 3 CAD Planning\\HPPS Code\\Shawn's Routines\\botol0v2-2.lsp")
            (C:botol0)
            (Print)(Prompt "Block Entities to Zero Layer: Complete")(print)
         )
;        ((= RunLisp "Other Routines Here"))
  ); Cond
(wait)
); foreach
;(acad-pop-dbmod)
;
;
); BatchHandler

(7) User selected LISP publishes drawing to server using Tririga publish function.
    (7a) Prep drawing for publish (queries, titleblock changes, layer settings, etc.)
    (7b) Publish to server. (Tririga publish utility in ARX file, so no change or dissasembly possible.)
   
Code: [Select]

(defun Publish03-20 ()
(C:SpaceClassUpdate)
(Print)(princ "Space Class Updates Complete: ")
(TitleBlock)
(Print)(princ "Titleblock Updated: ")
(Apreuploaddata)
(Print)(princ "Square Footage for Upload Complete: ")
;
;
;
(C:lastd)
(Print)(princ "Layer Standards Enforced: ")
;
;  Window resize Experiments
;
;(setq Doc_ID (vla-get-ActiveDocument (vlax-get-Acad-Object)))
;(ACADWindowSize 1245 846 );1660 1059 +34 for Top and Bottom headers
;(ACADWindowSize 1038 705 );1660 1059 +34 for Top and Bottom headers
;
;
(if (dictsearch (namedobjdict) "Tririga")
   (progn
      (C:AllShareHatch)
      (Print)(princ "Tririga Hatches Updated: ")
      (C:CiPublish)
      (Print)(princ "Drawing Published: ")
   );progn
   (Princ "Drawing not Linked to Tririga")
;   (write-line (Princ "Drawing not Linked to Tririga") (vl-bb-ref 'BatchLog))
)
;
;
;
(Command "._Qsave")
;(Print)(princ "Drawing Saved: ")
); defun



(8) S::STARTUP finishes and control is returned to Drawing1. 

(9) Any operations for after drawing open are executed
    (9a) See Other Operations on Work Drawings in Example code for DrawingActivator.
   
(10) Work drawing is saved if flag is set.

(11) Work drawing is released.

(12) Next drawing is Opened.
    (12a) DrawingActivator will repeat cycle until all files in directory are done.
    (12b) SubDirectory Handler will repeat cycle as specified by sub-directory processing mode.


If you get any ideas let me know, but in the meantime, thanks again for all your help.  Even without success on my resizing the window I have learned so much my head hurts.  Also one other question, which ARX contains the zoom command?  Maybe there is something I can learn from that.

Have a good one.
Shawn

pkohut

  • Guest
Re: Updating model space display extents
« Reply #37 on: March 25, 2010, 10:37:56 PM »
Hey Shawn, thanks for clarifying the process.  Unless your able to write some key parts of this in ARX I'm leaning toward creating a script on the fly that is run when a drawing is opened. Even in ARX there are times that a .scr file is useful. For instance, I have a set of routines that opens a select batch of drawings, zooms to a table of revision histories, freezes and turns all layers off except for the revision histories, and validates the RH entries in a SQL database, saves the drawings. The initial goal was to have a single ARX program handle everything, but there was a blocking feature that could not be done in a secondary drawing from the main ARX routine. This was resolved by having the main ARX program do the equivalent of "acad somedrawing /b myscript.scp". myscript.scp is in charge of bootstrapping an addition ARX routine to process the drawing.  What I described was a wall I hit with ARX, under lisp/vlisp you'll hit some limitation sooner.

vl-bb-set/ref look like cool features. Don't know anything about them.

Does SDMU have to be a lisp program?  How about making it a batch process, or better yet Power Shell (and scripts to bootstrap your code).

I think you misunderstood persisting data, not talking about having Autocad do it, your routines would need to do it. Maybe it is a lot of effort, sometimes it's required.


shawndoe

  • Guest
Re: Updating model space display extents
« Reply #38 on: March 26, 2010, 03:20:32 PM »
Hi,

I do plan to rewrite this in ARX eventually.  The LISP code could be better, I wrote this 5 years ago, and my skills have improved quite a bit since then.  I haven't done it up to know, because of time restraints and SDMUs reliability.  Routines run using SDMU may fail on occasion, but SDMU itself is a very reliable program. 

vl-bb-set/ref is awesome, it allows for transfer of all variable types between namespaces.  I use it in error handling, Batch Runs and anything else where I need data to be accessible outside the drawing.  It also lets me collect data and close the drawing, which is helpful in my audit routines.

I think I might spend this weekend writing an ARX to take over the drawing opening process, but I think the entire program would have to be written in ARX for scripting to work. 

I wonder, can this info be written to the drawing file before the drawing is opened.  AutoCAD seems to remember the size of a window at open.  Maybe the trick is not to open the drawing and set the window, but set the window and open the drawing...  Hummm.

I'm going to see if that works.  Let me know if you think I'm wasting my time.

Have a good one.
Shawn

shawndoe

  • Guest
Re: Updating model space display extents
« Reply #39 on: March 26, 2010, 04:54:13 PM »
Just a note,

A DWG remembers the window settings when you save a drawing, but a DXF does not.

Have a good one.
Shawn