Automatically Move Hatch(es) in Block to Background

Automatically Move Hatch(es) in Block to Background

M_Kocyigit
Enthusiast Enthusiast
289 Views
5 Replies
Message 1 of 6

Automatically Move Hatch(es) in Block to Background

M_Kocyigit
Enthusiast
Enthusiast

Hello everyone,


I have a block that contains one or more hatches, and I would like to automatically move these hatches to the background using the API, so they don't overlap other objects.

Has anyone found a solution or have an example of how to move all hatches within a block to the background?


Thank you

0 Likes
Accepted solutions (2)
290 Views
5 Replies
Replies (5)
Message 2 of 6

_gile
Consultant
Consultant
Accepted solution

Hi,

You can get the DrawOrderTable of the block definition (BlockTableRecord) using the BlockTableRecord.DrawOrderTableId property. The DrawOrderTable provides a MoveToBottom method.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 6

M_Kocyigit
Enthusiast
Enthusiast

Hi Gile,


thank you for your response and your hint!


I have already created a similar code, but it has no graphical effect at all. What could be the reason for this?
Do I need to regenerate or update the selected block—possibly with a screen refresh (Flush Screen)?

Both system variables, DRAWORDERCTL and HPDRAWORDER, seem to be correctly set to a value of 3.
Are there any insights regarding dictionaries or other system variables that might affect this?



public  void MoveHatchesToBackInBlock    ( )
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db  = doc.Database;
    Editor   ed  = doc.Editor;

    PromptEntityOptions promptOptions = new PromptEntityOptions("\nSelect a block reference:");

    promptOptions.SetRejectMessage("\nOnly block references are allowed.");

    promptOptions.AddAllowedClass ( typeof ( BlockReference ), true );

    PromptEntityResult promptResult = ed.GetEntity ( promptOptions );

    if ( promptResult.Status != PromptStatus.OK )
    {
        ed.WriteMessage("\nCommand canceled.");
        return;
    }

    ObjectId           blockId  = promptResult.ObjectId;
    ObjectIdCollection hatchIds = new ObjectIdCollection ();

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        BlockReference blockRef = tr.GetObject ( blockId, OpenMode.ForRead) as BlockReference;

        if ( blockRef == null )
        {
            ed.WriteMessage("\nSelected entity is not a block reference.");

            return;
        }

        BlockTableRecord blockRecord = tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;

        foreach (ObjectId entId in blockRecord)
        {
            Entity entity = tr.GetObject(entId, OpenMode.ForRead) as Entity;

            ed.WriteMessage("\nEntity: " + entity.GetType() );

            if ( entity is Hatch )
            {
                ed.WriteMessage(" ... hatch found. " );

                hatchIds.Add ( entId );
            }
        }

        if ( hatchIds.Count > 0 )
        {
            DrawOrderTable drawOrderTable = tr.GetObject( blockRecord.DrawOrderTableId, OpenMode.ForWrite ) as DrawOrderTable;

            drawOrderTable.MoveToBottom( hatchIds );

            ed.WriteMessage("\nAll hatches (" + hatchIds.Count + ") + have been moved to the back within the block.");

        }
        else
        {
            ed.WriteMessage("\nNo hatches found in the block.");
        }

        tr.Commit();
    }
}

 

0 Likes
Message 4 of 6

ActivistInvestor
Mentor
Mentor
Accepted solution

Have you tried doing a REGEN after your code runs to see if that's the issue?  When changes are made to block definitions, views containing insertions of those blocks are not updated automatically. You can force them to update in one of several ways, but the simpliest and easiest is Editor.Regen().

Message 5 of 6

M_Kocyigit
Enthusiast
Enthusiast

Hi,

thank you for your hint. That does indeed seem to be the issue. Now the block is displayed correctly, and the contours are clearly visible.
However, I’m still interested in what other possibilities exist (several ways).

Ed.Regen() seems to regenerate the entire drawing, right?

0 Likes
Message 6 of 6

M_Kocyigit
Enthusiast
Enthusiast

I have tested various options in the meantime and have arrived at an acceptable solution. With the following code, it is possible to regenerate only the object so that the hatches appear in the correct order visually and the contours become visible.

if ( hatchIds.Count > 0 )
{

    blockRef.UpgradeOpen();

    DrawOrderTable drawOrderTable = tr.GetObject( blockRecord.DrawOrderTableId, OpenMode.ForWrite ) as DrawOrderTable;

    drawOrderTable.MoveToBottom( hatchIds );


    // Solution: The better way

    blockRef.RecordGraphicsModified ( true );


    // 1. It works and regenerates the entire drawing. However, the process takes longer with larger drawings
    // ed.Regen ();
                 
    // 2. No effect!
    // blockRef?.ResetBlock ();

    // 3. No effect!
    // Application.DocumentManager.MdiActiveDocument.Editor.UpdateScreen();


    ed.WriteMessage("\nAll hatches (" + hatchIds.Count + ") + have been moved to the back within the block.");

    blockRef.DowngradeOpen();
}

 

0 Likes