problems with creating a helix using c#.net

problems with creating a helix using c#.net

jz5902
Explorer Explorer
1,471 Views
2 Replies
Message 1 of 3

problems with creating a helix using c#.net

jz5902
Explorer
Explorer

I'm attempting to create a helix programmatically, but it doesn't work.  Half the time it crashes autocad, and half the time it draws a helix that doesn't follow the parameters I set.  Can someone tell me what I'm doing wrong?  Here is the code:

 

public static ObjectId DrawHelix(Transaction transaction, Point3d startPoint, Vector3d axis, double radius, double height, double numberOfTurns, bool isLeft)

{
  try
  {
  // Open the Block table for read
  using (BlockTable _blockTable = transaction.GetObject(Utils.ActiveDatabase.BlockTableId, OpenMode.ForRead) as BlockTable)
  {
    // Open the Block table record Model space for write
    using (BlockTableRecord _blockTableRecord = transaction.GetObject(_blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord)
    {
       using (Helix _helix = new Helix())
       {
          _helix.BaseRadius = radius;
          _helix.TopRadius = radius;
          _helix.StartPoint = startPoint;
          //_helix.EndPoint = endPoint; not implemented exception?
          _helix.Height = height;
          _helix.Turns = numberOfTurns;
          _helix.Twist = isLeft;
          //_helix.AxisVector = axis;

         _blockTableRecord.AppendEntity(_helix);
         transaction.AddNewlyCreatedDBObject(_helix, true);

         return _helix.Id;
       }
    }
  }
}
catch
{
throw new System.Exception();
}
}

 

 

Specific questions:

1) Do I have to set the properties of the helix in a particular order?

2) Does the StartPoint property actually control the start of the helix?  On the occasions when this function works, the resulting helix is never drawn anywhere near the given start point.

3) Autocad's HELIX command asks the user to select a center point, but the Helix class doesn't have a CenterPoint property.  Is there a way to set the center point programmatically?

4) What is the AxisVector supposed to control?  I commented it out because it never seemed to affect anything.

5) If I later want to sweep a rectangle along the helix object, can I use the helix directly, or do I need to cast it to another type?

0 Likes
Accepted solutions (1)
1,472 Views
2 Replies
Replies (2)
Message 2 of 3

arcticad
Advisor
Advisor
Accepted solution

This will create a Helix, Polyline and then sweep the Polyline with the Helix

 

the Polylines is converted to an Entity and the helix to a Curve.

 

I didn't change the AxisVector, it seems to work fine without it being changed. 

 

using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Geometry;

namespace CreateHelix
{
    public class clsCreateHelix
    {
        [CommandMethod("MHelix", CommandFlags.Session)]
        public void CreateHelix()
        {
            Database acCurDb = Application.DocumentManager.MdiActiveDocument.Database;
            Document doc = Application.DocumentManager.MdiActiveDocument;

            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                using (DocumentLock DocLock = doc.LockDocument())
                {
                    using (BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable)
                    {
                        using (BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord)
                        {
                            // Create Helix
                            Helix acHelix = getHelix(270, true, 100, new Point3d(0, 0, 0), 10);
                            acBlkTblRec.AppendEntity((Entity)acHelix);
                            acTrans.AddNewlyCreatedDBObject(acHelix, true);

                            // Create Polyline for Sweep
                            Polyline acPolyline = getPolylineForSweep();
                            acBlkTblRec.AppendEntity((Entity)acPolyline);
                            acTrans.AddNewlyCreatedDBObject(acPolyline, true);
                        
                            // Sweep Polyline along helix. 
                            Solid3d acSolid = SweepAlongPath(acPolyline, acHelix);

                            if (acSolid != null)
                            {
                                acBlkTblRec.AppendEntity((Entity)acSolid);
                                acTrans.AddNewlyCreatedDBObject(acSolid, true);
                            }
                        }
                    }
                }
                acTrans.Commit();
            }
        }

        private double getTurnAngle(double dblDegrees)
        {
            return (((dblDegrees * 100) / 360) * .01);
        }

        internal Helix getHelix(double dblTurnAngle, bool CW, double dblRadius, Point3d pt3Origin, double dblHeight)
        {
            double dblDegree = getTurnAngle(dblTurnAngle);
            Helix acHelix = new Helix();
            acHelix.SetDatabaseDefaults();
            acHelix.Constrain = ConstrainType.Height;
            acHelix.StartPoint = pt3Origin;
            acHelix.BaseRadius = dblRadius;
            acHelix.TopRadius = dblRadius;
            acHelix.Height = dblHeight;
            acHelix.TurnHeight = (1 / dblDegree);
            acHelix.Turns = dblDegree;
            acHelix.Twist = !CW;
            acHelix.CreateHelix();
            return acHelix;
        }

        internal Polyline getPolylineForSweep()
        {
            Polyline pline = new Polyline();
            pline.SetDatabaseDefaults();
            // Polyline must not intersect itself
            pline.AddVertexAt(0, new Point2d(-10, 0.0), 0.0, 0.0, 0.0);
            pline.AddVertexAt(1, new Point2d(10, 0.0), 0.0, 0.0, 0.0);
            pline.AddVertexAt(2, new Point2d(10, 10), 0.0, 0.0, 0.0);
            pline.AddVertexAt(3, new Point2d(-10, 10), 0.0, 0.0, 0.0);
            pline.Closed = true;

            return pline;
        }


        internal Solid3d SweepAlongPath(Polyline acPolyline, Helix acHelix)
        {
            Solid3d rtnValue = new Solid3d();

            try
            {
                // Convert Entity's to appropriate types
                Entity sweepEnt = (Entity)acPolyline;
                Curve pathEnt = (Curve)acHelix;

                if (sweepEnt == null || pathEnt == null)
                {
                    return null;
                }

                // We use a builder object to create
                // our SweepOptions
                SweepOptionsBuilder sob = new SweepOptionsBuilder();

                // Align the entity to sweep to the path
                sob.Align = SweepOptionsAlignOption.AlignSweepEntityToPath;

                // The base point is the start of the path
                sob.BasePoint = new Autodesk.AutoCAD.Geometry.Point3d(0, 0, 0);

                // The profile will rotate to follow the path
                sob.Bank = false;
                sob.DraftAngle = 0;

                // Now generate the solid or surface...
                Solid3d sol = new Solid3d();
                sol.SetDatabaseDefaults();
                sol.CreateSweptSolid(sweepEnt, pathEnt, sob.ToSweepOptions());
                rtnValue = sol;
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ToString());
                rtnValue = null;
            }

            return rtnValue;
        }


    }
}

 

 

 

---------------------------



(defun botsbuildbots() (botsbuildbots))
Message 3 of 3

jz5902
Explorer
Explorer

Thank you, arcticad.  That was very helpful.  I finally got my code working thanks to that example.

 

There are a couple of non-obvious things I discovered through trial and error that I'd like to point out for people (like me) who aren't very experienced with Autocad.  First, the start point of the helix is actually the center of the helix, not the start of the helical path.  Second, trying to set the StartPoint property directly always had strange effects.  To position a helix where you want it, you have to use the TransformBy method.

0 Likes