Waarom lagen beheren vanuit code?
Wanneer je add-in automatisch objecten aanmaakt, wil je die op de juiste lagen plaatsen — niet op de actieve laag van de gebruiker, maar op gedefinieerde lagen met de juiste kleur, lijntype en lijndikte. Zo is de uitvoer altijd consistent, ongeacht hoe de tekening van de gebruiker is ingesteld.
Een laag aanmaken
Lagen zitten in de LayerTable van de database. Je opent die, controleert of de laag al bestaat, en maakt hem anders aan:
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Colors;
/// <summary>
/// Maakt een laag aan als die nog niet bestaat, of retourneert de bestaande laag.
/// Geeft de ObjectId van de laag terug zodat je entiteiten erop kunt plaatsen.
/// </summary>
public static ObjectId ZorgVoorLaag(Database db, Transaction tr,
string naam, short kleurIndex, string lijntype = "Continuous")
{
// Haal de LayerTable op voor schrijven
LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
// Als de laag al bestaat, retourneer haar ObjectId direct
if (lt.Has(naam))
return lt[naam];
// Laag bestaat niet — open de table voor schrijven en maak haar aan
lt.UpgradeOpen();
LayerTableRecord laag = new LayerTableRecord();
laag.Name = naam;
laag.Color = Color.FromColorIndex(ColorMethod.ByAci, kleurIndex);
laag.LineWeight = LineWeight.LineWeight025; // 0.25 mm standaard
// Voeg de laag toe en registreer haar in de transactie
ObjectId laagId = lt.Add(laag);
tr.AddNewlyCreatedDBObject(laag, true);
return laagId;
}
Lijntype koppelen aan een laag
Voordat je een lijntype aan een laag koppelt, moet het lijntype geladen zijn in de database. AutoCAD laadt standaard alleen "Continuous" — andere lijntypes (DASHED, CENTER, HIDDEN, …) moet je expliciet laden:
/// <summary>
/// Laadt een lijntype uit de standaard AutoCAD lijntype-bibliotheek (acad.lin).
/// Doet niets als het lijntype al geladen is.
/// </summary>
public static void LaadLijntype(Database db, string naam)
{
LinetypeTable lt = db.TransactionManager.GetObject(
db.LinetypeTableId, OpenMode.ForRead) as LinetypeTable;
// Alleen laden als het nog niet in de database zit
if (!lt.Has(naam))
{
// acad.lin bevat alle standaard AutoCAD-lijntypes
db.LoadLineTypeFile(naam, "acad.lin");
}
}
// Gebruik:
LaadLijntype(db, "DASHED");
LaadLijntype(db, "CENTER");
Daarna koppel je het lijntype aan de laag:
// Na het aanmaken van de laag, stel het lijntype in
LinetypeTable ltt = tr.GetObject(db.LinetypeTableId, OpenMode.ForRead) as LinetypeTable;
if (ltt.Has("DASHED"))
laag.LinetypeObjectId = ltt["DASHED"];
Een object op een specifieke laag plaatsen
Je stelt de laag in via de LayerId property van de entiteit, vóór je hem toevoegt aan de ModelSpace:
[CommandMethod("KLEVERLAAGENTEST")]
public void LaagEnTest()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Laad benodigde lijntypes
LaadLijntype(db, "DASHED");
// Maak twee lagen aan
ObjectId laagConstructie = ZorgVoorLaag(db, tr, "KC-CONSTRUCTIE", 5); // blauw
ObjectId laagMaatvoeringId = ZorgVoorLaag(db, tr, "KC-MAATVOERING", 3); // groen
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord ms = tr.GetObject(
bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
// Lijn op de constructielaag
Line lijn = new Line(new Point3d(0, 0, 0), new Point3d(150, 0, 0));
lijn.LayerId = laagConstructie; // koppel aan laag
ms.AppendEntity(lijn);
tr.AddNewlyCreatedDBObject(lijn, true);
// Maatlijn-placeholder op de maatvoeringslaag
Line maat = new Line(new Point3d(0, -10, 0), new Point3d(150, -10, 0));
maat.LayerId = laagMaatvoeringId;
ms.AppendEntity(maat);
tr.AddNewlyCreatedDBObject(maat, true);
tr.Commit();
}
}
Bestaande objecten verplaatsen naar een andere laag
Wil je bestaande entiteiten van laag wijzigen, dan open je ze voor schrijven en pas je de LayerId aan:
/// <summary>
/// Verplaatst alle entiteiten op "oudeLaag" naar "nieuweLaag".
/// </summary>
public static void WijzigLaag(Database db, Transaction tr,
string oudeLaag, string nieuweLaag)
{
LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
// Controleer of beide lagen bestaan
if (!lt.Has(oudeLaag) || !lt.Has(nieuweLaag)) return;
ObjectId nieuweLaagId = lt[nieuweLaag];
// Loop door alle entiteiten in de ModelSpace
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord ms = tr.GetObject(
bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
foreach (ObjectId entId in ms)
{
Entity ent = tr.GetObject(entId, OpenMode.ForRead) as Entity;
if (ent == null) continue;
// Alleen verplaatsen als de entiteit op de oude laag zit
if (ent.Layer == oudeLaag)
{
ent.UpgradeOpen(); // schakel over naar schrijfmodus
ent.LayerId = nieuweLaagId;
}
}
}
Laageigenschappen achteraf aanpassen
Je kunt ook eigenschappen van bestaande lagen aanpassen — handig als je een standaard tekensjabloon wilt normaliseren:
[CommandMethod("KLEVERLAAGRESET")]
public void LaagReset()
{
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
// Loop door alle lagen
foreach (ObjectId laagId in lt)
{
LayerTableRecord laag = tr.GetObject(laagId, OpenMode.ForRead) as LayerTableRecord;
// Vergrendel lagen die beginnen met "REF-"
if (laag.Name.StartsWith("REF-", StringComparison.OrdinalIgnoreCase))
{
laag.UpgradeOpen();
laag.IsLocked = true; // vergrendel de laag
laag.Color = Color.FromColorIndex(ColorMethod.ByAci, 8); // grijs
}
}
tr.Commit();
}
}
Handige laagoverzicht-hulpfunctie
/// <summary>
/// Schrijft een overzicht van alle lagen naar de AutoCAD commandoregel.
/// Nuttig tijdens development om te verifiëren welke lagen aanwezig zijn.
/// </summary>
[CommandMethod("KLEVERLAAGOVERZICHT")]
public void LaagOverzicht()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
ed.WriteMessage($"\n--- Lagen in tekening ({lt.Cast().Count()}) ---");
foreach (ObjectId laagId in lt)
{
LayerTableRecord laag = tr.GetObject(laagId, OpenMode.ForRead) as LayerTableRecord;
string status = laag.IsOff ? "[UIT]" :
laag.IsLocked ? "[VERGR]" :
laag.IsFrozen ? "[BEVROREN]": "[AAN]";
ed.WriteMessage($"\n {laag.Name,-20} ACI:{laag.Color.ColorIndex,-4} {status}");
}
}
}
Conclusie
Door lagen programmatisch aan te maken en te beheren, geeft je add-in altijd een consistente tekenstructuur — ongeacht de startsituatie van de gebruiker. Gebruik de ZorgVoorLaag-hulpfunctie als bouwsteen in elk commando dat objecten aanmaakt.
Volgende post: hoe je gebruikersinvoer verwerkt en objecten laat selecteren in je add-in.
Comments
No comments yet — be the first!
Leave a comment
Sign in to skip moderation — anonymous comments are reviewed before appearing.