I need some help converting a line, polyline or arc to a schematic line.
I think I need to use "Schematic.CreateFromGeCurve(curve3d)" but I cant seem to figure out how to get the curve3d of lines, polylines or arcs to pass to it.
Any help is appreciated.
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Thanks Gile,
I did see that but when I pass in an "Arc" "GetGeCurve" returns "Autodesk.AutoCAD.Geometry.CircularArc3d" and not a Curve3d.
Here's some of my code, passing in an "Arc"....
Dim db As Database = HostApplicationServices.WorkingDatabase
Using trans As Transaction = db.TransactionManager.StartTransaction()
Dim a As Arc = TryCast(trans.GetObject(objID, OpenMode.ForRead), Arc)
Dim cur As Curve3d = a.GetGeCurve
SLine = Autodesk.Aec.Building.DatabaseServices.Schematic.CreateFromGeCurve(cur)
' I assume that I will have to appendentity and addnewlycreateddbobject here ?
trans.Commit()
End Using
When I "Quickwatch" cur its says it is a "CircularArc3d" which has the start and end points of the "Curve3d" but I don't see how to get the "Curve3d" itself.
Hi,
You should learn about inheritance feature in .NET.
The Curve3d class is the abstract base class for all Curve3d types. So, a CircularArc3d instance is a type of Curve3d, which is a type of Entity3d ; as an Arc instance is a type of Curve which is a type of Entity which is a type of DBObject. In other words, The CircularArc3d type inherits from the Curve3d type.
Geometric objects as those which inherit from Entit3d are not database resident objects. Entity objects ( as all objects derived from DBObject) ar database resident and have to be explicitly added to the Database using AppendEntity() and AddNewlyCreatedObject() methods.
So I have read about inheritance and I believe I understand the "parent", "child" structure.
I am still unable to cast a "circularArc3d" up to a "Curve3d".
I have tried "CType" and "Directcast", for example, "Directcast(cur, Curve3d).CircularArc3d" where cur = a CircularArc3d object.
This returns the error 'CircularArc3d' is not a member of 'Curve3d'.
So I'm still stuck on how to "upcast" a child object to a parent object.
The CreateFromGeCurve() method requires an object of type Curve3d as argument. That means you can pass any object which type inhérits from Curve3d (as CircularArc3d, CompositeCurve3d, and so on) without having to upcast it.
If you really need to upcast your CircularArc3d (cur), simply do:
Dim curve3d As Curve3d = DirectCast(cur, Curve3d)
thank you for your time and patience but i'm still getting an error.
my code..
Dim db As Database = HostApplicationServices.WorkingDatabase Dim SLine As Autodesk.Aec.Building.DatabaseServices.Schematic = New Autodesk.Aec.Building.DatabaseServices.Schematic Using trans As Transaction = db.TransactionManager.StartTransaction() Dim a As Arc = TryCast(trans.GetObject(objID, OpenMode.ForRead), Arc) Dim cur As CircularArc3d = a.GetGeCurve SLine = Autodesk.Aec.Building.DatabaseServices.Schematic.CreateFromGeCurve(cur) ' ERRORS HERE Dim bt As BlockTable = DirectCast(trans.GetObject(mDb.BlockTableId, OpenMode.ForWrite, False), BlockTable) Dim btr As BlockTableRecord = DirectCast(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite, False), BlockTableRecord) btr.AppendEntity(SLine) trans.AddNewlyCreatedDBObject(SLine, True) trans.Commit() End Using
It's erroring on the CreateFromGeCurve line with a 'System.InvalidCastException' error.
Unable to cast object of type 'Autodesk.AutoCAD.DatabaseServices.Arc' to type 'Autodesk.Aec.Building.DatabaseServices.Schematic'.
Which would make sense except that cur, that I'm passing into CreateFromGeCurve, when inspected says its a Autodesk.AutoCAD.Geometry.CircularArc3d.
What am I doing wrong?
The error you get is not related to the CreateFromGeCurve() method which does return an Autodesk.AutoCAD.DatabaseServices.Arc while the argument is a CircularArc3d.
The error you get is about casting an Autodesk.AutoCAD.DatabaseServices.Arc into an Autodesk.Aec.Building.DatabaseServices.Schematic.
Sorry but I cannot help you further, I do not know the specific APIs of Architecture and MEP verticals.
Your entity types are not the same.
Autodesk.AutoCAD.DatabaseServices.Arc is not the same as
Autodesk.AutoCAD.Geometry.CircularArc3d
I have no experience with Aec either - just guessing.
@fieldguy we know Arc and CircularArc3d are different types.
The Autodesk.Aec.Building.DatabaseServices.Schematic type inherits from Autodesk.AutoCAD.DatabaseServices.Curve so it can call the Curve.CreateFromGeCurve() static method. This method requires as argument an object of type (i.e., derived from) Autodesk.AutoCAD.Geometry.Curve3d and returns the corresponding Autodesk.AutoCAD.DatabaseServices.Curve object (if possible).
The issue here is calling this method on the Autodesk.Aec.Building.DatabaseServices.Schematic type when passing it a CircularArc3d.
I cannot say if this is due to the argument type (i.e., it should work with a LineSegment3d but not with a CircularArc3d) or if this is due to the CreateFromCurve() method which does not work on the Autodesk.Aec.Building.DatabaseServices.Schematic type.
Thanks for trying.
I removed the accepted solution in hopes that someone from the Autodesk ADN might see this and provide an answer.
OK,
I made a try referencing AEC libraries.
You cannot use the CreateFromGeCurve() with a CircularArc3d object to create a Schematic instance because, in this case, this method returns an Arc object.
You have to use the Schematic.AddBaseCurve3d() instance method.
Working C# example
using (var tr = db.TransactionManager.StartTransaction()) { var arc = (Arc)tr.GetObject(objId, OpenMode.ForRead); var btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); var schem = new Schematic(); schem.AddBaseCurve3d(arc.GetGeCurve(), arc.Normal); btr.AppendEntity(schem); tr.AddNewlyCreatedDBObject(schem, true); tr.Commit(); }
VB conversion (not tested)
Using tr As Transaction = db.TransactionManager.StartTransaction() Dim arc As Arc = DirectCast(tr.GetObject(objId, OpenMode.ForRead), Arc) Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTablerecord) Dim schem As Schematic = new Schematic() schem.AddBaseCurve3d(arc.GetGeCurve(), arc.Normal) btr.AppendEntity(schem) tr.AddNewlyCreatedDBObject(schem, true) tr.Commit() End Using
Yes, that works!
At least for Arcs and Lines.
Substituting the following and passing in a "Polyline"...
Dim polyline As Polyline = DirectCast(tr.GetObject(objID, OpenMode.ForRead), Polyline) schem.AddBaseCurve3d(polyline.GetGeCurve(), polyline.Normal) btr.AppendEntity(schem) tr.AddNewlyCreatedDBObject(schem, True)
And I get a "eInvalidInput" error on the AddBaseCurve3d line.
polyline.GetGeCurve returns a value of "Autodesk.AutoCAD.Geometry.CompositeCurve3d" which inherits from "Curve3d" the same as a "Line", which works, is.
So now can you tell what's special about a "Polyline"?
Thanks.
One more time I do not use AEC APIs, so i do not really know.
I suppose the AddBaseCurve3d() only accepts 'simple' Curve3d objects (as LineSegment3d and CircularArc3d) but do not accept 'complex' Curve3d objects (as CompositeCurve3d)
You should try to add all the Curve3d objects componing the CompositeCurve3d one by one, something like this:
foreach (Curve3d curve in polyline.GetGeCurve().GetCurves()) { schem.AddBaseCurve3d(curve, polyline.Normal) }
Hi,
what are the current issues? as mentioned by @_gile, Curve.GetGecurve() method is the method to convert the database objects to geometry objects
Gile was able to get "Arcs" and "Lines" to convert to "Schematiclines".
My current issue is that "Polylines" do not work using the same method of conversion.
For example, the following works for a "Line"
Dim schem As Schematic = New Schematic()
Dim line As Line = DirectCast(tr.GetObject(objID, OpenMode.ForRead), Line)
schem.AddBaseCurve3d(line.GetGeCurve(), line.Normal)
But, the following does NOT work for a "Polyline"
Dim schem As Schematic = New Schematic()
Dim Pline As Polyline = DirectCast(tr.GetObject(objID, OpenMode.ForRead), Polyline )
schem.AddBaseCurve3d(Pline .GetGeCurve(), line.Normal) '<-- returns 'eInvalidInput' error
schem.AddBaseCurve3d(Pline .GetGeCurve(), line.Normal) '<-- returns 'eInvalidInput' error
What is the value of line.Normal?
Oops, editing error on my part.
That should have been polyline.normal
Dim polyline As Polyline = DirectCast(tr.GetObject(objID, OpenMode.ForRead), Polyline)
schem.AddBaseCurve3d(polyline.GetGeCurve(), polyline.Normal)
The code still errors.
polyline.Normal value = {(0,0,1)} Type = Autodesk.AutoCAD.Geometry.Vector3d
polyline.GetGeCurve() value = {Autodesk.AutoCAD.Geometry.CompositeCurve3d} Type= Autodesk.AutoCAD.Geometry.Curve3d
Image of actual error attached
As I said upper (message 15 of 20), the AddBaseCurve3d() do not accept a CompositeCurve3d object as argument, but we know it accepts the LineSegment3d and CircularArc3d objects. So you can get these objects from the polyline and pass them one by one.
Curiously I could not get it work using the CompositeCurve3d.GetCurves() method but it seems to work while collecting the Curve3d objects directy from the polyline.
using (var tr = db.TransactionManager.StartTransaction()) { var btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); var pline = (Polyline)tr.GetObject(objId, OpenMode.ForRead); var normal = pline.Normal; var curves = new List<Curve3d>(); for (int i = 0; i < pline.NumberOfVertices - 1; i++) { if (pline.GetBulgeAt(i) == 0.0) curves.Add(pline.GetLineSegmentAt(i)); else curves.Add(pline.GetArcSegmentAt(i)); } var schem = new Schematic(); foreach (var curve in curves) { schem.AddBaseCurve3d(curve, normal); } btr.AppendEntity(schem); tr.AddNewlyCreatedDBObject(schem, true); tr.Commit(); }
Can't find what you're looking for? Ask the community or share your knowledge.