want to rotate structures with pipe network

want to rotate structures with pipe network

goswami12897
Enthusiast Enthusiast
1,126 Views
19 Replies
Message 1 of 20

want to rotate structures with pipe network

goswami12897
Enthusiast
Enthusiast

Hello I am developing small tool so I can swap multiple structural members at once but I want to align the replacing parts along with the direction of pipe too please can anyone help me how can I do that the code is below

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using Autodesk.Civil.DatabaseServices.Styles;
using System;

[assembly: CommandClass(typeof(SwapParts.Swap))]
namespace SwapParts
{
    public class Swap
    {
        [CommandMethod("SwapAllParts")]
        public void SwapParts()
        {
            Document document = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
            Database database = document.Database;
            Editor editor = document.Editor;

            editor.WriteMessage("\n Select the structures to replace");

            PromptSelectionResult solidSelected = editor.GetSelection();
            if (solidSelected.Status != PromptStatus.OK)
            {
                editor.WriteMessage("\n Selected wrong Objects. Please restart the command to try again");
                return;
            }
            SelectionSet set = solidSelected.Value;
            using (Transaction transaction = database.TransactionManager.StartTransaction())
            {

                CivilDocument cDoc = CivilApplication.ActiveDocument;
                PartsListCollection partsListCollection = cDoc.Styles.PartsListSet;
                foreach (ObjectId part in partsListCollection)
                {
                    PartsList partsList = transaction.GetObject(part, OpenMode.ForRead) as PartsList;
                    {
                        editor.WriteMessage($"\nPARTS LISTS: {partsList.Name}");
                    }
                }
                    PromptStringOptions partsListName = new PromptStringOptions("\nSelect the Parts List from which you want to insert the new part")
                    {
                        AllowSpaces = true,
                    };
                    PromptResult partlistName1 = editor.GetString(partsListName);
                    string partsListName2 = partlistName1.StringResult;
                    ObjectId PartsList1 = cDoc.Styles.PartsListSet[partsListName2];
                    PartsList partsList2 = transaction.GetObject(PartsList1, OpenMode.ForWrite) as PartsList;
                    ObjectIdCollection partFamilyCollection = partsList2.GetPartFamilyIdsByDomain(DomainType.Structure);
                    foreach (ObjectId partStr in partFamilyCollection)
                    {
                        PartFamily partFamily1 = transaction.GetObject(partStr, OpenMode.ForWrite) as PartFamily;
                        if (partFamily1.Domain == DomainType.Structure)
                        {
                         editor.WriteMessage($"\nStructures: {partFamily1.Name}");
                        }
                    } 
                PromptStringOptions partFamilyName = new PromptStringOptions("\nSelect the structure you want to swap these structures with")
                {
                    AllowSpaces = true,
                };
                PromptResult partFamilySwapping = editor.GetString(partFamilyName);
                string swapper = partFamilySwapping.StringResult;
                ObjectId structureId = partsList2[swapper];
                Structure structure = transaction.GetObject(structureId, OpenMode.ForWrite) as Structure;
                PartFamily str1 = transaction.GetObject(structureId, OpenMode.ForWrite) as PartFamily;
                ObjectId psizestr = str1[0];
                

                foreach (SelectedObject obj in set)
                {
                    if (obj.ObjectId.ObjectClass.DxfName.Contains("STRUCTURE"))
                    {
                        Structure str = transaction.GetObject(obj.ObjectId, OpenMode.ForRead) as Structure;
                        str.SwapPartFamilyAndSize(structureId, psizestr);
                        string[] pipeNames = str.GetConnectedPipeNames();
                        if (pipeNames.Length > 1)
                        {
                            ObjectId pipedId = str.get_ConnectedPipe(1);
                            Pipe pipe = transaction.GetObject(pipedId, OpenMode.ForRead) as Pipe;
                            
                        }
                        else
                        {
                            ObjectId pipedId = str.get_ConnectedPipe(0);
                            Pipe pipe = transaction.GetObject(pipedId, OpenMode.ForRead) as Pipe;
                            
                        }


                    }
                }
                transaction.Commit();
            }
        }
    }
}

