Author Topic: Ellipsoid Solid  (Read 2865 times)

0 Members and 1 Guest are viewing this topic.

Offline SEANT

  • Newbie
  • *
  • Posts: 7
  • Karma: +1/-0
    • prefered language: C
    • Prog expertise: Good
    • View Profile
Ellipsoid Solid
« on: March 04, 2011, 11:27:42 AM »
I’m investigating a method for sculpting solids with surface entities for a ‘work in progress’ routine that I have posted over at swamp.org.  The routine posted below served as an early test-bed, and I think it could serve as a good intermediate level “3D Entities” example here as well.

This is definitely a ‘no frills’ routine.  It’s only objective is to place an ellipsoid of specified dimensions at the WCS origin.   Though not generally in high demand, an ellipsoid is a tricky shape to make as a 3dSolid, so this routine has some measure of practicality. 

An added benefit to the method I used was that it imbued the shape with snapable quadrants (via END osnap).

The method, though, has the drawback that it uses objects available only in AutoCAD 2011.

DWG example of outout.

Code: [Select]


using System;
using System.IO;
using System.Collections.Generic;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Windows;


[CommandMethod("Ellipsoid")]
        //Basic method to put an ellipsoid at WCS origin
        static public void OpInitEl()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            PromptDoubleOptions pdo = new PromptDoubleOptions("\nEnter Length ");
            pdo.AllowArbitraryInput = true;
            pdo.AllowNegative = false;
            PromptDoubleResult pdr = ed.GetDouble(pdo);
            if (pdr.Status != PromptStatus.OK || pdr.Value <= 0) return;
            double Length = pdr.Value;

            pdo.Message = " Enter Width";
            pdr = ed.GetDouble(pdo);
            if (pdr.Status != PromptStatus.OK || pdr.Value <= 0) return;
            double Width = pdr.Value;

            pdo.Message = " Enter Height";
            pdr = ed.GetDouble(pdo);
            if (pdr.Status != PromptStatus.OK || pdr.Value <= 0) return;
            double Height = pdr.Value;

            Double[] matarr = new Double[16]{Length/2, 0.0,0.0,0.0,
                                                0.0,Width/2,0.0,0.0,
                                                0.0,0.0,Height/2,0.0,
                                                0.0,0.0,0.0,1.0};

            Matrix3d mat = new Matrix3d(matarr);

            Point3dCollection Cvs = GenCVs();

            //Scale points from sphere to ellipsoid
            for (int i = 0; i < 9; i++ )
            {
                Cvs[i] = Cvs[i].TransformBy(mat); 
            }
            DoubleCollection Dc = GenWghts();
            KnotCollection[] Knots = GenKnots();
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = (BlockTableRecord)(trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite));
                try
                {
                    //Generate the ellipsoid Octant
                    Autodesk.AutoCAD.DatabaseServices.NurbSurface NS = new Autodesk.AutoCAD.DatabaseServices.NurbSurface
                        (2, 2, true, 3, 3, Cvs, Dc,
                        Knots[0], Knots[1]);

                    //Create, mirror and union
                    Solid3d sol = new Solid3d();
                    sol.CreateBox(Length, Width, Height);
                    sol.TransformBy(Matrix3d.Scaling(0.5, new Point3d(Length / 2.0, Width / 2.0, Height / 2.0)));
                    sol.Slice(NS);

                    NS.Dispose();//Perhaps not specifically necessary - as NS is transaction resident
                    Plane Mir = new Plane(new Point3d(), new Vector3d(1.0,0.0,0.0));
                    Solid3d solMirr = sol.GetTransformedCopy(Matrix3d.Mirroring(Mir)) as Solid3d;
                    sol.BooleanOperation(BooleanOperationType.BoolUnite, solMirr);

                    Mir = new Plane(new Point3d(), new Vector3d(0.0, 1.0, 0.0));
                    solMirr = sol.GetTransformedCopy(Matrix3d.Mirroring(Mir)) as Solid3d;
                    sol.BooleanOperation(BooleanOperationType.BoolUnite, solMirr);

                    Mir = new Plane(new Point3d(), new Vector3d(0.0, 0.0, 1.0));
                    solMirr = sol.GetTransformedCopy(Matrix3d.Mirroring(Mir)) as Solid3d;
                    sol.BooleanOperation(BooleanOperationType.BoolUnite, solMirr);

                    sol.SetDatabaseDefaults();
                    btr.AppendEntity(sol);
                    trans.AddNewlyCreatedDBObject(sol, true);
                    trans.Commit();
                }
                catch
                {
                    trans.Abort();
                }
            }
        }

        private static Point3dCollection GenCVs()
        {
            //Generate Control Vertices for one octant of nurb based sphere
            Point3dCollection tempPts = new Point3dCollection();
            tempPts.Add(new Point3d(1.0, 0.0, 0.0));
            tempPts.Add(new Point3d(1.0, 0.0, 1.0));
            tempPts.Add(new Point3d(0.0, 0.0, 1.0));

            tempPts.Add(new Point3d(1.0, 1.0, 0.0));
            tempPts.Add(new Point3d(1.0, 1.0, 1.0));
            tempPts.Add(new Point3d(0.0, 0.0, 1.0));

            tempPts.Add(new Point3d(0.0, 1.0, 0.0));
            tempPts.Add(new Point3d(0.0, 1.0, 1.0));
            tempPts.Add(new Point3d(0.0, 0.0, 1.0));

            return tempPts;
        }

        private static DoubleCollection GenWghts()
        {
            //Generate weights for rational nurb surface
            DoubleCollection temp = new DoubleCollection(9);
            Double NearCorner = Math.Sqrt(0.5);

            temp.Add(1.0);
            temp.Add(NearCorner);
            temp.Add(1.0);

            temp.Add(NearCorner);
            temp.Add(0.5);
            temp.Add(NearCorner);

            temp.Add(1.0);
            temp.Add(NearCorner);
            temp.Add(1.0);

            return temp;
           
        }

        private static KnotCollection[] GenKnots()
        {
            //Generate knot vectors for PI based paramatization - uniform span from 0 to Pi/2 in U
            //                                                  - uniform span from 0 to Pi/2 in V
            KnotCollection[] tempKnots = new KnotCollection[2];

            tempKnots[0] = new KnotCollection();
            tempKnots[0].Add(0.0);
            tempKnots[0].Add(0.0);
            tempKnots[0].Add(0.0);

            tempKnots[0].Add(Math.PI / 2);
            tempKnots[0].Add(Math.PI / 2);
            tempKnots[0].Add(Math.PI / 2);

            tempKnots[1] = new KnotCollection();
            tempKnots[1].Add(0.0);
            tempKnots[1].Add(0.0);
            tempKnots[1].Add(0.0);

            tempKnots[1].Add(Math.PI / 2);
            tempKnots[1].Add(Math.PI / 2);
            tempKnots[1].Add(Math.PI / 2);

            return tempKnots;
        }

 
