Author Topic: Create 3D solid by extruding a polyline  (Read 2957 times)

0 Members and 1 Guest are viewing this topic.

Offline fixo

  • Full Member
  • ***
  • Posts: 135
  • Karma: +4/-0
  • Gender: Male
    • prefered language: C
    • Prog expertise: Good
    • View Profile
Create 3D solid by extruding a polyline
« on: August 08, 2012, 09:52:08 PM »
     
Code: [Select]
     // based on C++ code by Virupaksha Aithal from this page:
      //http://adndevblog.typepad.com/autocad/2012/08/create-3d-solid-by-extruding-a-polyline.html
       [CommandMethod("extt")]
        public void CreateExtrude()
        {
            Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("delobj", 1);

            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Database db = doc.Database;

            Editor ed = doc.Editor;

            PromptSelectionOptions pso = new PromptSelectionOptions();

            pso.SingleOnly = true;

            pso.SinglePickInSpace = true;

            pso.MessageForAdding = "\nPlease select a polyline: ";

            pso.MessageForRemoval = "Failed to select a polyline";

            pso.PrepareOptionalDetails = true;

            SelectionFilter filter =
                new SelectionFilter(
                new TypedValue[] { new TypedValue(0, "lwpolyline"),new TypedValue(70, 1) });

            //select the polyline
            PromptSelectionResult sres = ed.GetSelection(pso,filter);

            if (sres.Status != PromptStatus.OK) return;

            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                //get the boundary curves of the polyline

                ObjectId idPoly = sres.Value[0].ObjectId;

                Entity pEntity = tr.GetObject(idPoly, OpenMode.ForRead) as Entity;

                Polyline pPoly = pEntity as Polyline; ;

                if (pPoly == null) return;

                DBObjectCollection lines = new DBObjectCollection();

                pPoly.Explode(lines);

                // Create a region from the set of lines.

                DBObjectCollection regions = new DBObjectCollection();

                regions = Region.CreateFromCurves(lines);

                if (regions.Count == 0)
                {
                    ed.WriteMessage("\nFailed to create region\n");
                    return;
                }

                Region pRegion = (Region)regions[0];

                // Extrude the region to create a solid.

                Solid3d pSolid = new Solid3d();

                pSolid.RecordHistory = true;

                pSolid.Extrude(pRegion, 10.0, 0.0);
           
                ObjectId savedExtrusionId = ObjectId.Null;

                ObjectId modelId;

                modelId = SymbolUtilityServices.GetBlockModelSpaceId(db);

                BlockTableRecord btr = tr.GetObject(modelId, OpenMode.ForWrite) as BlockTableRecord;

                savedExtrusionId = btr.AppendEntity(pSolid);

                tr.AddNewlyCreatedDBObject(pSolid,true);
         
                if (!pPoly.IsWriteEnabled) pPoly.UpgradeOpen();

                pPoly.Erase();
           
                tr.Commit();
            }

        }

~'J'~

Offline (gile)

  • C#
  • *
  • Posts: 87
  • Karma: +8/-0
  • Gender: Male
    • prefered language: F
    • Prog expertise: Good
    • View Profile
Re: Create 3D solid by extruding a polyline
« Reply #1 on: August 09, 2012, 06:42:16 AM »
Hi Oleg,

In my opnion, there's no need to explode the polyline, it can be passed as is to the Region.CreateFromCurves() method.

Anyway, you may explicitely dispose the DBObjectCollections (lines and regions) in case ther're some objects left for which no managed wrapper have been created.
You must explicitely dispose each region used to create a solid as a managed wrapped is creadted and is not added to the Database (the same for the curves used to create the region as you explode the polyline).

The following code is extract from a topic at TheSwamp about "To dispose or not To Dispose" (reply #82).
It's quite closed to yours and try to cover most of the 'disposing or not' issues.

C#
Code: [Select]
        public void ExtrudePline()
        {
            // Never dispose Document nor Document.Editor
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            // Never dispose Database when the drawing is opened in the Editor
            // On the other hand, always dispose Database created with the constructor, i.e. new Database()
            Database db = doc.Database;

            // Always dispose DocumentLock
            using (doc.LockDocument())
            // Always dispose Transaction
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // No need to dispose a DBObject opened from a transaction
                BlockTableRecord currentSpace =
                    (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);

                // Always dispose a new DBObject which may not be added to the database
                using (Polyline pline = new Polyline())
                {
                    pline.AddVertexAt(0, Point2d.Origin, 0.0, 0.0, 0.0);
                    pline.AddVertexAt(1, new Point2d(10.0, 0.0), 0.0, 0.0, 0.0);
                    pline.AddVertexAt(2, new Point2d(10.0, 10.0), 1.0, 0.0, 0.0);
                    pline.AddVertexAt(3, new Point2d(0.0, 10.0), 0.0, 0.0, 0.0);
                    pline.Closed = true;

                    // Dispose DBObjectCollection in case there're some objects left
                    // for which no managed wrapper have been created
                    using (DBObjectCollection plineCollection = new DBObjectCollection())
                    {
                        plineCollection.Add(pline);

                        // Dispose DBObjectCollection in case there're some objects left
                        // for which no managed wrapper have been created
                        using (DBObjectCollection regionCollection =
                            Region.CreateFromCurves(plineCollection))
                        {
                            // Always dispose an object contained in a DBObjectCollection
                            // for which a managed wrapper is created and isn't added to the database
                            using (Region region = (Region)regionCollection[0])
                            {
                                // Use Dispose to insure the new DBObject will be disposed
                                // if an exception occurs before it is added to the Database
                                using (Solid3d solid = new Solid3d())
                                {
                                    solid.Extrude(region, 30.0, 0.0);
                                    currentSpace.AppendEntity(solid);
                                    tr.AddNewlyCreatedDBObject(solid, true);
                                }
                            }
                        }
                    }
                    if ((short)Application.GetSystemVariable("DELOBJ") == 0)
                    {
                        currentSpace.AppendEntity(pline);
                        tr.AddNewlyCreatedDBObject(pline, true);
                    }
                }
                tr.Commit();
            }
        }

F#
Code: [Select]
let ExtrudePline() =
    // Never dispose Document nor Document.Editor
    let doc = AcAp.DocumentManager.MdiActiveDocument
    let ed = doc.Editor

    // Never dispose Database when the drawing is opened in the Editor
    // On the other hand, always dispose Database created with the constructor (i.e. new Database())
    let db = doc.Database
   
    // Always dispose DocumentLock
    use docLock = doc.LockDocument()

    // Always dispose Transaction
    use tr = db.TransactionManager.StartTransaction()

    // No need to dispose a DBObject opened from a transaction
    let currentSpace = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) :?> BlockTableRecord

    // Always dispose a new DBObject which may not be added to the database
    use pline = new Polyline()
    pline.AddVertexAt(0, Point2d.Origin, 0.0, 0.0, 0.0)
    pline.AddVertexAt(1, new Point2d(10.0, 0.0), 0.0, 0.0, 0.0)
    pline.AddVertexAt(2, new Point2d(10.0, 10.0), 1.0, 0.0, 0.0)
    pline.AddVertexAt(3, new Point2d(0.0, 10.0), 0.0, 0.0, 0.0)
    pline.Closed <- true;
   
    // Dispose DBObjectCollection in case there're some objects left
    // for which no managed wrapper have been created
    use plineCollection = new DBObjectCollection()
    plineCollection.Add(pline) |> ignore

    // Dispose DBObjectCollection in case there're some objects left
    // for which no managed wrapper have been created
    use regionCollection = Region.CreateFromCurves(plineCollection)

    // Always dispose an object contained in a DBObjectCollection
    // for which a managed wrapper is created and isn't added to the database
    use region = regionCollection.[0] :?> Region

    // Use Dispose to insure the new DBObject will be disposed
    // if an exception occurs before it is added to the Database
    use solid = new Solid3d()
    solid.Extrude(region, 30.0, 0.0)
    currentSpace.AppendEntity(solid) |> ignore
    tr.AddNewlyCreatedDBObject(solid, true)

    if Application.GetSystemVariable("DELOBJ") |> unbox  = 0s then
        currentSpace.AppendEntity(pline) |> ignore
        tr.AddNewlyCreatedDBObject(pline, true)
    tr.Commit()

VB
Code: [Select]
        Public Sub ExtrudePline()
            ' Never dispose Document nor Document.Editor
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor

            ' Never dispose Database when the drawing is opened in the Editor
            ' On the other hand, always dispose Database created with the constructor (i.e. New Database())
            Dim db As Database = doc.Database

            ' Always dispose DocumentLock
            Using doc.LockDocument()

                ' Always dispose Transaction
                Using tr As Transaction = db.TransactionManager.StartTransaction()

                    ' No need to dispose a DBObject opened from a transaction
                    Dim currentSpace As BlockTableRecord = _
                        DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

                    ' Always dispose a new DBObject which may not be added to the database
                    Using pline As New Polyline()
                        pline.AddVertexAt(0, Point2d.Origin, 0.0, 0.0, 0.0)
                        pline.AddVertexAt(1, New Point2d(10.0, 0.0), 0.0, 0.0, 0.0)
                        pline.AddVertexAt(2, New Point2d(10.0, 10.0), 1.0, 0.0, 0.0)
                        pline.AddVertexAt(3, New Point2d(0.0, 10.0), 0.0, 0.0, 0.0)
                        pline.Closed = True

                        ' Dispose DBObjectCollection in case there're some objects left
                        ' for which no managed wrapper have been created
                        Using plineCollection As New DBObjectCollection()
                            plineCollection.Add(pline)

                            ' Dispose DBObjectCollection in case there're some objects left
                            ' for which no managed wrapper have been created
                            Using regionCollection As DBObjectCollection = _
                                Region.CreateFromCurves(plineCollection)

                                ' Always dispose an object contained in a DBObjectCollection
                                ' for which a managed wrapper is created and isn't added to the database
                                Using region As Region = DirectCast(regionCollection(0), Region)

                                    ' Use Dispose to insure the new DBObject will be disposed
                                    ' if an exception occurs before it is added to the Database
                                    Using solid As New Solid3d()
                                        solid.Extrude(region, 30.0, 0.0)
                                        currentSpace.AppendEntity(solid)
                                        tr.AddNewlyCreatedDBObject(solid, True)
                                    End Using
                                End Using
                            End Using
                        End Using
                        If CShort(Application.GetSystemVariable("DELOBJ")) = 0 Then
                            currentSpace.AppendEntity(pline)
                            tr.AddNewlyCreatedDBObject(pline, True)
                        End If
                    End Using
                    tr.Commit()
                End Using
            End Using
        End Sub
« Last Edit: August 12, 2012, 03:06:37 PM by (gile) »