the part where the if else statement begins I tried to get angle the replacement tool works fine but unable to understand how to rotate the structures to align with pipe please help. 

0 Likes
Accepted solutions (1)
1,127 Views
19 Replies
Replies (19)
Message 2 of 20

norman.yuan
Mentor
Mentor

Structure.Rotation property (read/write)? You just need to determine the rotation angle based on the connected pipe(s)

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 20

goswami12897
Enthusiast
Enthusiast

exactly to what should I equate it to that's my doubt that it automatically takes direction of pipe

0 Likes
Message 4 of 20

goswami12897
Enthusiast
Enthusiast

I tried this but it is throwing the violation error and civil3d closes down please help me to rectify errors

 if (obj.ObjectId.ObjectClass.DxfName.Contains("STRUCTURE"))
                    {
                        Structure str = transaction.GetObject(obj.ObjectId, OpenMode.ForRead) as Structure;
                        str.SwapPartFamilyAndSize(structureId, psizestr);
                        string[] pipeNames = str.GetConnectedPipeNames();
                        if (pipeNames.Length > 1)
                        {
                            ObjectId pipedId = str.get_ConnectedPipe(1);
                            Pipe pipe = transaction.GetObject(pipedId, OpenMode.ForRead) as Pipe;
                            Point3d pt1 = pipe.StartPoint;
                            Point3d pt2 = pipe.EndPoint;
                            double angle = Vector3d.XAxis.GetAngleTo(pt2 - pt1);
                            structure.Rotation = angle;
                        }
                        else
                        { 
                            ObjectId pipedId = str.get_ConnectedPipe(0);
                            Pipe pipe = transaction.GetObject(pipedId, OpenMode.ForRead) as Pipe;
                            Point3d pt1 = pipe.StartPoint;
                            Point3d pt2 = pipe.EndPoint;
                            double angle = Vector3d.XAxis.GetAngleTo(pt2 - pt1);
                            structure.Rotation = angle;
                        }
                       
                    }
0 Likes
Message 5 of 20

hosneyalaa
Advisor
Advisor

@goswami12897 

Can you attached example drawing

0 Likes
Message 6 of 20

goswami12897
Enthusiast
Enthusiast

Screenshot 2024-01-15 173336.pngScreenshot 2024-01-15 173233.pngLike here when I swapped null structure with the rectangular slab I want that slab to be aligned with the pipe following it basically in it's direction, I commented out the part that was causing violation and this much happened now I want to rotate the part too to align it with pipe following it and if it's the last pipe I want it to be aligned with the pipe preceding it

0 Likes
Message 7 of 20

goswami12897
Enthusiast
Enthusiast

basically all parts are coming in horizontal rotation ie 0 degees but I want them to be following the pipe rotation

 

0 Likes
Message 8 of 20

norman.yuan
Mentor
Mentor

Your code is a bit of confusing:

 

In the "if..." condition, you test "obj" is a Structure or not. If yes, you open it for READ, and assign it as variable "str" for calculating rotation. Then you set the rotation angle to another structure pointer "structure", which is declare outside the code scope you showed: it is the same Structure as the variable "str" points to? was it opened for write?

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 9 of 20

goswami12897
Enthusiast
Enthusiast

one str is the structure that usee selected on screen, structure is fhe structure that is made on screen that swaps str

0 Likes
Message 10 of 20

norman.yuan
Mentor
Mentor

I do not understand your answer: shouldn't 2 structure variables point to the same structure (you only want to parsize to a different partsize (e.g the structure position is unchanged).

 

Also

str.SwapPartFamilyAndSize(structureId, psizestr);

 

What is the "structureId" in the SwapPartFamilyAndSize() call? Is it a partFamily's ObjectId? If yes, you have bad variable naming habit; if not (e.g., if it is a structure's ObjectId, as the variable name implies), that is one possible reason you get crash.

 

You should post more code to make sure how all variables are declared and objects are instantiated. Otherwise, I can only guess based on "common-sense" of variable names.

 

 

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 11 of 20

goswami12897
Enthusiast
Enthusiast

