.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IsolateSelection function not working when used in a loop.

8 REPLIES 8
Reply
Message 1 of 9
ShricharanaB
333 Views, 8 Replies

IsolateSelection function not working when used in a loop.

Hi, 

 

I want to isolate an object, zoom to it, take snapshot of it then move on to the next object and do the same in a loop.

I'm currently stuck at isolating the objects one after the other.  

I got these following methods from this forum, from one of _gile's answers(thanks!) 

 

 public static void IsolateSelection(SelectionSet ss)
 {
     Document doc = Application.DocumentManager.MdiActiveDocument;
     Database db = doc.Database;
     Editor ed = doc.Editor;
     //var selection = ed.GetSelection();
     //if (selection.Status != PromptStatus.OK)
     //    return;
     var ids = new HashSet<ObjectId>(ss.GetObjectIds());
     using (var tr = new OpenCloseTransaction())
     {
         var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
         foreach (ObjectId id in curSpace)
         {
             if (!ids.Contains(id))
             {
                 var entity = (Entity)tr.GetObject(id, OpenMode.ForWrite);
                 entity.Visible = false;
             }
             else
             {
                 var entity = (Entity)tr.GetObject(id, OpenMode.ForWrite);
                 entity.Visible = true;
             }


         }
         tr.Commit();
     }
 }

 public static void UnisolateAll()
 {
     var db = HostApplicationServices.WorkingDatabase;
     using (var tr = new OpenCloseTransaction())
     {
         var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
         foreach (ObjectId id in curSpace)
         {
             var entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
             if (!entity.Visible)
             {
                 entity.UpgradeOpen();
                 entity.Visible = true;
             }
         }
         tr.Commit();
     }
 }

 

 

 

This is working only the first time in the loop, after the first time its not isolating the next object. 

As a result, the snapshots are correct for only the first block. For the rest only the first block is visible instead of the respective blocks being visible.

 

What am I doing wrong here? 

Any help is appreciated!

 

Here is the code calling the IsolateSelection() method

 

foreach (SelectedObject sObj in ss)
{
    BlockReference br = trans.GetObject(sObj.ObjectId, OpenMode.ForRead) as BlockReference;
    string blockName;
    if (br.IsDynamicBlock)
    {
        blockName = ((BlockTableRecord)br.DynamicBlockTableRecord.GetObject(OpenMode.ForRead)).Name;
    }
    else
    {
        blockName = br.Name;
    }

    if (blockName.Contains("pdgblock"))
    {
      ObjectId[] objectIds = new ObjectId[1];
        objectIds[0] = sObj.ObjectId;                                
        SelectionSet ss2 = SelectionSet.FromObjectIds(objectIds);
        //edt.SetImpliedSelection(objectIds);        
        ObjectVisibility.IsolateSelection(ss2);
       
        ObjectIdCollection objIDCol = new ObjectIdCollection(ss2.GetObjectIds());
        string comm;
        foreach (string view in viewList)
        {
            SetCurrentView(view);                                   
            Zoom.ZoomObjects(objIDCol);
            comm = Path.GetDirectoryName(db.Filename);
            comm = comm + "\\images\\" + blockName + "_" + view + ".jpeg";
            CaptureImage.CreatePreviewImage(comm);

        }
        
        
    }
}

Edit: attached example drawing.

 

 

Labels (3)
8 REPLIES 8
Message 2 of 9
ShricharanaB
in reply to: ShricharanaB

Hi, 

 I've still not been able to isolate the issue. Can anyone help? 

 

Thanks in advance.

Message 3 of 9

I can't tell you exactly why your code isn't doing what you expect but I can't tell you that it is not really the best way to achieve your end objective.

 

You should start out by hiding all objects in the drawing or current space, then iterating over your list of block references, unhiding each one, make a snapshot of it, hide it again, and then move on to the next block reference and repeat the process. All of that would be done within a loop that might also need to include a regen to force a display update. And after you have finished processing all of your block references you can then restore the visibility of all objects to what they were when you started.

 

