Poll

how to updata a AcDbViewport object?

AcDbViewport
3 (75%)
FreezeLayer
1 (25%)

Total Members Voted: 1

Author Topic: how to updata a AcDbViewport object?  (Read 7930 times)

0 Members and 1 Guest are viewing this topic.

Dream.Fei

  • Guest
how to updata a AcDbViewport object?
« on: December 26, 2007, 11:14:12 AM »
Code: [Select]
static void Test_x1(void)
{
// -- Get Layer's ObjectId for Freeze;
AcDbObjectId FrzLay = acdbHostApplicationServices()->workingDatabase()->clayer();

// -- Make to a array for freezeLayer use
AcDbObjectIdArray FrzArray;
FrzArray.removeAll();
FrzArray.append(FrzLay);

// -- get all the viewport's objectId, but not paperSpace.
AcDbObjectIdArray vps;
vps.removeAll(); // -- clear it;

Acad::ErrorStatus es = Acad::eInvalidInput;
es = acdbHostApplicationServices()->workingDatabase()->getViewportArray(vps, false);
if (es != Acad::eOk)
{
acutPrintf(_T("\nError(getViewportArray): %s"), acadErrorStatusText(es));
return;
}

if (vps.isEmpty())
{
acutPrintf(_T("\nError(Viewport's IdArray): none viewport in it."));
return;
}

for (int i = 0; i < vps.length(); i++)
{
AcDbViewport *pEnt = NULL;
es = acdbOpenObject((AcDbObject*&)pEnt, vps[i], AcDb::kForWrite);
if (es != Acad::eOk)
{
acutPrintf(_T("\nError(OpenLayout): %s."), acadErrorStatusText(es));
continue; // -- skip current layout.
}

// -- Freeze Layer in viewPort
es = pEnt->freezeLayersInViewport(FrzArray);
if (es != Acad::eOk)
{
acutPrintf(_T("\nError(FrzInVp): %s"), acadErrorStatusText(es));
pEnt->close();
continue;
}

/* UpdataDisplay? but it no work. this viewport have no change. */
pEnt->updateDisplay();
pEnt->close();
}

}
I have write this code to Freeze Current layer on all viewport. but no work as I think.

the viewport do't updata when the command complete.

but, if I copy a viewport , the layer( what I want to freezed) already Freeze on the copy....

look the Gif:
« Last Edit: December 26, 2007, 11:20:43 AM by Dream.Fei »

Glenn R

  • Water Moccasin
  • Posts: 1932
  • What idiot child of married cousins wrote this?!
Re: how to updata a AcDbViewport object?
« Reply #1 on: December 26, 2007, 02:40:01 PM »
What is 'LAYOUTREGENCTL' set to?
Also, you might have to record the graphics as modified for the viewport.
Me

Dream.Fei

  • Guest
Re: how to updata a AcDbViewport object?
« Reply #2 on: December 27, 2007, 01:19:47 AM »
I don't understand what's you mean 'LAYOUTREGENCTL' ?
updata the Layout?

about viewport:
I have try the follow code, but it's not work yet.
Code: [Select]
/* UpdataDisplay? but it no work. this viewport have no change. */
pEnt->updateDisplay();

[color=red]pEnt->recordGraphicsModified();[/color] // -- new code for update

pEnt->close();
}
[color=red]acedUpdateDisplay(); [/color] // -- call graphic update

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: how to updata a AcDbViewport object?
« Reply #3 on: December 27, 2007, 01:29:33 AM »
.... I don't understand what's you mean 'LAYOUTREGENCTL' ? ..........

(getvar "LAYOUTREGENCTL") and/or it's equivalent from code.

Controls the display behavior of how a layout acts when switching to it.

0   Each time you switching to a layout tab, a regeneration occurs
1   Model and the last layout tab is cached into memory
2   Initial display of the tab is the only time that a regeneration occurs and any other time that the tab is activated it is read from cache

Saved in Registry; Initial value 2
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Dream.Fei

  • Guest
Re: how to updata a AcDbViewport object?
« Reply #4 on: December 27, 2007, 01:39:40 AM »
Quote
...(getvar "LAYOUTREGENCTL")...

Thank you.
set this var's value to "0" can see the modified.

Have any other way? don't change the sysvar's value?

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: how to updata a AcDbViewport object?
« Reply #5 on: December 27, 2007, 01:54:57 AM »
>>>>>>>>
Have any other way? don't change the sysvar's value?

perhaps a REGEN  ?
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Dream.Fei

  • Guest
Re: how to updata a AcDbViewport object?
« Reply #6 on: December 27, 2007, 02:33:43 AM »
the command "regen" and "regenall" can't updata this layout or viewport.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: how to updata a AcDbViewport object?
« Reply #7 on: December 27, 2007, 03:34:59 AM »
Just a guess ..
Have you tried ( in code)
read and save the variable
set the variable to 0
do your mojo
reset the variable to the previously saved value.

