TheSwamp

Code Red => .NET => Topic started by: It's Alive! on July 21, 2008, 08:21:37 AM

Title: Matrix3d and TransformBy help
Post by: It's Alive! on July 21, 2008, 08:21:37 AM
what I am trying to do is get the bounding box of my cuboid by getting the longest edge from the solid,
using the points from the edge create a matrix to align the solid to the WCS,  then getting the bounding box. 
My method is soo ugly, I wonder if one of you 3D guys might help me find a better solution. Acad09 w/brep

Code: [Select]

removed junk code

Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 21, 2008, 08:33:59 AM

Here is a picy of a sample object I would like to align to the WCS
Title: Re: Matrix3d and TransformBy help
Post by: SEANT on July 21, 2008, 09:15:29 AM
what I am trying to do is get the bounding box of my cuboid by getting the longest edge from the solid,
using the points from the edge create a matrix to align the solid to the WCS,  then getting the bounding box. 
My method is soo ugly, I wonder if one of you 3D guys might help me find a better solution. Acad09 w/brep

You may think it ugly, but I think it pretty effective.  I'll be watching this thread with interest.
Title: Re: Matrix3d and TransformBy help
Post by: SEANT on July 21, 2008, 10:40:37 AM
Would the next general step be to backtrack from that longest edge to the Parent’s (or is it the Child’s) face with the largest area?  Perhaps use that face’s Normal as a guide to square up the remaining axis.  This “roll” axis, as was discussed in some similar VBA threads, seems to be particularly difficult to orient. 
Title: Re: Matrix3d and TransformBy help
Post by: ahlzl on July 21, 2008, 11:08:49 AM
I don't completely understand.

NO Brep
Code: [Select]
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

namespace MyUCS
{
    public class Class1
    {
        [CommandMethod("test")]
        public void MyTest()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            Database db = HostApplicationServices.WorkingDatabase;
            Matrix3d mt = ed.CurrentUserCoordinateSystem;

            PromptEntityOptions opt = new PromptEntityOptions("\nSelect...");
            PromptEntityResult res = ed.GetEntity(opt);

            if (res.Status == PromptStatus.OK)
            {
                using (Transaction trans = db.TransactionManager.StartTransaction())
                {
                    Entity ent = (Entity)trans.GetObject(res.ObjectId,
                        OpenMode.ForWrite);
                    ent.TransformBy(mt.Inverse());
                    Point3d maxPt = ent.GeometricExtents.MaxPoint;
                    Point3d minPt = ent.GeometricExtents.MinPoint;
                    ent.TransformBy(mt);
                    ed.WriteMessage("\n MAX: " + maxPt.ToString());
                    ed.WriteMessage("\n MIN: " + minPt.ToString());       
                    trans.Commit();
                }
            }
        }
    }
}

Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 21, 2008, 11:17:54 AM
Would the next general step be to backtrack from that longest edge to the Parent’s (or is it the Child’s) face with the largest area?  Perhaps use that face’s Normal as a guide to square up the remaining axis.  This “roll” axis, as was discussed in some similar VBA threads, seems to be particularly difficult to orient. 

Interesting, I will have to try that.

Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 21, 2008, 11:25:31 AM
I don't completely understand.

You would get an incorrect value if your object is rotated off the UCS, for example your routine returns

Quote
TEST
Select...:
(102,2438,50.8 ) width, height, depth
Command:
TEST
Select...:
(1759.84735701708,1759.84735701708,102) width, height, depth

On these objects


Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 21, 2008, 12:03:53 PM
Nope .. needs more work.   :ugly:
Here is the latest code and a test DWG if anyone wants to play. The value should be ( 102,2438,50.8 ) in all cases

Code: [Select]
removed junk code

Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 21, 2008, 03:08:53 PM
Ok I think the attached code works better  :laugh:

edit: made some minor changes

Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 22, 2008, 04:31:48 AM

PFC, now I can extract my cabinet part dimensions, of course this is assuming the parts are not directional (grained)  8-)


Title: Re: Matrix3d and TransformBy help
Post by: bikelink on July 22, 2008, 05:20:59 AM
that's very nice!
Title: Re: Matrix3d and TransformBy help
Post by: SEANT on July 22, 2008, 07:20:07 AM
Daniel,

Excellent, excellent, excellent.

I'm not anywhere near up to speed enough (especially with the BREP stuff) to offer much coding feedback.  I can, however, attempt to throw a wrench, or two, into the works with these sample solids.  Granted, they are not typical, but any ideas on how to account for them?
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 22, 2008, 12:48:40 PM
Sean, I was able to modify the code to get the I-beam to come through, but the second object may take a little more work. As of now the test is looking for two edges that share a common point and that are perpendicular.  I have attached the latest code (kludge) , unfortunately it seems to spit the dummy when processing large numbers of objects( +4000) .  I dunno why  :-o

Title: Re: Matrix3d and TransformBy help
Post by: Paul Richardson on July 22, 2008, 07:22:38 PM
This just looks for the longest edge in each solid for a test. See attached brep.dwg to see a solid with multiple Complexes and the file TimberData.csv for the results.

See notes in Commands.cs. Code crashes randomly when looping 'brep.Complexes'. Seems to happen more as the number of solids increases - anyone know why?
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 23, 2008, 12:41:13 AM
This just looks for the longest edge in each solid for a test. See attached brep.dwg to see a solid with multiple Complexes and the file TimberData.csv for the results.

See notes in Commands.cs. Code crashes randomly when looping 'brep.Complexes'. Seems to happen more as the number of solids increases - anyone know why?

Nice work Paul. Thanks for sharing!
So far I am finding the brep stuff slightly unstable too, no error messages, just poof. 
Title: Re: Matrix3d and TransformBy help
Post by: Kerry on July 23, 2008, 01:17:20 AM

