I really wish AddFreeSCS can handle 0 spiral length. Alas it can't.
Because AddFreeSCS with 0 spiral length at both ends, is just AddFreeCurve. And things are easy if it's 0 spiral length at both ends. I can just check whether this is the condition and switch to using AddFreeCurve.
But what if it's only 0 spiral length at one end? How can I handle this case properly? I can't get the API to work , any ideas?
Here's how to reproduce it. Open the attached drawing in Civil 3D, and then run the following code:
public static Point3d ToPoint3d(this Point2d pt)
{
return new Point3d(pt.X, pt.Y, 0);
}
private static void Transact(Action<Transaction> action)
{
var doc = Application.DocumentManager.MdiActiveDocument;
using var tr = doc.TransactionManager.StartTransaction();
action(tr);
tr.Commit();
}
public static T SingleEntity<T>(this IEnumerable<ObjectId> objectIds,
Transaction ts, OpenMode openMode)
where T : DBObject
{
var allEntities = new List<T>();
foreach (ObjectId objectId in objectIds)
{
var theObj = ts.GetObject<T>(objectId, openMode);
if (theObj != null)
allEntities.Add(theObj);
}
if (allEntities.Count != 1)
throw new ArgumentException();
return allEntities.Single();
}
public static T SingleEntity<T>(this ObjectIdCollection objectIds,
Transaction ts, OpenMode openMode = OpenMode.ForRead)
where T : DBObject
{
return SingleEntity<T>(objectIds.Cast<ObjectId>(), ts, openMode);
}
public static T GetObject<T>(this Transaction ts, ObjectId objectId, OpenMode openMode = OpenMode.ForRead)
where T:DBObject
{
return ts.GetObject(objectId, openMode) as T;
}
[CommandMethod(nameof(WriteAlignment1))]
public void WriteAlignment1()
{
Transact(tr =>
{
var singleAlignment = ActiveCivil3DDocument.GetAlignmentIds()
.SingleEntity<Alignment>(tr);
var allLines = singleAlignment.Entities.OfType<AlignmentLine>().ToList();
var firstLine = allLines[0];
Debug.Assert(firstLine.EntityType == AlignmentEntityType.Line);
var firstPoint = firstLine.StartPoint;
var secondPoint = firstLine.EndPoint;
var spiralIn = (AlignmentSpiral)singleAlignment.Entities[1];
Debug.Assert(spiralIn.EntityType == AlignmentEntityType.Spiral);
var curve = (AlignmentArc)singleAlignment.Entities[2];
var spiralOut = (AlignmentSpiral)singleAlignment.Entities[3];
var secondLine = allLines[1];
Debug.Assert(secondLine.EntityType == AlignmentEntityType.Line);
var firstLabelSetStyles = ActiveCivil3DDocument.Styles.LabelSetStyles.AlignmentLabelSetStyles[0];
var copyAlignmentId = Alignment.Create(ActiveCivil3DDocument, "copycat", ObjectId.Null,
singleAlignment.LayerId, singleAlignment.StyleId, firstLabelSetStyles
, AlignmentType.Centerline);
ActiveCivil3DDocument.GetAlignmentIds().Add(copyAlignmentId);
var copyAlignment = tr.GetObject<Alignment>(copyAlignmentId);
var copycatLine1 = copyAlignment.Entities.AddFixedLine(firstPoint.ToPoint3d(),
secondPoint.ToPoint3d());
Debug.Assert(copycatLine1.StartPoint == firstPoint);
Debug.Assert(copycatLine1.EndPoint == secondPoint);
var copycatLine2 = copyAlignment.Entities.AddFixedLine
(secondLine.StartPoint.ToPoint3d(), secondLine.EndPoint.ToPoint3d());
var spiralInCopy = copyAlignment.Entities.AddFloatSpiral(copycatLine1.EntityId,
curve.Radius, spiralIn.Length, true, SpiralType.Clothoid);
var spiralOutCopy = copyAlignment.Entities.AddFloatSpiral(curve.Radius, spiralOut.Length,
copycatLine2.EntityId, false, SpiralType.Clothoid);
var curveCopy = copyAlignment.Entities.AddFreeCurve(spiralInCopy.EntityId, spiralOutCopy.EntityId,
curve.Radius, CurveParamType.Radius, false, CurveType.Compound); //crash here
//the below works
//var copycatSCS = copyAlignment.Entities.AddFreeSCS(copycatLine1.EntityId, copycatLine2.EntityId,
// spiralIn.Length, spiralOut.Length, SpiralParamType.Length,
// curve.Radius, false, SpiralType.Clothoid); //the angle is the angle of the arc
});
}
If it really works, then an incomplete alignment mimicking the original alignment will be created, with a few curves and lines at the front exactly the same.
But in my code above, it crashes at AddFreeCurve due to Invalid Argument or something.
Check out this thread.
How To Set the Length property of AlignmentSubEntitySpiral to 0 - Autodesk Community
I'm not entirely clear on that thread, how your code is supposed to help in setting the Spiral length=0. All I see is that you are transforming an AlignmentSCS to Spiral, Curve and Spiral; 3 AlignmentCurves.
Can you be more explicit about it?
The thing is that, I need it to be AlignmentSCS because I would need to use the AddAutoWidenings method, which explicitly expect AlignmentSubEntityArc, so AlignmentArc simply won't do at all.
Can't find what you're looking for? Ask the community or share your knowledge.