so copy that code and comment out the line where Structure class variable was introduced, run it in civil3d it will throw an error that the objectid should be from structure class based on the commonsense I see. As I have already stated parts are getting swapped successfully I need help regarding rotation of the members, thank you.

0 Likes
Message 12 of 20

goswami12897
Enthusiast
Enthusiast

Whenever you put an objectid, you need to allocate the class as well right otherwise which objectid it is?

 

0 Likes
Message 13 of 20

hosneyalaa
Advisor
Advisor

@goswami12897 

You do not need to the rotate , He takes it from the manhole before

 

 

7.gif

0 Likes
Message 14 of 20

goswami12897
Enthusiast
Enthusiast

Yes that's true but some parts in the network are at  0 degree rotation from horizontal so have to get the rotation according to the pipe inlet

0 Likes
Message 15 of 20

goswami12897
Enthusiast
Enthusiast

@hosneyalaa is there any way we can get objectid's of the pipes connected to a structure or vice versa?

 

0 Likes
Message 16 of 20

hosneyalaa
Advisor
Advisor

00.JPG

0 Likes
Message 17 of 20

goswami12897
Enthusiast
Enthusiast

Hey the parts are successfully rotating now but when our angle of pipe in downwards in civil3D the rotation is not matching the pipe, can you tell me what could be done other then that it is spot on.

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Internal;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using Autodesk.Civil.DatabaseServices.Styles;
using System;
using System.Linq;

[assembly: CommandClass(typeof(SwapParts.Swap))]
namespace SwapParts
{
    public class Swap
    {
        [CommandMethod("SwapAllParts")]
        public void SwapParts()
        {
            Document document = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
            Database database = document.Database;
            Editor editor = document.Editor;

            editor.WriteMessage("\n Select the structures to replace");

            PromptSelectionResult solidSelected = editor.GetSelection();
            if (solidSelected.Status != PromptStatus.OK)
            {
                editor.WriteMessage("\n Selected wrong Objects. Please restart the command to try again");
                return;
            }
            SelectionSet set = solidSelected.Value;
            using (Transaction transaction = database.TransactionManager.StartTransaction())
            {

                CivilDocument cDoc = CivilApplication.ActiveDocument;
                PartsListCollection partsListCollection = cDoc.Styles.PartsListSet;
                foreach (ObjectId part in partsListCollection)
                {
                    PartsList partsList = transaction.GetObject(part, OpenMode.ForRead) as PartsList;
                    {
                        editor.WriteMessage($"\nPARTS LISTS: {partsList.Name}");
                    }
                }
                    PromptStringOptions partsListName = new PromptStringOptions("\nSelect the Parts List from which you want to insert the new part")
                    {
                        AllowSpaces = true,
                    };
                    PromptResult partlistName1 = editor.GetString(partsListName);
                    string partsListName2 = partlistName1.StringResult;
                    ObjectId PartsList1 = cDoc.Styles.PartsListSet[partsListName2];
                    PartsList partsList2 = transaction.GetObject(PartsList1, OpenMode.ForWrite) as PartsList;
                    ObjectIdCollection partFamilyCollection = partsList2.GetPartFamilyIdsByDomain(DomainType.Structure);
                    foreach (ObjectId partStr in partFamilyCollection)
                    {
                        PartFamily partFamily1 = transaction.GetObject(partStr, OpenMode.ForWrite) as PartFamily;
                        if (partFamily1.Domain == DomainType.Structure)
                        {
                         editor.WriteMessage($"\nStructures: {partFamily1.Name}");
                        }
                    } 
                PromptStringOptions partFamilyName = new PromptStringOptions("\nSelect the structure you want to swap these structures with")
                {
                    AllowSpaces = true,
                };
                PromptResult partFamilySwapping = editor.GetString(partFamilyName);
                string swapper = partFamilySwapping.StringResult;
                ObjectId structureId = partsList2[swapper];
                Structure structure = transaction.GetObject(structureId, OpenMode.ForWrite) as Structure;
                PartFamily str1 = transaction.GetObject(structureId, OpenMode.ForWrite) as PartFamily;
                ObjectId psizestr = str1[0];
                

                foreach (SelectedObject obj in set)
                {
                    if (obj.ObjectId.ObjectClass.DxfName.Contains("STRUCTURE"))
                    {
                        Structure str = transaction.GetObject(obj.ObjectId, OpenMode.ForWrite) as Structure;
                        
                            string[] pipeNames = str.GetConnectedPipeNames();
                            foreach (string count in pipeNames)
                            {
                                editor.WriteMessage($"\n{count} ");
                            }




                        if (pipeNames.Length > 1)
                        {
                            try
                            {
                                ObjectId pipeId = str.get_ConnectedPipe(1);
                                Pipe pipe = transaction.GetObject(pipeId, OpenMode.ForRead) as Pipe;
                                Point3d pt1 = pipe.StartPoint;
                                Point3d pt2 = pipe.EndPoint;
                                double angle = Vector3d.XAxis.GetAngleTo(pt2-pt1);
                                str.Rotation = angle;
                                editor.WriteMessage($"\n 2 pipes connected angle of Rotation : {angle:N3}");
                            }
                            catch (System.Exception exx)
                            {
                                editor.WriteMessage($"\n {exx}");
                            }

                        }
                        else
                        {
                            try
                            {
                                ObjectId pipedId = str.get_ConnectedPipe(0);
                                Pipe pipe = transaction.GetObject(pipedId, OpenMode.ForRead) as Pipe;
                                Point3d pt1 = pipe.StartPoint;
                                Point3d pt2 = pipe.EndPoint;
                                double angle = Vector3d.XAxis.GetAngleTo(pt2 - pt1);
                                str.Rotation = angle;
                                editor.WriteMessage($"\n 1 pipe connected angle of Rotation : {angle:N3}");
                            }
                            catch (System.Exception ex)
                            {
                                editor.WriteMessage($"{ex}");
                            }
                        }
                        
                        str.SwapPartFamilyAndSize(structureId, psizestr);

                    }
                }
                transaction.Commit();
            }
        }
    }
}