Interesting stuff guys .. wish I could make time to play :-(

Dan/Paul : Perhaps Kean should be advised about the crashes. I'm not sure if he still visits here, so giving him a link  to this thread may be needed.


be well.

Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 23, 2008, 01:40:00 AM

Interesting stuff guys .. wish I could make time to play :-(

Dan/Paul : Perhaps Kean should be advised about the crashes. I'm not sure if he still visits here, so giving him a link  to this thread may be needed.


be well.



Hi Kerry,

That’s a good idea, I was kind of assuming that my code was the cause, but since Paul is having issues as well, we should probably pass this on to the big guy.
Title: Re: Matrix3d and TransformBy help
Post by: Paul Richardson on July 23, 2008, 08:14:30 AM
This just looks for the longest edge in each solid for a test. See attached brep.dwg to see a solid with multiple Complexes and the file TimberData.csv for the results.

See notes in Commands.cs. Code crashes randomly when looping 'brep.Complexes'. Seems to happen more as the number of solids increases - anyone know why?

Nice work Paul. Thanks for sharing!
So far I am finding the brep stuff slightly unstable too, no error messages, just poof. 


Daniel,

I see yours is crashing randomly too. I'm going to try in native brep and see if I get the same crash - maybe we can narrow it down to the wrapper.
Title: Re: Matrix3d and TransformBy help
Post by: Paul Richardson on July 23, 2008, 08:16:58 AM

Interesting stuff guys .. wish I could make time to play :-(

Dan/Paul : Perhaps Kean should be advised about the crashes. I'm not sure if he still visits here, so giving him a link  to this thread may be needed.


be well.



Hi Kerry,

That’s a good idea, I was kind of assuming that my code was the cause, but since Paul is having issues as well, we should probably pass this on to the big guy.


I was hoping I was just missing something in my code which was causing the crash - I think there is someplace to enter API bug reports. I'll take a look.
Title: Re: Matrix3d and TransformBy help
Post by: Paul Richardson on July 23, 2008, 08:36:07 AM
This just looks for the longest edge in each solid for a test. See attached brep.dwg to see a solid with multiple Complexes and the file TimberData.csv for the results.

See notes in Commands.cs. Code crashes randomly when looping 'brep.Complexes'. Seems to happen more as the number of solids increases - anyone know why?

My original version of 'LongestEdges' method did not loop each Complex so I had no need to
reset 'tempLongestEdge' to 0. Quick change in this version which resets it before looping the
next Complex.

Code: [Select]
    private static double[] LongestEdges(Solid3d sol)
    {

      double tempLongestEdge = 0;
      int complexCounter = 0;

      Brep brep = new Brep(sol);
      double[] tempLongestEdges = new double[ComplexCount(brep)];

      foreach (Complex complex in brep.Complexes)
      {

        foreach (Shell shell in complex.Shells)
        {

          foreach (Autodesk.AutoCAD.BoundaryRepresentation.Face face in shell.Faces)
          {

            foreach (BoundaryLoop loop in face.Loops)
            {
              //Find longest edge.
              foreach (Edge edge in loop.Edges)

                if (edge.Vertex1.Point.DistanceTo(edge.Vertex2.Point)
                  > tempLongestEdge)

                  tempLongestEdge =
                    edge.Vertex1.Point.DistanceTo(edge.Vertex2.Point);
            }
          }
        }

        tempLongestEdges[complexCounter] = tempLongestEdge;
        complexCounter++;
        //forget to reset in last version
        tempLongestEdge = 0;
      }

      return tempLongestEdges;
    }
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 23, 2008, 10:21:46 AM
Just thinking out loud, would something like this work? … Pseudo code…

Code: [Select]
 
   public static int EdgeComparer(AcBr.Edge A, AcBr.Edge B)
    {
      return A.GetPerimeterLength().CompareTo(B.GetPerimeterLength());
    }

    private static double[] LongestEdges(Solid3d sol)
    {
      AcBr.Brep brep = new AcBr.Brep(sol);

      List<List<AcBr.Edge>> MyEdges = new List<List<AcBr.Edge>>();

      foreach (AcBr.Complex c in brep.Complexes)
        MyEdges.Add(new List<AcBr.Edge>(c.Brep.Edges));
     
      MyEdges.ForEach(L => L.Sort(EdgeComparer));

      double[] tempLongestEdges = new double[MyEdges.Count];

      for (int i = 0; i < MyEdges.Count; i++)
        tempLongestEdges[i] = MyEdges[i][0].GetPerimeterLength();
     
      return tempLongestEdges;
    }
Title: Re: Matrix3d and TransformBy help
Post by: Paul Richardson on July 23, 2008, 01:04:57 PM
Just thinking out loud, would something like this work? … Pseudo code…

Code: [Select]
 
   public static int EdgeComparer(AcBr.Edge A, AcBr.Edge B)
    {
      return A.GetPerimeterLength().CompareTo(B.GetPerimeterLength());
    }

    private static double[] LongestEdges(Solid3d sol)
    {
      AcBr.Brep brep = new AcBr.Brep(sol);

      List<List<AcBr.Edge>> MyEdges = new List<List<AcBr.Edge>>();

      foreach (AcBr.Complex c in brep.Complexes)
        MyEdges.Add(new List<AcBr.Edge>(c.Brep.Edges));
     
      MyEdges.ForEach(L => L.Sort(EdgeComparer));

      double[] tempLongestEdges = new double[MyEdges.Count];

      for (int i = 0; i < MyEdges.Count; i++)
        tempLongestEdges[i] = MyEdges[i][0].GetPerimeterLength();
     
      return tempLongestEdges;
    }

Very nice... But same error - looks pretty while doing it though...)
Title: Re: Matrix3d and TransformBy help
Post by: m.araujo on July 23, 2008, 07:09:12 PM
Hi everyone,

I'm just a noob, but I've been following this post, because I'm the one who posited the question which got it all started back on the autodesk website.  I'm working on a solution for creating a lumber schedule from a 3d timber frame model that uses the I-J-K info from
MASSPROP to realign the ucs to an object. From there you can get the coords for an oriented bounding box (these OOB's are something that game programmers use alot).  This would essentially be the original uncut timber. I've been researching methods to calculate oriented bounding boxes using descriptive geometry....there's info if you want to google it.  A guy named o'Rourke wrote a algorithm back in the 90's that will do it for you based on coordinates....Its a rather complicated formula.

I wanted to comment on the approach of grabbing the longest edge of a "timber"  I am a timber framer and have attached a dwg with a single timber in which the longest edge does not accurately describe the required length of the uncut timber.  It is a Valley rafter and is essentially a parallelogram.  Does this in any way complicate the methods by which you guys are approaching this task?

keep up the great work,

Matt Araujo
Title: Re: Matrix3d and TransformBy help
Post by: Paul Richardson on July 23, 2008, 08:01:42 PM
Hi everyone,

I'm just a noob, but I've been following this post, because I'm the one who posited the question which got it all started back on the autodesk website.  I'm working on a solution for creating a lumber schedule from a 3d timber frame model that uses the I-J-K info from
MASSPROP to realign the ucs to an object. From there you can get the coords for an oriented bounding box (these OOB's are something that game programmers use alot).  This would essentially be the original uncut timber. I've been researching methods to calculate oriented bounding boxes using descriptive geometry....there's info if you want to google it.  A guy named o'Rourke wrote a algorithm back in the 90's that will do it for you based on coordinates....Its a rather complicated formula.

I wanted to comment on the approach of grabbing the longest edge of a "timber"  I am a timber framer and have attached a dwg with a single timber in which the longest edge does not accurately describe the required length of the uncut timber.  It is a Valley rafter and is essentially a parallelogram.  Does this in any way complicate the methods by which you guys are approaching this task?

keep up the great work,

Matt Araujo

Getting the longest line was just for a test, you can grab any data you want. Since brep.net seems to be buggy I'd keep going with your and Daniel's methods...
Title: Re: Matrix3d and TransformBy help
Post by: Paul Richardson on July 24, 2008, 05:26:53 AM
Just thinking out loud, would something like this work? … Pseudo code…

Code: [Select]
 
   public static int EdgeComparer(AcBr.Edge A, AcBr.Edge B)
    {
      return A.GetPerimeterLength().CompareTo(B.GetPerimeterLength());
    }

    private static double[] LongestEdges(Solid3d sol)
    {
      AcBr.Brep brep = new AcBr.Brep(sol);

      List<List<AcBr.Edge>> MyEdges = new List<List<AcBr.Edge>>();

      foreach (AcBr.Complex c in brep.Complexes)
        MyEdges.Add(new List<AcBr.Edge>(c.Brep.Edges));
     
      MyEdges.ForEach(L => L.Sort(EdgeComparer));

      double[] tempLongestEdges = new double[MyEdges.Count];

      for (int i = 0; i < MyEdges.Count; i++)
        tempLongestEdges[i] = MyEdges[i][0].GetPerimeterLength();
     
      return tempLongestEdges;
    }

Very nice... But same error - looks pretty while doing it though...)

fyi - Fenton Webb Just confirmed that there is a bug with 'Autodesk.AutoCAD.DatabaseServices.Solid3d.RemoveFaces' as the underlying AcDb3dSolid pointer is NULL and cannot be accessed... He is looking at this issue too - I'll let ya know.
Title: Re: Matrix3d and TransformBy help
Post by: SEANT on July 24, 2008, 09:33:54 AM
Here’s my contribution to the effort.  I made things easy on myself by increasing the level of symmetry, thus avoiding any “roll” axis concerns. 

I originally figured a “cylinder length” method would be fairly straight forward but it turned out rather elusive.  So much so I can virtually guarantee I missed a better method along the way.  Casting a Face's Surface as a Cylinder, which seems appropriate, was a big roadblock.

The only success I could realize was via Face/NurbsSurface conversion.  I don’t find that conversion particularly dreadful (as I have done some programming for Rhino) but can see how it would be distasteful to others.

In any event, the code is below.  It only processes one solid at a time but will probably suffer the same level of inconsistency - as mentioned previously in this thread - for larger selection sets.

Code: [Select]
using System;
using System.Text;
using System.Collections.Generic;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.BoundaryRepresentation;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using System.Runtime.InteropServices;

using AcAp = Autodesk.AutoCAD.ApplicationServices;
using AcEd = Autodesk.AutoCAD.EditorInput;
using AcGe = Autodesk.AutoCAD.Geometry;
using AcRx = Autodesk.AutoCAD.Runtime;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
using AcWd = Autodesk.AutoCAD.Windows;
using AcBr = Autodesk.AutoCAD.BoundaryRepresentation;

[assembly: CommandClass(typeof(CsMgdAcad5.STSCCommands))]

namespace CsMgdAcad5
{
    public class STSCCommands
    {

    /// <summary>
    /// Orient cylinder to return usefull BB info
    /// </summary>         
        public STSCCommands()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        // Define Command "CylinderSize"
        [CommandMethod("CylSize")]
        static public void CylinderDimensions() // This method can have any name
        {
            Database db = HostApplicationServices.WorkingDatabase;
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            Transaction tr = db.TransactionManager.StartTransaction();

            try
            {
                // Prompt for selection of a solid
                PromptEntityOptions prEntOpt = new PromptEntityOptions("Select a 3D solid: ");
                prEntOpt.SetRejectMessage("\nPlease select only a 3D Solid");
                prEntOpt.AddAllowedClass(typeof(Solid3d), true);

                PromptEntityResult prEntRes = ed.GetEntity(prEntOpt);
                ObjectId[] objIds = { prEntRes.ObjectId };

                Solid3d sol = (Solid3d)tr.GetObject(prEntRes.ObjectId, OpenMode.ForRead);
                Brep brp = new Brep(sol);
                int cmplxCount = 0, shllCount = 0;

                foreach (Complex cmplx in brp.Complexes)
                {
                    ++cmplxCount;
                }
                if (cmplxCount == 1)
                {
                    List<AcBr.Complex> lstCmPlx = new List<AcBr.Complex>();
                    lstCmPlx.AddRange(brp.Complexes);
                    foreach (Shell shll in lstCmPlx[0].Shells)
                       {
                            ++shllCount;
                       }
                    if (shllCount == 1)
                    {
                        List<AcBr.Shell> lstShell = new List<AcBr.Shell>();
                        lstShell.AddRange(brp.Shells);
                        double LargestArea = 0.0;
                        Autodesk.AutoCAD.BoundaryRepresentation.Face FaceLarge = null;
                        foreach (Autodesk.AutoCAD.BoundaryRepresentation.Face fce in lstShell[0].Faces)
                            //Let's assume the Face with the largest area defines extrusion direction.
                            //This is certainly not a bullet proof assumption but will work for the time being
                        {
                            if (fce.GetArea() > LargestArea)
                            {
                                FaceLarge = fce;
                                LargestArea = FaceLarge.GetArea();
                            }
                        }
                        NurbSurface NS = FaceLarge.GetSurfaceAsNurb();
                        if (NS.IsPeriodicInU ^ NS.IsPeriodicInV)//Locate cylindrical like surface (needs work to exclude Cone and Torus)
                        {
                            NurbSurfaceDefinition NSD = NS.GetDefinition();
                            Point3dCollection P3C = NSD.ControlPoints;
                            int CPCount = P3C.Count;
                            int CPCountU = NS.NumControlPointsInU;
                            int CPCountV = NS.NumControlPointsInV;
                            Point3d dir1;
                            Point3d dir2;
                            if (NS.IsPeriodicInU)
                            {
                                dir1 = P3C[0];
                                dir2 = P3C[CPCount / CPCountV];
                            }
                            else
                            {
                                dir1 = P3C[0];
                                dir2 = P3C[CPCount / CPCountU];                                   
                            }
                            Vector3d DirV = (dir2.Subtract(dir1.GetAsVector())).GetAsVector();
                            Matrix3d mat = Matrix3d.WorldToPlane(DirV);
                            mat = mat.Inverse();
                            mat = mat.Transpose();
                            sol.UpgradeOpen();
                            sol.TransformBy(mat);
                            dir1 = sol.GeometricExtents.MinPoint;
                            dir2 = sol.GeometricExtents.MaxPoint;
                            double X = Math.Round(Math.Abs(dir1.X - dir2.X),6);
                            double Y = Math.Round(Math.Abs(dir1.Y - dir2.Y),6);
                            double Z = Math.Round(Math.Abs(dir1.Z - dir2.Z),6);
                            StringBuilder sb = new StringBuilder();
                            sb.Append("(");
                            sb.Append(X.ToString());
                            sb.Append(",");
                            sb.Append(Y.ToString());
                            sb.Append(",");
                            sb.Append(Z.ToString());
                            sb.Append(")");
                            ed.WriteMessage("\n" + sb.ToString());
                        }                           
                    }
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nException in traversal: {0}", ex.Message);
            }
            finally
            {
                tr.Dispose();
            }
        }
    }
}
 
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 24, 2008, 12:35:05 PM
fyi - Fenton Webb Just confirmed that there is a bug with 'Autodesk.AutoCAD.DatabaseServices.Solid3d.RemoveFaces' as the underlying AcDb3dSolid pointer is NULL and cannot be accessed... He is looking at this issue too - I'll let ya know.

Well at least we know what’s going on. Thanks for sharing the info  :-)
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 24, 2008, 12:38:12 PM
Here’s my contribution to the effort.  ....

Wow! Very nice programming Sean!  8-)
I’ll give it a run in the AM.
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 24, 2008, 01:07:14 PM
Hi everyone,

I'm just a noob, but I've been following this post, because I'm the one who posited the question which got it all started back on the autodesk website.  I'm working on a solution for creating a lumber schedule from a 3d timber frame model that uses the I-J-K info from
MASSPROP to realign the ucs to an object. From there you can get the coords for an oriented bounding box (these OOB's are something that game programmers use alot).  This would essentially be the original uncut timber. I've been researching methods to calculate oriented bounding boxes using descriptive geometry....there's info if you want to google it.  A guy named o'Rourke wrote a algorithm back in the 90's that will do it for you based on coordinates....Its a rather complicated formula.

I wanted to comment on the approach of grabbing the longest edge of a "timber"  I am a timber framer and have attached a dwg with a single timber in which the longest edge does not accurately describe the required length of the uncut timber.  It is a Valley rafter and is essentially a parallelogram.  Does this in any way complicate the methods by which you guys are approaching this task?

keep up the great work,

Matt Araujo

Matt, I have compiled my routine for you to try. Some info for you, the routine searches for two edges in the solid that are perpendicular and share a common point, starting with the longest edge then iterating through until a match is found. If a match is found, the data from the edges is used to align the solid with the WCS; the routine then gets the bounding box data. Caveat,  It would be possible for the routine to pickup edges on say a compound miter and return incorrect dimensions.

Give it a shot, the command is Timber, you can find the DLL in the release folder of the attached solution


edit: removed old code
Title: Re: Matrix3d and TransformBy help
Post by: MickD on July 24, 2008, 05:44:42 PM
Nice work guys!

Dan'
instead of using 2 edges, can you grab the longest edge's normal? or maybe one off the edge's face (one of it's owners) to construct a matrix for xform.
Another way too, you don't need a perp edge, just grab any edge and xproduct it to give a perp vector to both edges, you can then square up the matrix by xproducting the new vec with the first edge vec ;)
hth
Title: Re: Matrix3d and TransformBy help
Post by: m.araujo on July 24, 2008, 06:14:56 PM
Quote

Matt, I have compiled my routine for you to try. Some info for you, the routine searches for two edges in the solid that are perpendicular and share a common point, starting with the longest edge then iterating through until a match is found. If a match is found, the data from the edges is used to align the solid with the WCS; the routine then gets the bounding box data. Caveat,  It would be possible for the routine to pickup edges on say a compound miter and return incorrect dimensions.

Give it a shot, the command is Timber, you can find the DLL in the release folder of the attached solution





Daniel,

Thanks.  I will take a look at this code this weekend when I can sit down and study it.  As far as aligning ucs this might be a more fool proof way....I'm way to green to try and code this but this is the method I discovered

run MASSPROP on an object and take note of the I and J coordinates (actually any two of the I,J,K  directions about centroid will work, because there are three appropriate ucs orientations to create the necessary bounding box.  )  create a new ucs with an origin at 0,0,0 and use the I coordinates to define X and the J to define a point on the XY axis....boom, new UCS.  If you then rerun massprop and create a box with an origin of the minimum xyz coord and end at the max xyz coord You will have a oriented bounding box. Of course with this info you don't even need to create the box,  Look at the 2 bounding box coords - subtract the max X value from the min x value, the max y from the min y and so forth....and these need to be |absolute|  values as dimensions cant be negative. 


Thanks again,

Matt Araujo

edit: fixed quote tags
Title: Re: Matrix3d and TransformBy help
Post by: SEANT on July 24, 2008, 08:27:11 PM
The thing with I, J, and K (Principal Directions) is that they are based on the distribution of mass in the solid.  Consequently, the vectors may not line up with the most useful directions if the solid has any irregularities. 

The attached example exaggerates the issue for demonstration purposes.  Compare the Mass Properties with the dimensions.
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 25, 2008, 01:52:06 PM
This is interesting, I was looking through the DRX SDK help files under Brep, they have a method
Code: [Select]
//Returns the transformation matrix for this BREP object.
Bool  OdBrBrep::getTransformation(OdGeMatrix3d&  xfm ) const

Sure would be nice if AutoCAD had this .... hint hint
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on July 26, 2008, 12:24:00 PM
This is interesting, I was looking through the DRX SDK help files under Brep, they have a method
Code: [Select]
//Returns the transformation matrix for this BREP object.
Bool  OdBrBrep::getTransformation(OdGeMatrix3d&  xfm ) const

Sure would be nice if AutoCAD had this .... hint hint


Perhaps, the below function could be use for what you guys are doing, and ported to C#, not fully tested, no idea.-

edit: by me change of pRegion to pSolid

Code: [Select]
static void GetSolidBound(void)
{
ads_name ss, ename;
TCHAR* promptPtrs[] = {_T("Select solid object: "), _T("Remove solid object: ")};
resbuf *ssfilter = acutBuildList(RTDXF0, _T("3DSOLID"), RTNONE);
if (acedSSGet(_T("_:S:$"), promptPtrs, NULL, ssfilter, ss) == RTNORM)
{
acutRelRb(ssfilter);
if (acedSSName(ss, 0, ename) != RTNORM)
{
acedSSFree(ss);
return;
}
acedSSFree(ss);
AcDbObjectId objid = AcDbObjectId::kNull;
acdbGetObjectId(objid, ename);
if (objid == AcDbObjectId::kNull) return;
AcDbObjectPointer <AcDbEntity> pSolid(objid, AcDb::kForWrite);
if (pSolid.openStatus() != Acad::eOk) return;
AcBrBrep brep;
brep.set(*(pSolid.object()));
AcBr::ErrorStatus returnValue = AcBr::eOk;

// getBoundBlock = Geometric bounds query.
// Returns the model space bounding box for the current topology object.
// The box is returned as an AcGeBoundBlock3d, with the entire chain of transforms from the object ID array applied.
// The box is instantiated by the caller and passed by reference for getBoundBlock() to (re)set.
AcGeBoundBlock3d bblock;
returnValue = brep.getBoundBlock(bblock);
if (returnValue != AcBr::eOk)
{
acutPrintf(_T("\n***Error in AcBrBrep::getBoundBlock***"));
return;
}
AcGePoint3d min, max;
bblock.getMinMaxPoints(min, max);
acutPrintf(_T("\n Bounding Block lower corner is ("));
acutPrintf(_T("%lf, "), min.x);
acutPrintf(_T("%lf, "), min.y);
acutPrintf(_T("%lf"), min.z);
acutPrintf(_T(")\n"));
acutPrintf(_T("\n Bounding Block upper corner is ("));
acutPrintf(_T("%lf, "), max.x);
acutPrintf(_T("%lf, "), max.y);
acutPrintf(_T("%lf"), max.z);
acutPrintf(_T(")\n"));
}
}
Title: Re: Matrix3d and TransformBy help
Post by: MickD on July 26, 2008, 06:48:32 PM
The problem with solids is that they do not have a 'useful' direction as such as the solid has no real identity (it's not a steel beam or 4x2 say), it's just some direction derived at creation so it could still be meaningless in some cases.
If the solid was an extrusion, that would be a good start though, particularly in construction and similar trades where 'sections' are used of the shelf.

I still find adding the data at creation to be most efficient for me, I can also add data to existing objects if needed but they still lack other useful data such as it's material/grade, mass, std pitch and gauge for example.

If you want to make a quick 'add directional data' to existing solids. I'd probably ask the user to select an edge (or an edge from multiple solids for easier use using brep to highlight each edge say) indicating length direction and use the edge's face normal to construct the xform matrix, this way you will get the correct length even if it's shorter than the width/height. Unless you are sure that all lengths are greater than W/H it's pretty hard to get it right automatically, somewhere the user will need to decide which way is which.
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on July 26, 2008, 07:55:10 PM
Thanks Mick,


Makes sense...



About the 3d world, I am in diapers...  :laugh:


I have been playing with the Z principal axe and trying to build an oriented bounding box.... if works, will post here....
Title: Re: Matrix3d and TransformBy help
Post by: MickD on July 26, 2008, 08:30:18 PM
As was mentioned earlier, the principal directions are produced from the solids' geometry and centre of gravity etc, this changes as the solid is modified so it will/can change the length direction also so I wouldn't spend too much time on it ;)

I have spent a lot of time on this subject and there's no easy way for the reason's I mentioned above, a 3d solid in autocad terms needs to be a simple as possible so it can be used in any discipline to represent what is needed, if they were to fix things like direction vectors it may put a constraint on what can be done with the solid.

Think of 3d solids as a 'base class' in programming terms that simply provides the solid manifold geometry representation of your object (autocad uses the acis modeling engine for the geometry in memory and acad displays it by drawing each edge/face and sending it to the graphics card), you then derive from it to build in discipline specific attributes for your application.
You can do it in 2 ways, custom objects or use extended data and reactors, I prefer the latter as these elements are native to autocad and well tested and really are not that different (extended data takes a little more work to store and retrieve though).
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on July 26, 2008, 08:39:42 PM
10-4
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 27, 2008, 06:37:24 AM
Nice work guys!

Dan'
instead of using 2 edges, can you grab the longest edge's normal? or maybe one off the edge's face (one of it's owners) to construct a matrix for xform.
Another way too, you don't need a perp edge, just grab any edge and xproduct it to give a perp vector to both edges, you can then square up the matrix by xproducting the new vec with the first edge vec ;)
hth

Thanks for the tips Mick!
I’m really not sure I follow you though.  My abbey normal brain can only figure out how to square up the solid when I have two edges that are perpendicular.  Everything else I try seems to miss one axis.  :mrgreen:
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 27, 2008, 06:43:04 AM
I still find adding the data at creation to be most efficient for me

This is what I do also.

Just having a bit of fun too, this is the farthest I have ever gotten in aligning the BB with the WCS, I know people (including me) have been trying on and off for years.
Title: Re: Matrix3d and TransformBy help
Post by: SEANT on July 27, 2008, 08:39:15 AM
Mick

As also implied by Luis and Daniel, I think this exercise has its greatest potential as a matter of intellectual curiosity.

With regard to the more practical considerations, I think your assessment makes perfect sense.  Given the potential benefit of imbuing the solid with useful characteristics, such as the ones you mentioned, leveraging an OpenMode.ForWrite to also include orientation data is efficient. 

One pitfall is when dealing with documents from other organizations.  Many of which may not be receptive to outside routines, especially if required to run persistently.   

My perfect scenario would be the development of organization specific routines which allows processing of non-standardized documents, thus avoiding any compliance requirements.  This processing would couple Entities with material data (as derived from Layer, Tables, Xdata, or etc) in an internally consistent fashion.

Dimensional data would also be included in that processing. Asking the user to select the length for a given solid is the most sensible but has a few drawbacks; some of these projects use hundreds of extrusions, the task is somewhat monotonous, and that user is always me.  Given that potential benefit, the exercise straddles the fence between curiosity and practicality.
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on July 27, 2008, 12:38:12 PM
Well... since this, it is just an exercise for my brain and before I lost the 1/2 brain cell left....

I have the bounding box (min-max aligned or on the solid not the projected ones as my previous arx function)... now what do I needed for? or use them for....  :ugly:
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 27, 2008, 08:08:41 PM
Well... since this, it is just an exercise for my brain and before I lost the 1/2 brain cell left....

I have the bounding box (min-max aligned or on the solid not the projected ones as my previous arx function)... now what do I needed for? or use them for....  :ugly:

Well, there are many industries that would benefit from having such an animal, example the commercial casework industry deals with mostly square parts. If one could build a library that would generate a bill of materials or data to feed to a sheet optimizer from a 3d drawing, companies might buy it.. ie think ($$$) :angel:
Title: Re: Matrix3d and TransformBy help
Post by: MickD on July 27, 2008, 09:13:36 PM
DaveW's MillLister does this, he has been using this approach for quite a while now with some success and I think his product is reasonably priced as well, might be worth a look.
The exercise is fun though :)
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 27, 2008, 09:25:47 PM
DaveW's MillLister does this, he has been using this approach for quite a while now with some success and I think his product is reasonably priced as well, might be worth a look.
The exercise is fun though :)

True dat
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 28, 2008, 09:17:58 AM
more fun  8-)


Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on July 28, 2008, 09:52:51 AM
Well... since this, it is just an exercise for my brain and before I lost the 1/2 brain cell left....

I have the bounding box (min-max aligned or on the solid not the projected ones as my previous arx function)... now what do I needed for? or use them for....  :ugly:

Well, there are many industries that would benefit from having such an animal, example the commercial casework industry deals with mostly square parts. If one could build a library that would generate a bill of materials or data to feed to a sheet optimizer from a 3d drawing, companies might buy it.. ie think ($$$) :angel:

I need to read (later at home) all what you guys have been doing... and will continue debugging the function, still it is work in progress.

Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on July 28, 2008, 10:25:06 AM
companies might buy it.. ie think ($$$) :angel:

Thanks Daniel,

I had tried that in the past, on some other projects, that I did, and it is not easy as it sounds....  :wink:
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 28, 2008, 10:42:35 AM
companies might buy it.. ie think ($$$) :angel:

Thanks Daniel,

I had tried that in the past, on some other projects, that I did, and it is not easy as it sounds....  :wink:

Yes I know,  I have one product out there, generates little income and big headaches  :-o
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on July 28, 2008, 12:35:24 PM
companies might buy it.. ie think ($$$) :angel:

Thanks Daniel,

I had tried that in the past, on some other projects, that I did, and it is not easy as it sounds....  :wink:

Yes I know,  I have one product out there, generates little income and big headaches  :-o

Yep...

Now, getting back to this topic, it is good idea to post the solution as open source?... I will upload an animated image, later from home or when I have something more useful.

But, I am using for example for this GetOBB(); function a lot of my own geometry library, and there are things, that I want to keep away from the public....
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on July 28, 2008, 12:47:09 PM
companies might buy it.. ie think ($$$) :angel:

Thanks Daniel,

I had tried that in the past, on some other projects, that I did, and it is not easy as it sounds....  :wink:

Yes I know,  I have one product out there, generates little income and big headaches  :-o

Yep...

Now, getting back to this topic, it is good idea to post the solution as open source?... I will upload an animated image, later from home or when I have something more useful.

But, I am using for example for this GetOBB(); function a lot of my own geometry library, and there are things, that I want to keep away from the public....

Only post what your comfortable posting  :-)
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on July 31, 2008, 06:09:04 PM
Only post what your comfortable posting  :-)