« Last Edit: March 05, 2011, 01:22:57 PM by SEANT »

Offline SEANT

  • Newbie
  • *
  • Posts: 7
  • Karma: +1/-0
    • prefered language: C
    • Prog expertise: Good
    • View Profile
Re: Ellipsoid Solid
« Reply #1 on: March 04, 2011, 11:29:32 AM »
It doesn't look like my DWG example attachment made it through.  I'll try a second time

Offline marko_ribar

  • Newbie
  • *
  • Posts: 2
  • Karma: +0/-0
  • Gender: Male
    • prefered language: C
    • Prog expertise: Beginner
    • View Profile
Re: Ellipsoid Solid
« Reply #2 on: December 21, 2011, 09:56:12 AM »
Seant, why didn't you post compiled *.dll to use it with NETLOAD from AUTOCAD

M.R.

Offline SEANT

  • Newbie
  • *
  • Posts: 7
  • Karma: +1/-0
    • prefered language: C
    • Prog expertise: Good
    • View Profile
Re: Ellipsoid Solid
« Reply #3 on: December 23, 2011, 08:14:21 AM »
The approaching holiday generates numerous distractions. :tresetonne:

Welcome to AcadNETwork, Marko,  and the .NET world at large.

Offline SEANT

  • Newbie
  • *
  • Posts: 7
  • Karma: +1/-0
    • prefered language: C
    • Prog expertise: Good
    • View Profile
Re: Ellipsoid Solid
« Reply #4 on: December 23, 2011, 08:27:05 AM »
By the way: I've changed the command name to "EllipsoidSolid" (or "ElSol", for short) to avoid conflicts.

Offline marko_ribar

  • Newbie
  • *
  • Posts: 2
  • Karma: +0/-0
  • Gender: Male
    • prefered language: C
    • Prog expertise: Beginner
    • View Profile
Re: Ellipsoid Solid
« Reply #5 on: December 23, 2011, 09:34:49 AM »
Never mind, I've compiled also, hope you wouldn't be mad at me, I posted *.dll files on www.theswamp.org

Regards, M.R.
Seems that no one knows for this site, and it has stupid verification question for registration process...
:)