like in these attached Screenshots if the pipes are coming in V shape it is fine but when opposite it is having error please check just some geometric correction required. Screenshot 2024-01-24 145152.png

0 Likes
Message 18 of 20

goswami12897
Enthusiast
Enthusiast

Screenshot 2024-01-24 145208.pngScreenshot 2024-01-24 145152.png

0 Likes
Message 19 of 20

hosneyalaa
Advisor
Advisor
Accepted solution

TRY

foreach (SelectedObject obj in set)
                {
                    if (obj.ObjectId.ObjectClass.DxfName.Contains("STRUCTURE"))
                    {
                        Structure str = transaction.GetObject(obj.ObjectId, OpenMode.ForRead) as Structure;
                        str.SwapPartFamilyAndSize(structureId, psizestr);

                        string[] pipeNames = str.GetConnectedPipeNames();
                        if (pipeNames.Length > 1)
                        {
                            ObjectId pipedId = str.get_ConnectedPipe(1);
                            Pipe pipe = transaction.GetObject(pipedId, OpenMode.ForRead) as Pipe;
                            Point3d pt1 = pipe.StartPoint;
                            Point3d pt2 = pipe.EndPoint;
                            //double angle = Vector3d.XAxis.GetAngleTo(pt2 - pt1);
                            double angle = Vector3d.XAxis.GetAngleTo(pt1.GetVectorTo(pt2), Vector3d.ZAxis);
                            str.Rotation = angle;

                        }
                        else
                        {
                            ObjectId pipedId = str.get_ConnectedPipe(0);
                            Pipe pipe = transaction.GetObject(pipedId, OpenMode.ForRead) as Pipe;
                            Point3d pt1 = pipe.StartPoint;
                            Point3d pt2 = pipe.EndPoint;
                            //double angle = Vector3d.XAxis.GetAngleTo(pt2 - pt1);
                            double angle = Vector3d.XAxis.GetAngleTo(pt1.GetVectorTo(pt2), Vector3d.ZAxis);
                            str.Rotation = angle;

                        }


                    }
                }
Message 20 of 20

goswami12897
Enthusiast
Enthusiast

Thank you, it's working just flawless 💓

0 Likes