Mimic Line Number > New feature on Plant 3D – 2.0

By Augusto Goncalves

This is an expanded version of what was previously posted here, hence the 2.0

But what was missing on version 1.0?

Actually it considered just one element at a time. Also, it ignored the related elements, like connectors, for instance. Now the sample below gets a selection of entities, then finds related elements (like P3dConnector and Universal) and adds them all to the newly created group.

Thanks to Jens Dorstewitz (ADN Partner) for helping improve it.

[CommandMethod("customNewTag")]
public static void CmdCustomNewTag()
{
    Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

    PromptSelectionResult per = ed.GetSelection();
    if (per.Status != PromptStatus.OK)
    {
        return;
    }

    PromptResult pr = ed.GetString("\nEnter new tag: ");
    if (pr.Status != PromptStatus.OK)
    {
        return;
    }

    ObjectIdCollection ids = new ObjectIdCollection();
    foreach (SelectedObject selObj in per.Value)
    {
        ids.Add(selObj.ObjectId);
    }

    CreateNewTag(ids, pr.StringResult);
}

private static void CreateNewTag(
    ObjectIdCollection itemIds,
    string newTagValue)
{
    PlantProject currentProj = PlantApplication.CurrentProject;
    PipingProject pipeProj =
        (PipingProject)currentProj.ProjectParts["Piping"];
    DataLinksManager dlm = pipeProj.DataLinksManager;
    PnPDatabase db = dlm.GetPnPDatabase();

    // create new line group
    PnPTable p3dLineGroupTable = db.Tables["P3dLineGroup"];
    PnPRow lgRow = p3dLineGroupTable.NewRow();
    lgRow["Tag"] = newTagValue;
    p3dLineGroupTable.Rows.Add(lgRow);
    int newLineGroupId = lgRow.RowId;

    // rowIds of the selected items
    List rowIds = new List();
    foreach (ObjectId itemId in itemIds)
    {
        rowIds.Add(dlm.FindAcPpRowId(itemId));
    }

    // now the rowIds list contain only the
    // items selected on screen, but we need more
    // elements related to those
    List relateRowIds = new List();
    foreach (int itemRowId in rowIds)
    {
        // only Olet, skip others.
        if (db.GetRowTableName(itemRowId) != "Olet")
        {
            continue;
        }

        // get the P3dConnectors
        List p3dConnectorIds = new List();
        p3dConnectorIds.AddRange(
            dlm.GetRelatedRowIds(
                "P3dPartConnection",
                "Part1", itemRowId, "Part2"
            )
        );
        p3dConnectorIds.AddRange(
            dlm.GetRelatedRowIds(
                "P3dPartConnection",
                "Part2", itemRowId, "Part1"
            )
        );

        List universals = new List();
        foreach (int connectorId in p3dConnectorIds)
        {
            // now the Universal:
            // the PnPDataLinks table should contain both
            // P3dConnector and Universal, and both share the
            // same DwgHandleLow value, so find the first and
            // use this value to find the second
            PnPTable datalinksTable = db.Tables["PnPDataLinks"];
            PnPRow[] rows = datalinksTable.Select(
                string.Format("\"RowId\"={0}", connectorId)
            );
            foreach (PnPRow row in rows)
            {
                PnPRow[] universalRow = datalinksTable.Select(
                    string.Format(
                        "\"DwgHandleLow\"={0} AND \"DwgSubIndex\"=1",
                        row["DwgHandleLow"]
                    )
                );
                universals.Add(
                    int.Parse(universalRow[0]["RowId"].ToString()));
            }
        }

        // add what we found to the main list
        relateRowIds.AddRange(p3dConnectorIds);
        relateRowIds.AddRange(universals);
    }

    // finally a list with the selected elements
    // plus all related elements
    // now the rowIds should contain everything
    // that needs to be added to the new line group
    rowIds.AddRange(relateRowIds);

    // .Distinct avoid duplicated
    foreach (int itemRowId in rowIds.Distinct().ToList())
    {
        // get all line groups related to the items we found
        PnPRowIdArray priorGroupIds = dlm.GetRelatedRowIds(
            "P3dLineGroupPartRelationship",
            "Part", itemRowId, "LineGroup"
        );

        // remove them from any previous group
        if (priorGroupIds.Count != 1)
        {
            foreach (int id in priorGroupIds)
            {
                dlm.Unrelate(
                    "P3dLineGroupPartRelationship",
                    "LineGroup", id,
                    "Part", itemRowId
                );
            }
        }

        // make the new relation
        if (newLineGroupId != -1 && itemRowId != -1)
        {
            dlm.Relate(
                "P3dLineGroupPartRelationship",
                "LineGroup", newLineGroupId,
                "Part", itemRowId
            );
        }
    }

    // relate the drawing to the line group
    int dwgId = dlm.GetDrawingId(
        Application.DocumentManager.MdiActiveDocument.Database
    );
    if (dwgId != -1)
    {
        dlm.Relate(
            "P3dDrawingLineGroupRelationship",
            "Drawing", dwgId,
            "LineGroup", newLineGroupId
        );
    }
}

Comments

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading