← Inbox

C3D-0302 · 260610 Tara Blvd: TXT2MTXT the store text, set Arial, add category tags error

Converts all 25 store DBText to MText preserving position/height/rotation/layer, puts every store label (converted plus the 3 existing MText) on style GF_050 which is real arial.ttf - NOT the style named ARIAL which maps to swissb.ttf Swis721 BT - and adds a smaller category tag under each merchandise label using the 7 categories from the sheet: Fresh Fruits and Vegetables, Fresh Uncooked Meats, Dairy Products, Canned Foods, Frozen Foods, Dry groceries and baked goods, Non-Alcoholic beverages. Non-merchandise labels (aisle, exit, gameroom, bathroom, elec room, locker, entrance, t-shirts, checkout counters, HSE products) get no tag. Verifies no DBText remains and everything is on the Arial style.

Script file
C3D-0302.cs
Target
260610 - 6736 Tara Blvd R2.dwg · model space
Author
claude
Approved
yes · auto-auth
Timeout
60s

C# payload

// 260610 Tara Blvd store plan:
//   1. convert every DBText in the store to MText (TXT2MTXT equivalent, done in the API so
//      position/height/rotation/layer are preserved exactly)
//   2. put ALL of it - converted and pre-existing MText - on real Arial
//   3. add a category tag under each fixture label, from the 7 sheet categories
//
// FONT: the style named "ARIAL" maps to swissb.ttf ("Swis721 BT"), NOT Arial. The only style on
// real arial.ttf is GF_050. Using GF_050 so the text is genuinely Arial.
//
// The 7 categories, verbatim from the sheet MText [21991]:
//   Fresh Fruits & Vegetables / Fresh Uncooked Meats, seafood, poultry / Dairy Products /
//   Canned Foods / Frozen Foods / Dry groceries and baked goods / Non-Alcoholic beverages
// Anything that is not merchandise (aisle, exit, gameroom, ...) gets no tag.
const string FONT = "GF_050";
double X0 = 2261060, X1 = 2261110, Y0 = 1391805, Y1 = 1391860;

var tst = (TextStyleTable)Tx.GetObject(Db.TextStyleTableId, OpenMode.ForRead);
if (!tst.Has(FONT)) { Log("text style " + FONT + " missing"); return; }
ObjectId styleId = tst[FONT];
{
    var ts = (TextStyleTableRecord)Tx.GetObject(styleId, OpenMode.ForRead);
    string tt = ""; try { tt = ts.Font.TypeFace; } catch { }
    Log("font style: " + ts.Name + "  file=" + ts.FileName + "  TTF=\"" + tt + "\"");
}

// label -> category. Only merchandise gets a tag.
var cat = new Dictionary<string,string>(StringComparer.OrdinalIgnoreCase) {
    { "fruit",               "Fresh Fruits & Vegetables" },
    { "frozen food",         "Frozen Foods" },
    { "ice cream",           "Frozen Foods" },
    { "cabnits",             "Frozen Foods" },
    { "drinks",              "Non-Alcoholic beverages" },
    { "NON-ALCOHOIC DRINKS", "Non-Alcoholic beverages" },
    { "chips",               "Dry groceries and baked goods" },
    { "candy",               "Dry groceries and baked goods" },
    { "Candy",               "Dry groceries and baked goods" },
    { "snacks",              "Dry groceries and baked goods" },
    { "Food",                "Dry groceries and baked goods" },
};

var ms = (BlockTableRecord)Tx.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(Db), OpenMode.ForWrite);

// ---- collect first; converting while iterating the same BTR is not safe
var work = new List<ObjectId>();
foreach (ObjectId id in ms) {
    var ent = Tx.GetObject(id, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Entity;
    if (ent == null) continue;
    if (!(ent is DBText) && !(ent is MText)) continue;
    double x, y;
    var d0 = ent as DBText; var m0 = ent as MText;
    if (d0 != null) { x = d0.Position.X; y = d0.Position.Y; } else { x = m0.Location.X; y = m0.Location.Y; }
    if (x < X0 || x > X1 || y < Y0 || y > Y1) continue;
    work.Add(id);
}
Log("store text entities: " + work.Count);

int converted = 0, restyled = 0, tagged = 0;
var tags = new List<Tuple<Point3d,double,double,string,string>>();   // pos, height, rot, layer, category

foreach (ObjectId id in work) {
    var ent = Tx.GetObject(id, OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.Entity;
    if (ent == null) continue;

    string content; Point3d pos; double hgt, rot; string layer = ent.Layer;

    var dt = ent as DBText;
    if (dt != null) {
        content = dt.TextString; pos = dt.Position; hgt = dt.Height; rot = dt.Rotation;
        // build the MText replacement at the same place
        var nm = new MText();
        nm.SetDatabaseDefaults();
        nm.TextStyleId = styleId;
        nm.TextHeight = hgt;
        nm.Location = pos;
        nm.Rotation = rot;
        nm.Attachment = AttachmentPoint.BottomLeft;
        nm.Layer = layer;
        nm.Contents = content;
        ms.AppendEntity(nm);
        Tx.AddNewlyCreatedDBObject(nm, true);
        dt.Erase();
        converted++;
        Log(string.Format("  DBText [{0}] -> MText [{1}] \"{2}\"", dt.Handle, nm.Handle, content));
    } else {
        var mt = (MText)ent;
        content = mt.Contents; pos = mt.Location; hgt = mt.TextHeight; rot = mt.Rotation;
        mt.TextStyleId = styleId;
        restyled++;
        Log(string.Format("  MText [{0}] restyled \"{1}\"", mt.Handle, content.Replace("\n"," / ")));
    }

    string c;
    if (cat.TryGetValue(content.Trim(), out c))
        tags.Add(Tuple.Create(pos, hgt, rot, layer, c));
}

// ---- category tags, placed just under each merchandise label
foreach (var t in tags) {
    var pos = t.Item1; double hgt = t.Item2, rot = t.Item3;
    double th = hgt * 0.55;
    // offset perpendicular to the text direction so rotated labels stay readable
    double dx = Math.Sin(rot) * (th * 1.6), dy = -Math.Cos(rot) * (th * 1.6);
    var tag = new MText();
    tag.SetDatabaseDefaults();
    tag.TextStyleId = styleId;
    tag.TextHeight = th;
    tag.Location = new Point3d(pos.X + dx, pos.Y + dy, 0);
    tag.Rotation = rot;
    tag.Attachment = AttachmentPoint.BottomLeft;
    tag.Layer = t.Item4;
    tag.Contents = t.Item5;
    ms.AppendEntity(tag);
    Tx.AddNewlyCreatedDBObject(tag, true);
    tagged++;
    Log(string.Format("  TAG [{0}] ({1:F2},{2:F2}) \"{3}\"", tag.Handle, tag.Location.X, tag.Location.Y, t.Item5));
}

// ---- verify: nothing left as DBText, everything on the Arial style
int leftDb = 0, wrongStyle = 0, total = 0;
foreach (ObjectId id in ms) {
    var ent = Tx.GetObject(id, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Entity;
    if (ent == null || ent.IsErased) continue;
    var d = ent as DBText; var m = ent as MText;
    if (d == null && m == null) continue;
    double x, y;
    if (d != null) { x = d.Position.X; y = d.Position.Y; } else { x = m.Location.X; y = m.Location.Y; }
    if (x < X0 || x > X1 || y < Y0 || y > Y1) continue;
    total++;
    if (d != null) leftDb++;
    ObjectId sid = d != null ? d.TextStyleId : m.TextStyleId;
    if (sid != styleId) wrongStyle++;
}
Log("");
Log(string.Format("converted {0} DBText -> MText, restyled {1} existing MText, added {2} category tags",
    converted, restyled, tagged));
Log(string.Format("VERIFY: {0} text entities in the store, DBText remaining = {1}, not on {2} = {3}",
    total, leftDb, FONT, wrongStyle));
Ed.Regen();

Result

Status
error
Drawing file
C:\Users\sanja\OneDrive\_SurveyDisco\260610 - 6736 Tara Blvd, Jonesboro, GA 30236, USA\260610 - 6736 Tara Blvd R2.dwg
Message
An item with the same key has already been added. Key: Candy
Entities
Duration
646 ms
Civil 3D
25.0.0.0

Log

font style: GF_050  file=arial.ttf  TTF="Arial"

Notes

What worked, what didn't, job-specific gotchas — flagged notes feed the recipes.

No notes yet.