sorry I can't be more help.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

mjguzik

  • Newt
  • Posts: 30
Re: how to updata a AcDbViewport object?
« Reply #8 on: December 27, 2007, 11:55:53 AM »
Ran into this problem some time ago with limited success updating layer changes in multiple viewports.  Then discovered what I believe is an undocumented function.  Hopefully this helps

Code: [Select]

// declarations
//

void __stdcall acedRegenLayers(class AcArray<class AcDbObjectId,class AcArrayMemCopyReallocator<class AcDbObjectId> > const &,int);

void applyLayerChanges();
Acad::ErrorStatus getLayerObjectIdArray();


// Implementation
//

// Usage applies changes to Layer Table forcing update and regen
//
void applyLayerChanges(void)
{
  applyCurDwgLayerTableChanges();
  if ( acdbHostApplicationServices()->workingDatabase()->tilemode() )
     ads_regen(); // Modelspace
  else {
    AcDbObjectIdArray layerIds;
    getLayerObjectIdArray(layerIds);
    acutPrintf(_T("Regenerating layout"));
    acedRegenLayers(layerIds, 0);
  }
  return;
}


// Usage return AcDbObjectIdArray of pDb LayerTable
Acad::ErrorStatus getLayerObjectIdArray(AcDbObjectIdArray& objIds, bool External, AcDbDatabase* pDb)
{
if ( pDb == NULL ) pDb =acdbHostApplicationServices()->workingDatabase();
Acad::ErrorStatus es = Acad::eOk;

AcDbLayerTable* pTable = 0;
es = pDb->getSymbolTable(pTable, AcDb::kForRead);
if ( es != Acad::eOk ) return es;

// Interate layers
//
AcDbLayerTableIterator* pIter = 0;
es = pTable->newIterator(pIter);
if ( es != Acad::eOk ) {
pTable->close();
return es;
}

for (pIter->start();!pIter->done();pIter->step())
{
AcDbLayerTableRecord* pRecord = 0;
es = pIter->getRecord(pRecord, AcDb::kForRead);
if( es == Acad::eOk ) {
if ( pRecord->isDependent() ) {
if (External == true)
objIds.append(pRecord->objectId());
}
else
objIds.append(pRecord->objectId());
}
pRecord->close();
}
delete pIter;
pIter = 0;

// Close layer table
pTable->close();
pTable = 0;
return es;
}


Never found any information on the int call of function other than trial and error.

Regards,

MJG

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 7012
  • AKA Daniel
Re: how to updata a AcDbViewport object?
« Reply #9 on: December 28, 2007, 11:54:35 AM »
MJG, Thatís a great find, thanks for sharing it!

Dream.Fei

  • Guest
Re: how to updata a AcDbViewport object?
« Reply #10 on: December 29, 2007, 01:38:01 AM »
Thanks for the help.

Dream.Fei

  • Guest
Re: how to updata a AcDbViewport object?
« Reply #11 on: December 29, 2007, 02:03:14 AM »
...
read and save the variable
set the variable to 0
...
reset the variable to the previously saved value.
I'm use the code in a AcDbDatabaseReactor, when a new LayerRecord append,  I want it freezed on some layout's viewport.

If I save the variable and reset it, that is very busy by the code. (for example, if I insert a Xref object, may be have 10-50 layerRecord, so, if save and reset variable........ :-D)

now, in the Arx init (On_kInitAppMsg()), set the variable to 0:
Code: [Select]
  struct resbuf rb;
  rb.restype = RTREAL;
  rb.resval.rreal = 0;
  acedSetVar(_T("LAYOUTREGENCTL"), &rb);
the problem is: if this variable set to 0, any Model or Paper switch will call GraphicModify......

MJG's code give me some inspired, Thanks.

Thanks all~

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: how to updata a AcDbViewport object?
« Reply #12 on: December 29, 2007, 02:14:02 AM »
I don't use CPP but I'm sure some people would appreciate you posting your working revised code from the first post.

Happy that you have an answer.

Quote
I'm use the code in a AcDbDatabaseReactor, when a new LayerRecord append,  I want it freezed on some layout's viewport.

I didn't recall you saying that earlier  ..
« Last Edit: December 29, 2007, 02:17:07 AM by Kerry Brown »
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Dream.Fei

  • Guest
Re: how to updata a AcDbViewport object?
« Reply #13 on: December 29, 2007, 04:01:19 AM »
I didn't recall you saying that earlier  ..
:-)That's my problem..

The project code have no change, only add "set variable" code on the Arx init.....

Now , I'm try updata viewport without change SYSVAR.

Dream.Fei

  • Guest
Re: how to updata a AcDbViewport object?
« Reply #14 on: December 29, 2007, 04:38:04 AM »

// declarations
//
void __stdcall acedRegenLayers(class AcArray<class AcDbObjectId,class AcArrayMemCopyReallocator<class AcDbObjectId> > const &,int);
:cry:
where this function define?

mjguzik

  • Newt
  • Posts: 30
Re: how to updata a AcDbViewport object?
« Reply #15 on: December 31, 2007, 09:11:28 AM »
Just to close out the intent of the above workaround.  The problem was when manipulating the layer table -- changing frozen and off status. It would not update multiple viewports in paperspace without a REGENALL command.  The above was a workaround without requiring a regen and the litter on the command line.

The function is an EXPORT from the "acad.lib" file in the ARX library.  Both the ads_regen and acedRegenLayers need a declaration in a header file before implementing in a cpp file.

Regards,

MJG


Dream.Fei

  • Guest
Re: how to updata a AcDbViewport object?
« Reply #16 on: January 01, 2008, 01:01:04 AM »
Thank you~ MJG, and happy new year~

Dream.Fei

  • Guest
Re: how to updata a AcDbViewport object?
« Reply #17 on: January 02, 2008, 10:37:31 PM »
This's my project for freeze new layer on layout's viewport.
The layout has limit name with 1 to 5. when a new layerrecord append, freeze it on some layout.
On this project, I used "DocumentReactor" "DatabaseRector" and "LayoutReactor".

DocumentReactor: it's support for the MDI.
DatabaseReactor: when a new layerRecord append. call AcDbDatabaseReactor::objectAppend() method for freeze it.
LayoutReacotr: when rename the layout, updata the FreezeLayer's ID Array on the layout.

on this project, I have use "FeiOhter::ReadFileToArray" to get some layer's define from the text file. beacause I think it's too easy, so I don't post this function.

Thank's all help and I hope some one give me a suggest to optimization this project.

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 7012
  • AKA Daniel
Re: how to updata a AcDbViewport object?
« Reply #18 on: January 05, 2008, 07:34:46 AM »
This's my project for freeze new layer on layout's viewport.
The layout has limit name with 1 to 5. when a new layerrecord append, freeze it on some layout.
On this project, I used "DocumentReactor" "DatabaseRector" and "LayoutReactor".

DocumentReactor: it's support for the MDI.
DatabaseReactor: when a new layerRecord append. call AcDbDatabaseReactor::objectAppend() method for freeze it.
LayoutReacotr: when rename the layout, updata the FreezeLayer's ID Array on the layout.

on this project, I have use "FeiOhter::ReadFileToArray" to get some layer's define from the text file. beacause I think it's too easy, so I don't post this function.

Thank's all help and I hope some one give me a suggest to optimization this project.

Nice Coding  8-)

ahlzl

  • Guest
Re: how to updata a AcDbViewport object?
« Reply #19 on: March 10, 2008, 10:33:00 AM »
Ran into this problem some time ago with limited success updating layer changes in multiple viewports.  Then discovered what I believe is an undocumented function.  Hopefully this helps

Code: [Select]

// declarations
//

void __stdcall acedRegenLayers(class AcArray<class AcDbObjectId,class AcArrayMemCopyReallocator<class AcDbObjectId> > const &,int);

void applyLayerChanges();
Acad::ErrorStatus getLayerObjectIdArray();


// Implementation
//

// Usage applies changes to Layer Table forcing update and regen
//
void applyLayerChanges(void)
{
  applyCurDwgLayerTableChanges();
  if ( acdbHostApplicationServices()->workingDatabase()->tilemode() )
     ads_regen(); // Modelspace
  else {
    AcDbObjectIdArray layerIds;
    getLayerObjectIdArray(layerIds);
    acutPrintf(_T("Regenerating layout"));
    acedRegenLayers(layerIds, 0);
  }
  return;
}


// Usage return AcDbObjectIdArray of pDb LayerTable
Acad::ErrorStatus getLayerObjectIdArray(AcDbObjectIdArray& objIds, bool External, AcDbDatabase* pDb)
{
if ( pDb == NULL ) pDb =acdbHostApplicationServices()->workingDatabase();
Acad::ErrorStatus es = Acad::eOk;

AcDbLayerTable* pTable = 0;
es = pDb->getSymbolTable(pTable, AcDb::kForRead);
if ( es != Acad::eOk ) return es;

// Interate layers
//
AcDbLayerTableIterator* pIter = 0;
es = pTable->newIterator(pIter);
if ( es != Acad::eOk ) {
pTable->close();
return es;
}

for (pIter->start();!pIter->done();pIter->step())
{
AcDbLayerTableRecord* pRecord = 0;
es = pIter->getRecord(pRecord, AcDb::kForRead);
if( es == Acad::eOk ) {
if ( pRecord->isDependent() ) {
if (External == true)
objIds.append(pRecord->objectId());
}
else
objIds.append(pRecord->objectId());
}
pRecord->close();
}
delete pIter;
pIter = 0;

// Close layer table
pTable->close();
pTable = 0;
return es;
}


Never found any information on the int call of function other than trial and error.

Regards,

MJG

Study well and make progress every day.