Dear Swamp users,
I'm facing issues while creating a hatch that properly aligns with a polyline3d. Currently, the function loops through all the objects in the ModelSpace and checks if the object is a 3D polyline with a layer that starts with "FACET_". If the object meets this condition, the function retrieves the UCS (User Coordinate System) by the layer name and sets it as the active viewport's UCS. The function then creates a temporary copy of the 3D polyline and transforms it by the current user coordinate system. Next, a new hatch object is created and added to the block table record. The properties of the hatch object are set, including pattern, angle, and scale, and the normal and elevation of the hatch are set based on the current user coordinate system.
However, I suspect that the elevation/normal of the hatch is set at some basepoint that is not a property I can access. Currently, I'm offsetting the elevation by the difference between the first vertex of the polyline and the origin of the UCS, hoping that this is where the elevation of the hatch is being set. This doesn't seem to be the case (though it is closer than without the offset so right direction). If I can get the Point2d or Point3d of the hatch, I can create an offset from the origin to adjust for this, but I'm unsure how to obtain it. I might also be overcomplicating things, and any assistance would be appreciated.
***Outerloops is currently being set to null until I can get the base case setup*** can ignore that bit.
Command Entry Point:
[CommandMethod("CreateHatches")]
public void CreateHatches()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
string hatchPattern = "ANSI31";
double angle = 45;
double scale = 192.0;
foreach (ObjectId objectId in btr)
{
Entity entity = tr.GetObject(objectId, OpenMode.ForRead) as Entity;
if (entity != null && entity is Polyline3d polyline3d && entity.Layer.StartsWith("FACET_"))
{
ViewportTableRecord acVportTblRec;
acVportTblRec = tr.GetObject(doc.Editor.ActiveViewportId, OpenMode.ForWrite) as ViewportTableRecord;
UcsTableRecord ucsRecord = Utilities.GetUCSByName(entity.Layer);
var wcsOrgin = Point3d.Origin;
var wcsX = Vector3d.XAxis;
var wcsY = Vector3d.YAxis;
var wcsZ = Vector3d.ZAxis;
/* var ucsOrgin = ucsRecord.Origin;
var ucsX = ucsRecord.XAxis;
var ucsY = ucsRecord.YAxis;
var ucsZ = ucsRecord.XAxis.CrossProduct(ucsRecord.YAxis);*/
ed.WriteMessage("The current UCS is" + ed.CurrentUserCoordinateSystem);
acVportTblRec.SetUcs(ucsRecord.ObjectId);
doc.Editor.UpdateTiledViewportsFromDatabase();
ed.WriteMessage("The current UCS is" + ed.CurrentUserCoordinateSystem);
Utilities.CreateHatch(polyline3d, hatchPattern, angle, scale, null);
}
}
tr.Commit();
}
}
public void CreateHatch(Polyline3d outerLoop, String hatchName, Double angle, Double scale, List<Polyline3d> holePolylines = null)
{
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
Editor ed = acDoc.Editor;
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
var vertices = outerLoop.Cast<ObjectId>()
.Select(id => (PolylineVertex3d)id.GetObject(OpenMode.ForRead))
.Select(vertex => vertex.Position)
.ToList();
var offset = vertices[0].Z;
ViewportTableRecord acVportTblRec;
acVportTblRec = acTrans.GetObject(acDoc.Editor.ActiveViewportId, OpenMode.ForWrite) as ViewportTableRecord;
UcsTableRecord ucsRecord = Utilities.GetUCSByName(outerLoop.Layer);
BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
var newMatrix = Matrix3d.AlignCoordinateSystem(acVportTblRec.Ucs.Origin,
acVportTblRec.Ucs.Xaxis,
acVportTblRec.Ucs.Yaxis,
acVportTblRec.Ucs.Zaxis,
Point3d.Origin,
Vector3d.XAxis,
Vector3d.YAxis,
Vector3d.ZAxis);
// Create a temporary copy of the 3D polyline and transform it by the current user coordinate system
Polyline3d outerLoopTemp = (Polyline3d)outerLoop.Clone();
outerLoopTemp.TransformBy(newMatrix);
acBlkTblRec.AppendEntity(outerLoopTemp);
acTrans.AddNewlyCreatedDBObject(outerLoopTemp, true);
// Adds the outerLoopTemp ObjectId to an object id array
ObjectIdCollection acObjIdColl = new ObjectIdCollection();
acObjIdColl.Add(outerLoopTemp.ObjectId);
// Create the hatch object and append it to the block table record
Hatch acHatch = new Hatch();
acBlkTblRec.AppendEntity(acHatch);
acTrans.AddNewlyCreatedDBObject(acHatch, true);
// Set the properties of the hatch object
acHatch.SetDatabaseDefaults();
acHatch.SetHatchPattern(HatchPatternType.PreDefined, hatchName);
acHatch.PatternScale = scale;
acHatch.PatternAngle = angle;
acHatch.AppendLoop(HatchLoopTypes.Outermost, acObjIdColl);
acHatch.Associative = true;
// Get the normal vector and elevation of the UCS
Vector3d normal = ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis;
ed.WriteMessage("The normal extracted is" + normal);
double elevation = ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Origin.Z;
ed.WriteMessage("The elevation extracted is" + elevation);
// Set the normal and elevation of the hatch
acHatch.Normal = normal;
acHatch.Elevation = elevation + (elevation - offset);
acHatch.EvaluateHatch(true);
outerLoopTemp.Layer = acHatch.Layer;
// Handle holePolylines as inner loops
if (holePolylines != null)
{
foreach (Polyline3d holePolyline in holePolylines)
{
// Create a temporary copy of the holePolyline and transform it by the current user coordinate system
Polyline3d holePolylineTemp = (Polyline3d)holePolyline.Clone();
holePolylineTemp.TransformBy(acDoc.Editor.CurrentUserCoordinateSystem);
acBlkTblRec.AppendEntity(holePolylineTemp);
acTrans.AddNewlyCreatedDBObject(holePolylineTemp, true);
// Adds the holePolylineTemp ObjectId to an object id array
ObjectIdCollection holeObjIdColl = new ObjectIdCollection();
holeObjIdColl.Add(holePolylineTemp.ObjectId);
// Append hole polyline as inner loop
acHatch.AppendLoop(HatchLoopTypes.Default, holeObjIdColl);
}
}
outerLoopTemp.TransformBy(acDoc.Editor.CurrentUserCoordinateSystem);
acHatch.EvaluateHatch(true);
// Remove temporary polylines
// outerLoopTemp.Erase();
// Save the new object to the database
acTrans.Commit();
}
}