How to get and set the current viewport in RealDWG?

How to get and set the current viewport in RealDWG?

tbrammer
Advisor Advisor
2,753 Views
5 Replies
Message 1 of 6

How to get and set the current viewport in RealDWG?

tbrammer
Advisor
Advisor

in RealDWG all acedXXX() functions are missing. Especially:

  • AcDbObjectId acedActiveViewportId();
  • Acad::ErrorStatus acedSetCurrentVPort(int vpnumber);
  • Acad::ErrorStatus acedSetCurrentVPort(const AcDbViewport* pVp);

How can I implement them in RealDWG? IMO this should be possible because the information about the current layout and current viewport is in the AcDbDatabase.  So it should not depend on the AutoCAD editor.

 

I managed to implement AcDbObjectId acedGetCurViewportObjectId():
The current layout's BTR can be retrieved by AcDbDatabase::currentSpaceId(). There is no direct API to identify the active viewport within a layer. But the active viewport has DXFCODE 68 == 1. So it can be found using acdbEntGet(entname).

acedActiveViewportId() however should also return the active AcDbViewportTableRecord ID if TILEMODE=1. But how do I find the active one if there are more than one? They are all named "*Active".

 

In AutoCAD CVPORT holds an identifier for the viewport. But RealDWG has no acedGetVar()/acedSetVar() to access variables
and CVPORT can't be accessed from AcDbDatabase allthough it is store in the drawing.

I have no idea how to implement acedSetCurrentVPort(...). At least I could change DXFCODE 68 of a viewport if acdbEntMod(const struct resbuf*) would exist in RealDWG.


I implemented acdbEntGet(name) myself using dxfOut() with a custom AcDbDxfFiler that simply records written DXF-codes.
But I have no idea how to implement acdbEntMod(..)

 

Any ideas?


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
2,754 Views
5 Replies
Replies (5)
Message 2 of 6

tbrammer
Advisor
Advisor

I just found out that these functions are available in RealDWG:

AcDbObjectId      acdbGetCurVportTableRecordId(AcDbDatabase* pDb);
AcDbObjectId      acdbGetCurVportId(AcDbDatabase* pDb);
Acad::ErrorStatus acdbGetCurUserViewportId(AcDbDatabase*, AcDbObjectId&);

They should allow me to implement acedActiveViewportId() too.

 

Still no idea how to implement acedSetXXX().

 

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 3 of 6

owenwengerd
Advisor
Advisor

@tbrammer wrote:

 

I have no idea how to implement acedSetCurrentVPort(...). At least I could change DXFCODE 68 of a viewport if acdbEntMod(const struct resbuf*) would exist in RealDWG.


I implemented acdbEntGet(name) myself using dxfOut() with a custom AcDbDxfFiler that simply records written DXF-codes.
But I have no idea how to implement acdbEntMod(..)

 

Any ideas?


 

acedEntMod() is just AcDbObject::dxfInFields, and I recall the current vport is always the first. At least, I'm pretty sure sequence matters in the vport table.

--
Owen Wengerd
ManuSoft
0 Likes
Message 4 of 6

tbrammer
Advisor
Advisor

Hi Owen,

 

thanks for your reply.

> acedEntMod() is just AcDbObject::dxfInFields

Well, yes. But how do I get the AcDbDxfFiler for AcDbObject::dxfInFields(AcDbDxfFiler *pFiler)? And how exactly should I use it?

The process could work somehow like this:

MyDxfFiler filer; 
AcDbObject *pObj = <whatever>;
pObj->dxfOutFields(&filer);         // MyDxfFile internally creates a resbuf list
filer.modifyResbufData(<whatever>); // Modify the objects resbuf list
pObj->dxfInFields(&filer);          // Miracles happen here... 

AcDbDxfFiler  is a pure virtual class. So I need a filer object from a derived class that implements the pure virtual methods. I implemented

class MyDxfFiler: public AcDbDxfFiler. It's writeXXX() methods just create a resbuf list.

The big question is: What happens in pObj->dxfInFields(&filer)?

  • Which AcDbDxfFiler-methods will be called?
  • Do I have to call AcDbDxfFiler::rewindFiler()?
  • Does this work with the same AcDbObject or must I use a new AcDbObject?

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 5 of 6

tbrammer
Advisor
Advisor

> I recall the current vport is always the first. At least, I'm pretty sure sequence matters in the vport table.

 

When I use the command SNOOPDB from <ARX>\samples\database\arxdbg and look into the Viewport Table the "*Active" viewports are always listed in the same order - no matter which VP is active. And their data (like Viewdir) isn't swapped when the current VP changes (I saved ard reloaded to make sure that the data is updated). I'm not sure how ArxDbg iterates over the viewport table. Maybe they use a "wrong iterator".

However - even if the order matters: How could I change the order? As I said implementing acedActiveViewportId() is no problem - setting the active viewport is.

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 6 of 6

owenwengerd
Advisor
Advisor

@tbrammer wrote:

Well, yes. But how do I get the AcDbDxfFiler for AcDbObject::dxfInFields(AcDbDxfFiler *pFiler)? And how exactly should I use it?

 


Of course you have to implement a DXF filer, and then use it to feed the DXF data to an object, either a new one or an existing one, it shouldn't matter. You could first write the object data, then modify it, then rewind the file and read it back in, but that's completely up to you. You can just as well implement a dxf filer that provides requested data from a caller-provided resbuf list. As far as which methods you have to implement, well, all of them, at least if you want everything to work. 🙂

--
Owen Wengerd
ManuSoft
0 Likes