So my suggestion would be to completely rewrite the code to work thusly.

 

 

Message 4 of 9

@ActivistInvestor 

 

I took your suggestion and created a function to hide all first. Then I'm creating a transaction to open the current object in the loop for write and set visibility to true and then using editor.regen to regenerate.

 

Interestingly, HideAll (opposite of UnisolateAll) function hides everything in the beginning without fail. Then the in the loop the current object is made visible without fail. 

 

But it fails to hide the current object after I get the screenshots (though the transaction commits successfully). So what is happening is, through out the loop, the number of blocks visible are increasing as they are made visible but are not being hidden. There is no error shown either. I tried to use the HideAll function after image creation each time to see if that would work but still no difference. 

What am I missing? Is the object not being made available to write after I first make it visible? If so there should have been an error. 

 

Here is the updated code for each block

 

 

if (blockName.Contains("pdgblock"))
	{
		
		using (OpenCloseTransaction trans2 = new OpenCloseTransaction())
		{
			Entity ent = trans2.GetObject(sObj.ObjectId, OpenMode.ForWrite) as Entity;                                    
			ent.Visible = true;                                
			trans2.Commit();                                   
		}                                
	   
		edt.Regen();

		ObjectId[] objectIds = new ObjectId[1];
		objectIds[0] = sObj.ObjectId;                                
		SelectionSet ss2 = SelectionSet.FromObjectIds(objectIds);
		
		ObjectIdCollection objIDCol = new ObjectIdCollection(ss2.GetObjectIds());
		string comm;
		foreach (string view in viewList)
		{
			SetCurrentView(view);                                   
			Zoom.ZoomObjects(objIDCol);
			comm = Path.GetDirectoryName(db.Filename);
			comm = comm + "\\images\\" + blockName + "_" + view + ".jpeg";
			CaptureImage.CreatePreviewImage(comm);
		   
		}
	
		using (OpenCloseTransaction trans3 = new OpenCloseTransaction())
		{

			Entity ent = trans3.GetObject(sObj.ObjectId, OpenMode.ForWrite) as Entity;   
			ent.Visible = false;
			trans3.Commit();                               
		}
	}

 

 

 

Message 5 of 9
ShricharanaB
in reply to: ShricharanaB

Here is a workaround I just thought of for the the hiding issue.  Tested and working.

Since any object that is made visible is failing to be hidden again. I'm erasing the object instead of hiding it, then making the next object visible. I wrapped the whole thing in another transaction which I'm aborting at the end no matter what so none of the objects are really deleted.

 

I'd still like to understand why the objects weren't being hidden though. 

 

here is the updated trans3 code.

 

using (Transaction trans3 = db.TransactionManager.StartTransaction())
{

    Entity ent = trans3.GetObject(sObj.ObjectId, OpenMode.ForWrite) as Entity;
    //ent.UpgradeOpen();
    ent.Erase();
    //ent.Dispose();
    trans3.Commit();
    
}

 

 

Message 6 of 9

did you try to call the QueueForGraphicFlush() method of the database transaction manager?
I remember I once had an issue and Norman pointed that out and it solved my issue.
so basically you would go like db.TransactionManager.QueueForGraphicFlush() in your loop.

Tags (1)
Message 7 of 9

My guess is that the problem maybe related to the use of the OpenCloseTransaction. It doesn't do any kind of display management.

 

Try using a Transaction started via the Document's TransactionManager instead. You may also need to use EnableGraphicsFlush() and FlushGraphics() as well.

Message 8 of 9
ShricharanaB
in reply to: ShricharanaB

@a.kouchakzadeh  No I have not tried that. I'll give it a go.

@ActivistInvestor  When I used TransactionManager.StartTransaction()  the objects wouldn't unhide either.

I'll try using QueueForGraphicFlush(), EnableGraphicsFlush(), FlushGraphics() and see and get back to you. 

 

 

Message 9 of 9

I presume that you used the Document's TransactionManager as opposed to the Database's TransactionManager?

 

There is a subtle difference.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost