Catch event when some PI in the alignment is dragged

Catch event when some PI in the alignment is dragged

joantopo
Mentor Mentor
2,331 Views
13 Replies
Message 1 of 14

Catch event when some PI in the alignment is dragged

joantopo
Mentor
Mentor

Hi.

I have an objectModified event and I check if the object is an Alignment object.

 

However, I need to do an exception if the user is dragging the grip of some PI of the alignment.

How could I Do this?

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
0 Likes
Accepted solutions (1)
2,332 Views
13 Replies
Replies (13)
Message 2 of 14

Civil3DReminders_com
Mentor
Mentor

I ended up keeping a list of the PI points for alignments I want to watch in memory. Then when then alignment is modified I compare it to my stored list of information. If it's changed I know the user is modifying the alignment. I think you could use  the alignment overrules, kind of like what is in this post that I think will update as the person modifies the alignment.

 

http://through-the-interface.typepad.com/through_the_interface/2009/08/gluing-a-point-to-an-autocad-...

 

Although I'm not quite certain it would work, but it's the approach I'd try first. 

Civil Reminders
http://blog.civil3dreminders.com/
http://www.CivilReminders.com/
Alumni
0 Likes
Message 3 of 14

joantopo
Mentor
Mentor

Thanks for replying Christopher.

 

Could you share your function to get the PI alignment in a list?

 

I have seen that there isn´t a class in the API. There is no AlignmentPI class, whereas there is ProfilePVI...

 

 

I read this post to get the PI with IntersectionWith( ) method creating 2 lines on the line entities:

http://adndevblog.typepad.com/infrastructure/2012/08/using-overrule-with-civil-3d-entities.html

 

But then, if you have 2 consecutive arcs (in opposite direction "S") ,how you get the PI or  how you consider that scenario?

 

My issue is that I don´t need to check if a PI is dragged, only those PI which are the closed to a selected fixed entity in my alignment. (And there is not for all alignments in the drawing).

 

 

I have the objectModified event, which I get an ObjectIdcollection (global var) of all alignments modified. 

When that event ends up, then it is fired EnteringQuiescentState event to check every alignment in the ObjectIdCollection.

 

However, that error is thrown when ObjectModified event ends up and before this last event.

 

I wish, Civil 3D had "lock" property for PI..

 

 

 

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
0 Likes
Message 4 of 14

joantopo
Mentor
Mentor

There is another issue.

 

if you move all the alignment object to another location. I have no issue in my app right now.

If you do that, the coodinates (x,y) of every PI are changing and the app will consider the user is dragging a PI Intersection point.

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
0 Likes
Message 5 of 14

joantopo
Mentor
Mentor

I think what is the issue.

 

If I have a fixed tangent + free curve + fixed tangent and my app always establish new coordinates (Through pass point 1 and through pass point 2) for the first fixedn entity, if I drag the PI to a new location, second point of the fixed entity never can be out of the fixed line, I mean, the PI can´t be a "Solve PI".

 

To solve this, if I have to check the entity type after my fixed entity, if it was a free or floating (from entity) entity. In that case, P2 location must be the same coordinates that PI.

 

If it is the revers scenario: P1 point must be the same coordinates that PI (in case the previous entity was a free or floating entity (from entity).

 

 

This is the "solve PI":

https://knowledge.autodesk.com/support/autocad-civil-3d/learn-explore/caas/CloudHelp/cloudhelp/2017/...

 

 

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
0 Likes
Message 6 of 14

Civil3DReminders_com
Mentor
Mentor

I can't find my code. 

 

I'm fairly certain I went through the AlignmentEntities and found out what type it was. If the segment was an AlignmentArc (or if I used sprials one of the ones with spirals) and the used the StartDirection and ExternalTangent to find the PI point. This way it doesn't matter if there is an actual tangent between curves. 

Civil Reminders
http://blog.civil3dreminders.com/
http://www.CivilReminders.com/
Alumni
0 Likes
Message 7 of 14

joantopo
Mentor
Mentor

Yes, I was thinking in the "External tangent" property. The most of cases I think it would work, but, if you have an entity such as "CurveCurveReverseCurve", then I  think that it is not valid the "external tangent", because you would have several external tangents in the same entity.

 

 

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
0 Likes
Message 8 of 14

Civil3DReminders_com
Mentor
Mentor

Each arc in that situation has their own properties with the corresponding external tangent, as shown below.

 

The pain becomes grabbing the entities and then processing them with a switch based on the type of entity and then processing each one. 

 

Arcs.png

Civil Reminders
http://blog.civil3dreminders.com/
http://www.CivilReminders.com/
Alumni
0 Likes
Message 9 of 14

joantopo
Mentor
Mentor

Exactly, there is a pain. There´s a lot of Alignment Entity types..

 

 

I have found this:

Alignment.GetStationSet Method (StationTypes, Double)

 

Where there is StationType= PIPoint

 

https://forums.autodesk.com/t5/autocad-civil-3d-customization/alignment-pi-and-or-tangent-intersecti...

 

but anyway, I don´t think we can get the PI point (coordinates, not station).

 

 

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
0 Likes
Message 10 of 14

joantopo
Mentor
Mentor

I have a question.

 

If we have A SCS entity, the PI of the arc (AlignmentEntity[1] ) would be the same that some PI in the alignment?

 

 

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
0 Likes
Message 11 of 14

joantopo
Mentor
Mentor

Ok, PI of the arc is about "PI" of the arc, not the PI SCS entity.

 

I am thinking in another workaround:

 

Get the PIpoints collection of the alignment.

 

Create a AutoCAD "auxiliary line" from the fixed tangent. Check if that point is on that "auxiliary line" . GetClosed() method.

 

 

 

 

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
0 Likes
Message 12 of 14

christopher
Enthusiast
Enthusiast

The PI of the curve in a SCS is not the same as the SCS PI point you are looking for. 

 

I'd take the known inputs and solve the spiral formulas for the information that I'm looking for. 

 

Here is one Imperial source of the formulas: http://www.iowadot.gov/design/dmanual/02c-01.pdf

0 Likes
Message 13 of 14

joantopo
Mentor
Mentor

I will do another workaround:

 

There is the class:   Alignment.GetStationSet Method (StationTypes)

 

  Autodesk.Civil.DatabaseServices.Alignment align = default(Autodesk.Civil.DatabaseServices.Alignment);
                    align = trans.GetObject(idAL1, OpenMode.ForWrite) as Alignment;
                  
                  Station[] myStations = align.GetStationSet(StationTypes.PIPoint); //obtenemos todos los PI del eje.
                 

                    foreach (Station myStation in myStations)
                  {
                      Point2d PuntoInt = myStation.Location;
                  }

                List<Station> ListStations = myStations.ToList();

StationTypes= PIPoint

Which returns all PI stations of the alignment in an array.

 

I can loop this array to find out the previous PI before the start station of my fixed tangent.

The same to get the after PI  after the end station of my fixed tangent.

 

Once I have the PI station, I can get the  PI point looking for the "findIndex" in the List about that station, and finally "myStation.Location" which will be the PI point.

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
0 Likes
Message 14 of 14

joantopo
Mentor
Mentor
Accepted solution

If you have Fixed tangents defined by pass-through points, you can put them (pass-through points) on the PI to avoid "Solve PI", but you have to do this for each "fixed tangent" in the alignment.

Previous fixed tangent (the second pass-through point on the after PI location)

Next fixed tangent (the first pass-through point on the previous PI location)  🙂

 

I check first, if before or after the fixed tangent there is actually an entity.

 

This snippet code works:

 

  using (DocumentLock docLock = acDoc.LockDocument())
            {
                using (Transaction trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
                {
                    Autodesk.Civil.DatabaseServices.Alignment align = default(Autodesk.Civil.DatabaseServices.Alignment);
                    align = trans.GetObject(idAL1, OpenMode.ForWrite) as Alignment;
                    Autodesk.Civil.DatabaseServices.AlignmentEntityCollection entidadesPrimarias = align.Entities;
                    AlignmentEntity entitatFija = entidadesPrimarias.EntityAtId(Id_entidadFija);
                    AlignmentEntityType tipo = entitatFija.EntityType;  //si es una recta o curva fija.


                  Station[] myStations = align.GetStationSet(StationTypes.PIPoint); //obtenemos todos los PI del eje.


                  foreach (Station myStation in myStations)
                  {
                      Point2d PuntoInt = myStation.Location;
                  }

                  List<Station> List_PIStations = myStations.ToList();
              
                    #region LINE
                    if (tipo == AlignmentEntityType.Line)
                    {
                        Autodesk.Civil.DatabaseServices.AlignmentLine linea = (Autodesk.Civil.DatabaseServices.AlignmentLine)entitatFija;
                        if (linea.Constraint2 == AlignmentLineConstraintType.TwoPoints)
                        {
    
                                AlignmentEntity entidad_Previa = null;
                                try
                                { 
                                 int id_entidadPrevia= entitatFija.EntityBefore;
                                 entidad_Previa= entidadesPrimarias.EntityAtId(id_entidadPrevia);
                                }
                                catch{}

                                AlignmentEntity entidad_Posterior = null;
                                try
                                {
                                  int id_entidadPosterior= entitatFija.EntityAfter;
                                   entidad_Posterior= entidadesPrimarias.EntityAtId(id_entidadPosterior);
                                }
                                catch{}


                              
                                   
                                    if (entidad_Previa != null && entidad_Previa.Constraint1 == AlignmentEntityConstraintType.Free) //PREVIOUS ENTITY
                                    {

                                        double StartStation_FixedTangent = entitatFija[0].StartStation;

                                     int pos=  List_PIStations.FindLastIndex(x => x.RawStation <= StartStation_FixedTangent);

                                     try
                                     {
                                         linea.PassThroughPoint1 = List_PIStations[pos].Location;
                                     }
                                     catch { }
                                        
                                    }
                            


                       
                                    if (entidad_Posterior != null && entidad_Posterior.Constraint1 == AlignmentEntityConstraintType.Free) //AFTER ENTITY
                                    {

                                        double EndStation_Fixed = entitatFija[0].EndStation;
                                     
                                      int pos = List_PIStations.FindIndex(x => x.RawStation >= EndStation_Fixed);

                                      try
                                      {
                                          linea.PassThroughPoint2 = List_PIStations[pos].Location;
                                      }
                                      catch { }
                                    }
                            

                        }
                    }
                    #endregion
                }
            }
            #endregion

 

 

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
0 Likes