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

Transform, explode and get Geometry of Various AEC objects

1 REPLY 1
Reply
Message 1 of 2
akolymparis
392 Views, 1 Reply

Transform, explode and get Geometry of Various AEC objects

Hello,

 

I have been making some tests while trying to retrieve some geometric data from some AEC objects coming frm Acad Architecture, such as walls, staircases, railings, windows and doors.

The user selects a bunch of objects from the scene and the process runs on those. Before getting into retrieving the actual geometry, I request from the user a new origin and attempt to transform all selected objects by that.

 

This works as expected for Walls, Staircases, Multi-View Blockreferences and, of course, normal Acad Objects.

The problem is, that it doesn't seem to work for Windows, Doors, Railings and other objects that seem to be depended on some other object (for example doors and windows are dependent on walls...?).

 

So I have this little piece of code that does the transformation for one selection:

public void TestTransform()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    BlockTable bt =
                              (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);

                    BlockTableRecord ms =
                              (BlockTableRecord)tr.GetObject(
                                bt[BlockTableRecord.ModelSpace],
                                OpenMode.ForWrite);

                    // Ask user to select entities
                    PromptEntityOptions peo = new PromptEntityOptions("");
                    peo.AllowNone = false;

                    PromptEntityResult per = ed.GetEntity(peo);
                    if (per.Status != PromptStatus.OK)
                        return;

                    //Ask for new origin
                    PromptPointOptions ppo = new PromptPointOptions("Select Origin");
                    ppo.AllowNone = false;

                    PromptPointResult ppr = ed.GetPoint(ppo);
                    Point3d origin = default(Point3d);
                    if (ppr.Status == PromptStatus.OK)
                        origin = ppr.Value;

                    Matrix3d orgTrs = Matrix3d.Identity;
                    if (origin != default(Point3d))
                    {
                        CoordinateSystem3d ucs = new CoordinateSystem3d(db.Ucsorg, db.Ucsxdir, db.Ucsydir);
                        orgTrs = Matrix3d.AlignCoordinateSystem(ucs.Origin, ucs.Xaxis, ucs.Yaxis, ucs.Zaxis,
                                                                origin, ucs.Xaxis, ucs.Yaxis, ucs.Zaxis).Inverse();
                    }

                    using (Entity e = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as Entity)
                    {
                        e.TransformBy(orgTrs);
                        e.Color = Color.FromRgb(255, 0, 0);
                    }

                    tr.Commit();
                }
                catch (System.Exception ex)
                {
                    ed.WriteMessage(ex.Message);
                }
            }
        }

When I select a wall with a window on it, the entire wall along with the window are transformed correctly.
When I select just the window nothing happens.

When later I want to retrieve the geometry, I proceed to explode the wall (which has been correctly transformed along with the window), but after the explode, while the wall retains it's shape, the window is not returned in the results.

Now, what that means for my case is that the following happens:
The user selects all walls and windows. These are returned in the selection set and each is transformed by the new origin.
The walls are transformed corrently but nothing is done to the windows.
That means that later, when I start exploding the entities to get the geometry the wall returns some faces that give me the shape of the wall, placed where they should be, but without the windows, and the windows are exploded seperately (as returned in the selection set) but are not transformed, so they are placed in their initial (pre-origin-transformation) position.

Is there a way to also get the windows (doors/etc) geometry placed correctly, or transform them correctly on their own?

 

(P.S., if instead of TransformBy I use GetTransformedCopy, then the copied object is placed correctly, but the wall then doesn't retain it's shape

Entity cp = e.GetTransformedCopy(orgTrs);
cp.Color = Color.FromRgb(255, 0, 0);

ObjectId trcopyID = ms.AppendEntity(cp);
tr.AddNewlyCreatedDBObject(cp, true);

)

1 REPLY 1
Message 2 of 2

The behavior is as expected: Locations of elements like doors and windows are expressed in terms of the walls they're anchored to, so you can't transform them independently, that requires the AEC API. 

 

If you're expecting to be able to manipulate AEC content in basic AutoCAD, you're expecting too much.

 


@akolymparis wrote:

Hello,

 

I have been making some tests while trying to retrieve some geometric data from some AEC objects coming frm Acad Architecture, such as walls, staircases, railings, windows and doors.

The user selects a bunch of objects from the scene and the process runs on those. Before getting into retrieving the actual geometry, I request from the user a new origin and attempt to transform all selected objects by that.

 

This works as expected for Walls, Staircases, Multi-View Blockreferences and, of course, normal Acad Objects.

The problem is, that it doesn't seem to work for Windows, Doors, Railings and other objects that seem to be depended on some other object (for example doors and windows are dependent on walls...?).

 

So I have this little piece of code that does the transformation for one selection:

public void TestTransform()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    BlockTable bt =
                              (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);

                    BlockTableRecord ms =
                              (BlockTableRecord)tr.GetObject(
                                bt[BlockTableRecord.ModelSpace],
                                OpenMode.ForWrite);

                    // Ask user to select entities
                    PromptEntityOptions peo = new PromptEntityOptions("");
                    peo.AllowNone = false;

                    PromptEntityResult per = ed.GetEntity(peo);
                    if (per.Status != PromptStatus.OK)
                        return;

                    //Ask for new origin
                    PromptPointOptions ppo = new PromptPointOptions("Select Origin");
                    ppo.AllowNone = false;

                    PromptPointResult ppr = ed.GetPoint(ppo);
                    Point3d origin = default(Point3d);
                    if (ppr.Status == PromptStatus.OK)
                        origin = ppr.Value;

                    Matrix3d orgTrs = Matrix3d.Identity;
                    if (origin != default(Point3d))
                    {
                        CoordinateSystem3d ucs = new CoordinateSystem3d(db.Ucsorg, db.Ucsxdir, db.Ucsydir);
                        orgTrs = Matrix3d.AlignCoordinateSystem(ucs.Origin, ucs.Xaxis, ucs.Yaxis, ucs.Zaxis,
                                                                origin, ucs.Xaxis, ucs.Yaxis, ucs.Zaxis).Inverse();
                    }

                    using (Entity e = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as Entity)
                    {
                        e.TransformBy(orgTrs);
                        e.Color = Color.FromRgb(255, 0, 0);
                    }

                    tr.Commit();
                }
                catch (System.Exception ex)
                {
                    ed.WriteMessage(ex.Message);
                }
            }
        }

When I select a wall with a window on it, the entire wall along with the window are transformed correctly.
When I select just the window nothing happens.

When later I want to retrieve the geometry, I proceed to explode the wall (which has been correctly transformed along with the window), but after the explode, while the wall retains it's shape, the window is not returned in the results.

Now, what that means for my case is that the following happens:
The user selects all walls and windows. These are returned in the selection set and each is transformed by the new origin.
The walls are transformed corrently but nothing is done to the windows.
That means that later, when I start exploding the entities to get the geometry the wall returns some faces that give me the shape of the wall, placed where they should be, but without the windows, and the windows are exploded seperately (as returned in the selection set) but are not transformed, so they are placed in their initial (pre-origin-transformation) position.

Is there a way to also get the windows (doors/etc) geometry placed correctly, or transform them correctly on their own?

 

(P.S., if instead of TransformBy I use GetTransformedCopy, then the copied object is placed correctly, but the wall then doesn't retain it's shape

Entity cp = e.GetTransformedCopy(orgTrs);
cp.Color = Color.FromRgb(255, 0, 0);

ObjectId trcopyID = ms.AppendEntity(cp);
tr.AddNewlyCreatedDBObject(cp, true);

)


 

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

Post to forums  

Forma Design Contest


AutoCAD Beta