.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Convert Line, polyline or Arc to Schematicline

20 REPLIES 20
SOLVED
Reply
Message 1 of 21
jshimkus
3702 Views, 20 Replies

Convert Line, polyline or Arc to Schematicline

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.

 

20 REPLIES 20
Message 2 of 21
_gile
in reply to: jshimkus

Hi,

 

Have a look at the Curve.GetGecurve() method.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 21
jshimkus
in reply to: _gile

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.

Message 4 of 21
_gile
in reply to: jshimkus

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.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 21
jshimkus
in reply to: _gile

Thanks for pointing me in the right direction.

Message 6 of 21
jshimkus
in reply to: _gile

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.

Message 7 of 21
_gile
in reply to: jshimkus

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)



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 8 of 21
jshimkus
in reply to: _gile

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?

Message 9 of 21
_gile
in reply to: jshimkus

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.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 10 of 21
fieldguy
in reply to: jshimkus

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.  

 

Message 11 of 21
_gile
in reply to: fieldguy

@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.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 12 of 21
jshimkus
in reply to: _gile

Thanks for trying.

I removed the accepted solution in hopes that someone from the Autodesk ADN might see this and provide an answer.

Message 13 of 21
_gile
in reply to: jshimkus

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


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 14 of 21
jshimkus
in reply to: _gile

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.

Message 15 of 21
_gile
in reply to: jshimkus

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)
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 16 of 21

Hi,

 

what are the current issues? as mentioned by @_gile,  Curve.GetGecurve() method is the method to convert the database objects to geometry objects 



Virupaksha Aithal KM
Developer Technical Services
Autodesk Developer Network

Message 17 of 21

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

Message 18 of 21
fieldguy
in reply to: jshimkus

schem.AddBaseCurve3d(Pline .GetGeCurve(), line.Normal)  '<-- returns 'eInvalidInput' error

 

What is the value of line.Normal?

Message 19 of 21
jshimkus
in reply to: fieldguy

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

2018-08-10_12h26_34.png

Message 20 of 21
_gile
in reply to: jshimkus

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();
            }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Forma Design Contest


Autodesk Design & Make Report