I will....


Now, what it is the status on this?.... have something that it is working?


LE!
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 01, 2008, 11:21:34 AM
By the way...

Look/google for:

Stefan Gottschalk's Separating Axis Theorem thesis.
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 01, 2008, 11:38:11 AM
I am trying to do some of the brep stuff  in ARX, so I can p/invoke from C#.
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 01, 2008, 11:55:13 AM
I am trying to do some of the brep stuff  in ARX, so I can p/invoke from C#.


See if you can extract all the vectors for each face and get the min and max.

And then.... maybe you can do something like:

edit: for swampers... only

Code: [Select]
public OrientedBoundingBox(
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 02, 2008, 07:22:03 AM
I think I tried something like that once before using lisp and Owen’s secret decoder ring (decoding the SAT),
the problem is that the points are returned in WCS so you end up with a standard bounding box.
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 02, 2008, 12:44:47 PM
This is what I have done so far.

Tested on AutoCAD 2007 only.

Command: OOB

Draws:

1. Solid points points in Yellow.
2. Centroid & AcGeBoundBlock3d min max in Magenta.
3. Min Max on solid in Cyan.
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 02, 2008, 01:07:49 PM
I  created a cuboid  100 x 100 x 10 rotated by 45* in both Z and X. as you can see your points are correct but they are not transformed to the orientation of the object so when you get the min, max it’s in WCS.

Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 02, 2008, 01:15:02 PM
I  created a cuboid  100 x 100 x 10 rotated by 45* in both Z and X. as you can see your points are correct but they are not transformed to the orientation of the object so when you get the min, max it’s in WCS.



As I said it here previously.... it is my first time playing with 3D stuff.

I downloaded your sample, ran the command OOB, and I get the two min-max points (the ones in cyan) on the solid.

Now, I am confused....  :oops:
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 02, 2008, 01:26:16 PM
I had moved the solid so I could see the points  :-o
Have a look at these two objects, they are the same size, but the min max results are different
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 02, 2008, 01:38:14 PM
I had moved the solid so I could see the points  :-o
Have a look at these two objects, they are the same size, but the min max results are different

Daniel,

I think I understand what you are saying :)

Maybe I did not explain myself on the min-max points the arx command is extracting.

I'll try again.-

For now the function returns two points on the solid let's named min & max. (if you draw a line between those two points and compare it it will be the same length)

What I am doing as the next phase, is to get the two bases of the solid, base on those two points, as soon I finished, will upload the command.

Maybe I am totally wrong.... but I am having fun :)
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 02, 2008, 01:54:35 PM
You’re right, that’s what I did with my C# routine, it starts to get more complex as the solid become more complex,
for example when there are no 90* angles on the solid.   :laugh:
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 02, 2008, 02:02:09 PM
You’re right, that’s what I did with my C# routine, it starts to get more complex as the solid become more complex,
for example when there are no 90* angles on the solid.   :laugh:

Yes, and for now I do not have any intention to get into to deep.



Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 03, 2008, 10:57:37 AM
You’re right, that’s what I did with my C# routine, it starts to get more complex as the solid become more complex,
for example when there are no 90* angles on the solid.   :laugh:

I end up using the UCS command with Face option, and all the points are not shown right.

Here is the file again with the correction, still it computes just two points (rectangular faces only).

Note: WIP

PS> Cannot test your C# routine, no A2009 here...
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 03, 2008, 02:48:26 PM
You’re right, that’s what I did with my C# routine, it starts to get more complex as the solid become more complex,
for example when there are no 90* angles on the solid.   :laugh:

