Hi Community,
I'm using a AcDbVisibilityOverrule to temporarily hide all Entities in the drawing except a small set.
This Process is slow for big Drawings. Do you know a way to speed up the unhiding process?
Thanks in advance,
Martin
I tried to hide all entities in the database traversing the database and call setVisibility for them. This lead to a delay when hiding AND unhiding the objects. Using AcDbVisibilityOverrule only lead to a delay when unhiding the objects when calling. I also tried to use a AcGiDrawableOverrule with empty worldDraw and viewportDraw routines. It worked but wasn't faster.
Thanks anyway. As you said, there seems to be no faster solution. I compared it with the block editor. It's equaly slow when closed.
Maybe I can limit the area of my Jig operation. Currently the user can zoom out as far as he likes. This doesn't make sense. When the area is limited, I could only hide entities inside that area. Which could be a lot faster. Any ideas about that?
Thanks.
Martin
I would also expect that using AcDbEntity::setVisibility() is the most performant way to change visibilities.
The show/hide performance should be comparable to thawing/freezing layers.
When you tried setVisibility(), did you force the GS (graphic system) somehow to update each entity after you changed its visibility? I.e. by calling AcDbEntity::draw() / AcDbEntity::recordGraphicsModified() / acedUpdateDisplay() / actrTransactionManager.flushGraphics() / acedRedraw() / ...? This would slow down the performance. It is better to do all changes within a transaction and let the GS do the update for all modified entities at once.
You might want to test performance with this simple code that hides/shows all modelspace entities on layer 0:
void visOnLayerId(AcDbObjectId idLayer, AcDb::Visibility vis) { AcDbDatabase *pDB = acdbHostApplicationServices()->workingDatabase(); AcDbObjectId IdModelSpace = acdbSymUtil()->blockModelSpaceId(pDB); AcDbBlockTableRecord *model; Acad::ErrorStatus es; if ( (es=acdbOpenObject(model, IdModelSpace, AcDb::kForRead)) == Acad::eOk ) { AcDbBlockTableRecordIterator *pit; es = model->newIterator(pit); if (pit) { for (pit->start(); !pit->done(); pit->step()) { AcDbEntity *entity=nullptr; es = pit->getEntity(entity, AcDb::kForRead); if (!es) { if (entity->layerId() == idLayer) { if (entity->visibility()!=vis) { if (!entity->upgradeOpen()) entity->setVisibility(vis); } } entity->close(); } } delete pit; } model->close(); } } void cmdHide() { AcDbDatabase *pDB = acdbHostApplicationServices()->workingDatabase(); AcDbObjectId idLayer0 = acdbSymUtil()->layerZeroId(pDB); visOnLayerId(idLayer0, AcDb::kInvisible); } void cmdShow() { AcDbDatabase *pDB = acdbHostApplicationServices()->workingDatabase(); AcDbObjectId idLayer0 = acdbSymUtil()->layerZeroId(pDB); visOnLayerId(idLayer0, AcDb::kVisible); }
It is not suprisingly slow. It is slow, because there are more then 11.000 Entities in the drawing. These objects are of custom type. They work like a block reference, pointing to an unonymous block. This block contains a polyline and a hatch. So there are about 33.000 entities and 11.000 blocks involved.
I'm searching for a way to clear the view without processing all entities. Maybe by limiting the working area. Or for maybe I can delay the processing in some way not unhiding them all at once.
Can't find what you're looking for? Ask the community or share your knowledge.