Dan, try something like this (pseudo code) -

Find the longest edge
get a face this edge belong to //(there are 2 choices, it doesn't matter at this stage)

// the zvec of the xfrom
vecz = edge.ep - edge.sp
vecz.normalise

// the y vec of the xform, as the face normal is perp to the face it's also perp to the edge ;)
vecy = face.normal()

// now create the x vec for the xform
vecx = vecz.crossproduct(vecy)

// if you need to xlate it as well, get the vector to the sp (start point) of the edge

vectrans = edge.sp.asVector()


Now all you need to do is build your matrices and do the work, invert them to xform back if required. The length will be bbox max.z - minz
hth


   

Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 03, 2008, 06:16:02 PM
Mick,

Have you used your pseudo code? sound very simple and straight forward.  :)


Again, the next correction or addition... still just for solids with rectangular faces.

It finds two faces (points) closed to the min and max points (min-max on solid).

Command: OOB
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 04, 2008, 02:24:47 PM
Nice work luis,

Try this one, the command it doit

Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 04, 2008, 02:32:56 PM
Looks good, but where is the bbox :)

Now, try to tested with a cone.... ( it crashes acad  :-( )
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 04, 2008, 02:39:38 PM
Looks good, but where is the bbox :)

Well my goal was to get the dimension of the solid so I just something like..

Code: [Select]
   if(pSolid.openStatus() == Acad::eOk)
    {
      if(pSolid->transformBy(matrix.inverse()) == Acad::eOk)
      {
        pSolid->getGeomExtents(extents);
        pSolid->cancel();

        AcGePoint3d pt(extents.maxPoint().x - extents.minPoint().x ,
                       extents.maxPoint().y - extents.minPoint().y ,
                       extents.maxPoint().z - extents.minPoint().z);

        pts.append(pt);
      }
    }

Now, try to tested with a cone.... ( it crashes acad  :-( )

OH CARP  :-o
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 04, 2008, 02:42:22 PM
Looks good, but where is the bbox :)

Well my goal was to get the dimension of the solid so I just something like..

Code: [Select]
   if(pSolid.openStatus() == Acad::eOk)
    {
      if(pSolid->transformBy(matrix.inverse()) == Acad::eOk)
      {
        pSolid->getGeomExtents(extents);
        pSolid->cancel();

        AcGePoint3d pt(extents.maxPoint().x - extents.minPoint().x ,
                       extents.maxPoint().y - extents.minPoint().y ,
                       extents.maxPoint().z - extents.minPoint().z);

        pts.append(pt);
      }
    }

Now, try to tested with a cone.... ( it crashes acad  :-( )

OH CARP  :-o

I know.... I was just asking :)

Again, it is looking good, Daniel.

Keep doing the good work!
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 04, 2008, 02:47:16 PM
wait...

pSolid

hmm, don't have my visual studio nor my arx sdk....

is transformBy available directly ? I forgot... I am all a mess today

AcDb3Dsolid? or you are casting as an entity?


Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 04, 2008, 04:31:41 PM
all ent's have the transformBy() method, they  inherit it from Entity (AcDbEntity). ;)
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 04, 2008, 04:39:38 PM
all ent's have the transformBy() method, they  inherit it from Entity (AcDbEntity). ;)

Gracias Mick :)


Mind is clearing now....
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 05, 2008, 10:20:45 AM
es muy bueno  :lol:
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 05, 2008, 10:23:40 AM
es muy bueno  :lol:

Let try it...

(Dan, is that you on the avatar?...)
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 05, 2008, 10:31:02 AM
(Dan, is that you on the avatar?...)

No that’s  Ted Cassidy (AKA Lurch)  as “RUK” in  "Star Trek, What Are Little Girls Made Of?" (1966)

is that you in yours?
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 05, 2008, 10:33:27 AM
es muy bueno  :lol:

Good!!!, does not crash and works just on rectangular faces solids... or cubes ones
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 05, 2008, 10:34:40 AM
(Dan, is that you on the avatar?...)

No that’s  Ted Cassidy (AKA Lurch)  as “RUK” in  "Star Trek, What Are Little Girls Made Of?" (1966)

is that you in yours?

He he... I knew.... sorry

That old guy is me. :)
Title: Re: Matrix3d and TransformBy help
Post by: Chuck Gabriel on August 05, 2008, 10:36:16 AM
That old guy is me. :)

He's lying.  That's Wolfgang Puck. :lmao:
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 05, 2008, 10:37:49 AM
es muy bueno  :lol:

Good!!!, does not crash and works just on rectangular faces solids... or cubes ones


It will process any solid that has at least two edges that are perpendicular, still working on Mick’s idea
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 05, 2008, 10:38:09 AM
That old guy is me. :)

He's lying.  That's Wolfgang Puck. :lmao:


Dang!!!!,...... I knew it....  :lmao:
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 05, 2008, 10:41:48 AM
es muy bueno  :lol:

Good!!!, does not crash and works just on rectangular faces solids... or cubes ones


It will process any solid that has at least two edges that are perpendicular, still working on Mick’s idea

I see, I ran the tests on simple and complex cubes solids.... thanks.

I will try to continue with mine....
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 05, 2008, 11:13:39 AM
Anyone have seen this:

http://www.geo.informatik.uni-bonn.de/software/geotoolkit/intro.htm
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 05, 2008, 12:10:54 PM
Anyone have seen this:

http://www.geo.informatik.uni-bonn.de/software/geotoolkit/intro.htm

Also, have a look at the samples...

http://www.geo.informatik.uni-bonn.de/software/geotoolkit/libgt/index.html
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 08, 2008, 10:06:12 AM
Hi,


Is there by any chance to upload here some 3d solid samples (complex/simple), that I can use to run tests ?


Thanks.


Below is a test to one of the solid posted here, the oriented bounding box is shown in green:
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 08, 2008, 06:40:57 PM
Try this one Luis, this is a classic case of when the wrong edge could give invalid results.

Note: the length should be perp the the I beam section.
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 08, 2008, 06:55:27 PM
This nect one's a bit contrived but we can get even stranger section cuts at times.
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 08, 2008, 06:56:02 PM
Try this one Luis, this is a classic case of when the wrong edge could give invalid results.

Note: the length should be perp the the I beam section.


This is the result...
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 08, 2008, 06:57:09 PM
If you get the next one we may have a winner :D, nice work Luis!
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 08, 2008, 07:03:30 PM
No prob's, after posting the first one I realised that the measured edge was the longest edge even though the depth of the beam was greater. The thing is, when looping through the edges it won't get the height, only the length of the beam web edge which is well short of the length, that's why I posted the second one ;)
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 08, 2008, 07:06:48 PM
No prob's, after posting the first one I realised that the measured edge was the longest edge even though the depth of the beam was greater. The thing is, when looping through the edges it won't get the height, only the length of the beam web edge which is well short of the length, that's why I posted the second one ;)


This is what I am getting:
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 08, 2008, 07:11:28 PM
That looks pretty good to me Luis, 2 thumbs up!  :kewl:

heh, just noticed my dim was in the wrong place  :roll:
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 08, 2008, 07:13:07 PM
That looks pretty good to me Luis, 2 thumbs up!  :kewl:

heh, just noticed my dim was in the wrong place  :roll:

:)
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 08, 2008, 07:35:11 PM
Hang on Luis, you're not off the hook yet :)

I just realised that both samples were in the world ucs, just doing a 'list' would've given the correct BB,
try the one attached, it has a couple of rotations added :)
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 08, 2008, 10:50:46 PM
Hang on Luis, you're not off the hook yet :)

I just realised that both samples were in the world ucs, just doing a 'list' would've given the correct BB,
try the one attached, it has a couple of rotations added :)

Have a look:
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 09, 2008, 02:07:31 AM
Very nice!

Ok. now it beg's the question, what are you basing your direction/s on? One thing I do notice off the top of my head is that the majority of edges point in the same direction, this would work with this kind of solid at least.

So, can you get the BB regardless of the current UCS and the rotation of the solid? If so, this is a great feat Luis, nice work!
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 09, 2008, 09:53:36 AM
Nice work, my routine did not get this one. What’s your secret 
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 09, 2008, 10:16:34 AM
Ok. now it beg's the question, what are you basing your direction/s on? One thing I do notice off the top of my head is that the majority of edges point in the same direction, this would work with this kind of solid at least.

I think it will required more tests and with more complex solids, and included those with rounded edges, etc.

Quote
So, can you get the BB regardless of the current UCS and the rotation of the solid? If so, this is a great feat Luis, nice work!

Per all the tests so far, looks like it does/will.
Title: Re: Matrix3d and TransformBy help
Post by: Zydenet on August 12, 2008, 09:54:44 AM
I've been following this discussion with a good bit of interest since Luis pointed it to me from another group. I too have been playing around with this but using acis data and reading the sat file. Boxes where easy to read from the sat file but I could never figure out a way to consistently read a cylindrical object. Reading pipe runs to create a BOM was what I was after. I tried your BrepTest on a cylinder and it seems to pick it up correctly as long as it's 90%%d to the wcs. The problem is when you rotate it (with the sat file). It's hard to pick up the center (points) of each circular face to get an accurate length. Gave up on this about a year ago. Just something I thought I would kick out to ya'll to see if there was a way with the path that you're going.
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 12, 2008, 11:42:14 AM
OK....

So, everyone that have participated here, it is going to their own directions/approach/etc, no?

How about, to take a single one? - it won't matter if it going to be open or close source code.

Also, can this topic be moved to the C++ forum?


Maybe?

Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 12, 2008, 11:52:22 AM
I've been following this discussion with a good bit of interest since Luis pointed it to me from another group. I too have been playing around with this but using acis data and reading the sat file. Boxes where easy to read from the sat file but I could never figure out a way to consistently read a cylindrical object. Reading pipe runs to create a BOM was what I was after. I tried your BrepTest on a cylinder and it seems to pick it up correctly as long as it's 90%%d to the wcs. The problem is when you rotate it (with the sat file). It's hard to pick up the center (points) of each circular face to get an accurate length. Gave up on this about a year ago. Just something I thought I would kick out to ya'll to see if there was a way with the path that you're going.


Welcome to the thread  :lol:
I wouldn’t expect my routing to work with anything but cuboid type solids. A normal cylinder ought to be fairly simple as there are only two points, you could either calculate the distance between the two points or use the two points to find the direction (to get a bounding box). The difficulties begin when the solid are more complex I.e. curved pipe.

BTY, have you tried Sean’s routine here in this thread
http://www.theswamp.org/index.php?topic=24045.msg291577#msg291577
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 12, 2008, 11:57:48 AM
Also, can this topic be moved to the C++ forum?

We can start a new thread in the C++ area.
                  Just so everyone is aware, solutions in any language would be welcome.
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 12, 2008, 04:50:53 PM
The problem sounds simple - get the aligned bounding box of arbitrary 3d solids to get there length (minimum, for extruded
sections say), width and height.
The theory is easy, get the direction/s of the solid, transform it to world, get the bbox and calc the LWH, then transform it back.

There's a catch though that I've yet to see a real solution too - how do you determine these directions accurately (i.e. the 'expected' xyz vectors of the solid) 'without' user interaction. The goal is to be able to iterate the drg and grab the LWH of all solids regardless of orientation to the WCS.
It can't be done with math as it fails, the parameters can change even in the same solid if someone adds another cut or similar modification.

This leaves only 2 options.

1) get the best case bounding box using math and hope it's alright, the only way to make sure it's correct is to present it to the user to decide which way is LWH (this is what MillLister does).

2) add at least one vector (for lengths only if that's all that's required) to the 3d solid at creation time. The best solution I find is to add world point xdata elements, these get transformed with the objects when copied and modified so they're pretty safe.

There's a couple of ways to do this, one would be to trap the extrusion event with a reactor and set the data relative to the current ucs. This only works if the solid's 'section' to extrude is aligned correctly to the ucs at the time though.

The other option is to create the xyz vec's in your code, the user needs to use your tools to create objects, not so bad really considering the benefits of other section data that can also be added.

Another option I thought of was creating a block lib of sections for extrusion, these polylines can have this data already attached which can be transfered to the solid using a home built 'extrusion' method or reactors. As they can be inserted at any angle the xdata is always updated.

Anyway, good luck, it's a good exercise in 3d math that's for sure!
Title: Re: Matrix3d and TransformBy help
Post by: mohnston on August 13, 2008, 05:22:45 PM
This is all way over my head but I'm interested anyway.
I happened to stumble on a webcast on the "brep" subject and I thought I would pass the link along.
http://download.autodesk.com/media/adn/ACADBrep.NETAPIWebcast_24Jun08.zip (http://download.autodesk.com/media/adn/ACADBrep.NETAPIWebcast_24Jun08.zip)

I haven't watched the webcast, mostly because I don't even know who/what "brep" is/means and why I would want to use/ignore/master/understand/kick it.
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 13, 2008, 05:30:45 PM
brep stands for 'boundary representation' and it's a library for traversing 3d solid manifolds to give you access to the vertice, edge and face data of an autocad 3d solid. You might use for highlighting a picked face or edge by the user to use for some other calcuation or part of your code.

vertices are 3d point coord's
edges are lines which contain 2 vertices and have a direction
faces have edges and a normal which dictates which way the face is pointing, generally to the outside of the solid (think of holes as a special case).
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 13, 2008, 09:21:09 PM
I couldn’t find how to get the normal from the face (through the API).

What’s interesting is that Bricscad seems to somehow store the orientation of the solid. I’m NOT sure whats going on yet but it sure is acting different than AutoCAD
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 13, 2008, 10:15:57 PM
I've only looked at the lib briefly but using an edge traverser, graba vector from each of the first 2 edges, do a cross product on them and you have the normal of the face.

Basically, the cross product of any 2 vectors gives you a vector perpendicular to the plane created by the 2 vec's. This may vary on the 'winding' of the face edges though, as I'm assuming the traverser follows the winding of the edges it should be giving you a normal pointing away from the face (to the outside of the solid).

Just had a quick peek at the doc's, you're right, no normal!? Even if you get the face's surface.
I noticed that there are point on face etc methods so it must be there somewhere, just not exposed.
I's easy enough to get though using 2 edges of the face you want.
hth
Title: Re: Matrix3d and TransformBy help
Post by: mohnston on August 14, 2008, 01:50:12 PM
Checking the properties of a "box" type solid3d there is a width, height and depth.
However when that box is modified in any way (union, subtract etc.) those values do not appear.

Another thing I noticed is that there is some solid3d dxf information that is proprietary.

3dsolid group codes
 
Group code Description
100            Subclass marker (AcDbModelerGeometry)
70              Modeler format version number (currently = 1)
1                Proprietary data (multiple lines < 255 characters each)
3                Additional lines of proprietary data (if previous group 1 string is greater than 255 characters) (optional)
100            Subclass marker (AcDb3dSolid)
350            Soft-owner ID/handle to history object

I wonder what's in the proprietary data.
Title: Re: Matrix3d and TransformBy help
Post by: MickD on August 14, 2008, 04:34:23 PM
note the history group codes, this is new to the 2007/8/9 modelers, you may be able to get to the root object (it would be the first node in the CSG tree) if it's available?? When you extrude an object you then have the arrow on the extension face that you can grip edit the solid with making it's length longer.

Just a side note, with my C# code, I get a eWasOpenForWrite error on new solids created when I try and modify them with code, turning off SOLIDHIST and using the BREP command fixes the problem which I'll have to fix (probably an upgrade open or similar).
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on August 15, 2008, 11:03:01 AM
I've only looked at the lib briefly but using an edge traverser, graba vector from each of the first 2 edges, do a cross product on them and you have the normal of the face.

Basically, the cross product of any 2 vectors gives you a vector perpendicular to the plane created by the 2 vec's. This may vary on the 'winding' of the face edges though, as I'm assuming the traverser follows the winding of the edges it should be giving you a normal pointing away from the face (to the outside of the solid).

Just had a quick peek at the doc's, you're right, no normal!? Even if you get the face's surface.
I noticed that there are point on face etc methods so it must be there somewhere, just not exposed.
I's easy enough to get though using 2 edges of the face you want.
hth

What is the best face to use, the face with the largest area?
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on August 15, 2008, 11:45:24 AM
I noticed that there are point on face etc methods

yep... there are some methods avail... but for example the containment ones, do not work...... at least for me...

I tried to move the extreme (2+) points I found aligned to the solid into a face and no luck, I will try to use the mpolygon combination.

With that I can find the face I need and calculate the direction....

A lot to play for this weekend....
Title: Re: Matrix3d and TransformBy help
Post by: mohnston on September 02, 2008, 01:23:39 PM
Thought this was relevant.

http://through-the-interface.typepad.com/through_the_interface/2008/09/traversing-a-3d.html
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on September 02, 2008, 02:11:31 PM
Thought this was relevant.

http://through-the-interface.typepad.com/through_the_interface/2008/09/traversing-a-3d.html

Thanks, that's the easy part..... :)
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on January 21, 2009, 09:38:22 PM
After more than 120 days.... here is something.-

Base on the work of Gill Barequet

Here.-
http://www.cs.technion.ac.il/~barequet/

I was able to use it inside of my ObjectARX project.

Attached it is the arx, and a drawing (a2007) - for testing.

Note:
This is a beta - debug and not full tested, so expect ERRORS.

How to use the command OBB:
Loaded in the attached drawing, call the command OBB, select a solid and the command will draw four points around the oriented bounding box, if nothing goes wrong :)

Looks, to me that have future, give it a try.


Luis.
Title: Re: Matrix3d and TransformBy help
Post by: SEANT on January 22, 2009, 04:54:12 AM
Definitely looks good on all the slab-sided solids in the drawing.

As a point of interest though; it causes a fatal crash (AutoCAD 2009) if a cylindrical object is selected.
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on January 22, 2009, 10:47:56 AM
Definitely looks good on all the slab-sided solids in the drawing.

As a point of interest though; it causes a fatal crash (AutoCAD 2009) if a cylindrical object is selected.


Yes, because when it does the traversing on the faces, it returns two points and they are colinear, that's why :)

I will continue playing with this project, and as soon became more stable, will post it in the was C++ forum - the VS SLN.

LE!
Title: Re: Matrix3d and TransformBy help
Post by: It's Alive! on January 23, 2009, 09:30:09 PM
Nice work Luis..  8-)

Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on January 29, 2009, 04:17:01 PM
Appears that this new algorithm it is working - a total new approach.   :-)

So in case someone wants to run some tests, please do it and let me know if works as expected.

For now, it will just draw two points that are the min and max at the oriented bounding box found and a line between both points.

Again, please remember that this is a debug version and might have or generate some errors.


Load the arx file and call the below command name:
Command: OBB


Note: I have not implemented the function to work with spheres, pyramids, cones.... I'm working on that, at this moment...
Thanks!
Title: Re: Matrix3d and TransformBy help
Post by: MickD on January 29, 2009, 07:29:35 PM
OBB doesn't work for me, sure it's the right command?
thanks
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on January 29, 2009, 07:38:17 PM
OBB doesn't work for me, sure it's the right command?
thanks

Hi Mick,

Let me upload the file, one more time...
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on January 29, 2009, 07:43:21 PM
OBB doesn't work for me, sure it's the right command?
thanks

Hi Mick,

Let me upload the file, one more time...

There it is now... maybe I uploaded a previous one, normally I use the command TST for all my test commands....

Thanks.
Title: Re: Matrix3d and TransformBy help
Post by: MickD on January 29, 2009, 09:04:11 PM
Sorry Luis, not quite.
I really don't see a way to do this without the solid having some knowledge of its direction or an ecs that doesn't change with any modifications.

See attached, it has a standard beam and the same beam after mod's so you can see how it should come out, hth.
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on January 29, 2009, 09:16:37 PM
Sorry Luis, not quite.
I really don't see a way to do this without the solid having some knowledge of its direction or an ecs that doesn't change with any modifications.

See attached, it has a standard beam and the same beam after mod's so you can see how it should come out, hth.

It's all right.... this has become an obsession, and some day, it will come up... others have done it, for other applications, so it is possible :)

Mick,

Can you upload the drawing sample ?

Thanks!
Title: Re: Matrix3d and TransformBy help
Post by: MickD on January 29, 2009, 09:29:02 PM
I just attached it to last post, cheers.
Title: Re: Matrix3d and TransformBy help
Post by: MickD on January 29, 2009, 09:53:26 PM
For an aligned bounding box to work it needs something to align to, that's pretty easy to handle if you have it. The problem is if you are basing your alignment of an algorythm that takes the current geometry into consideration, what happens when the geometry changes??

The only way other applications can handle this is if they embed/attach an ECS at the time of the solids creation.
I'm talking more along the lines of say timber or steel where things come in lengths, it doesn't matter how you cut it, you need 'x' amount of length of the material, this is what's important so you can order the right amounts.
With mechanical or molded items it doesn't really matter as long as they fit inside the BBox in an economic way which is what your arx seems to be able to do.
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on January 30, 2009, 12:42:38 AM
more... just to show some advanced.... I guess....  :roll:
Title: Re: Matrix3d and TransformBy help
Post by: MickD on January 30, 2009, 05:30:44 AM
Luis, that looks good,..but.... I know those solids are aligned with the the wcs (the beam extrusion follows the y axis), what if you rotated them about say two axes??

That's the BBox we want though :)
Title: Re: Matrix3d and TransformBy help
Post by: Spike Wilbury on January 30, 2009, 09:15:59 AM
Luis, that looks good,..but.... I know those solids are aligned with the the wcs (the beam extrusion follows the y axis), what if you rotated them about say two axes??

That's the BBox we want though :)

Mick,

If you had a chance, please provide me with some drawing samples - they will be better for my testings - Thanks!.

This algorithm does not depend on any axis at all (just uses points) or in other words it looks for points and does the projection, until it find the aligned bounding box (to put it in simple words) - I know it requires more refinement, but it's getting there. :)

LE!