Hello guys,
I'm trying to get and then to write the surface section points but I having some problems here.
My section line don't cross a surface entirely but the section points collection returns some strange data where it should be null.
In the picture bellow I show a surface profile where there is no data between -200 and -175 and also there is no data between -90 and 50. The problem is my code returns section points where locations are placed at this no data space (for example these points: [0.00,7.60] [4.56,8.06] [241.84,8.65] [250.00,8.70]).
Code:
Private Sub TEMP() 'Selecionando DOC do Civil 3D Dim civilDoc As CivilDocument = CivilApplication.ActiveDocument Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim oDBase As Database = acDoc.Database 'Listando alinhamentos no arquivo Dim alignColl As ObjectIdCollection = civilDoc.GetAlignmentIds() Dim oTrans As Transaction = oDBase.TransactionManager.StartTransaction() Using (oTrans) Try 'Selecionando cada alinhamento For Each oAlignmentId As ObjectId In alignColl 'for each alignment Dim oAlignment As Alignment = oTrans.GetObject(oAlignmentId, OpenMode.ForRead) 'selecionando cada sample line groups If oAlignment.GetSampleLineGroupIds.Count > 0 Then For Each oSampleLineGroupId In oAlignment.GetSampleLineGroupIds Dim oSampleLineGroup As SampleLineGroup = oTrans.GetObject(oSampleLineGroupId, OpenMode.ForRead) 'selecionando cada sample line do sample group For Each oSampleLineId As ObjectId In oSampleLineGroup.GetSampleLineIds Dim oSampleLine As SampleLine = oTrans.GetObject(oSampleLineId, OpenMode.ForRead) 'selecionando cada section do sampleline For Each oSectionID As ObjectId In oSampleLine.GetSectionIds Dim oSection As Autodesk.Civil.DatabaseServices.Section = oTrans.GetObject(oSectionID, OpenMode.ForRead) Dim oSectionPoints As SectionPointCollection = oSection.SectionPoints Next Next oSampleLineId Next oSampleLineGroupId End If Next oAlignmentId Catch ex As Exception MsgBox(ex.ToString) End Try End Using End Sub
I am sending also the dwg file and the excel file with the results.
What am I doing wrong?
Thank you,
Hello guys,
I'm trying to get and then to write the surface section points but I having some problems here.
My section line don't cross a surface entirely but the section points collection returns some strange data where it should be null.
In the picture bellow I show a surface profile where there is no data between -200 and -175 and also there is no data between -90 and 50. The problem is my code returns section points where locations are placed at this no data space (for example these points: [0.00,7.60] [4.56,8.06] [241.84,8.65] [250.00,8.70]).
Code:
Private Sub TEMP() 'Selecionando DOC do Civil 3D Dim civilDoc As CivilDocument = CivilApplication.ActiveDocument Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim oDBase As Database = acDoc.Database 'Listando alinhamentos no arquivo Dim alignColl As ObjectIdCollection = civilDoc.GetAlignmentIds() Dim oTrans As Transaction = oDBase.TransactionManager.StartTransaction() Using (oTrans) Try 'Selecionando cada alinhamento For Each oAlignmentId As ObjectId In alignColl 'for each alignment Dim oAlignment As Alignment = oTrans.GetObject(oAlignmentId, OpenMode.ForRead) 'selecionando cada sample line groups If oAlignment.GetSampleLineGroupIds.Count > 0 Then For Each oSampleLineGroupId In oAlignment.GetSampleLineGroupIds Dim oSampleLineGroup As SampleLineGroup = oTrans.GetObject(oSampleLineGroupId, OpenMode.ForRead) 'selecionando cada sample line do sample group For Each oSampleLineId As ObjectId In oSampleLineGroup.GetSampleLineIds Dim oSampleLine As SampleLine = oTrans.GetObject(oSampleLineId, OpenMode.ForRead) 'selecionando cada section do sampleline For Each oSectionID As ObjectId In oSampleLine.GetSectionIds Dim oSection As Autodesk.Civil.DatabaseServices.Section = oTrans.GetObject(oSectionID, OpenMode.ForRead) Dim oSectionPoints As SectionPointCollection = oSection.SectionPoints Next Next oSampleLineId Next oSampleLineGroupId End If Next oAlignmentId Catch ex As Exception MsgBox(ex.ToString) End Try End Using End Sub
I am sending also the dwg file and the excel file with the results.
What am I doing wrong?
Thank you,
This was brought up in another thread but I can't be bothered to look for it. Basically you have to weed out the points that occur outside of the LeftOffset and RightOffset. This is a simple C# method I used to return valid points (no guarantees that it will work in all situations, you can probably neaten the code up with some linq too):
private IEnumerable<SectionPoint> GetValidSectionPoints( Section section ) { var valid = new HashSet<SectionPoint>(); foreach ( var sp in section.SectionPoints ) { try { if ( sp.Location.X >= section.LeftOffset && sp.Location.X <= section.RightOffset ) { valid.Add( sp ); } } catch {} } return valid; }
I don't recall why the try catch is needed here, you may have to debug it to see if it ever catches anything.
This was brought up in another thread but I can't be bothered to look for it. Basically you have to weed out the points that occur outside of the LeftOffset and RightOffset. This is a simple C# method I used to return valid points (no guarantees that it will work in all situations, you can probably neaten the code up with some linq too):
private IEnumerable<SectionPoint> GetValidSectionPoints( Section section ) { var valid = new HashSet<SectionPoint>(); foreach ( var sp in section.SectionPoints ) { try { if ( sp.Location.X >= section.LeftOffset && sp.Location.X <= section.RightOffset ) { valid.Add( sp ); } } catch {} } return valid; }
I don't recall why the try catch is needed here, you may have to debug it to see if it ever catches anything.
I brought this up for the COM API a few years ago. I found, then, that the .NET API also showed the same issue. I ended up with a similar solution what @tyronebk showed. It also shows that this issue occurs with all section, not just surface or corridor.
I brought this up for the COM API a few years ago. I found, then, that the .NET API also showed the same issue. I ended up with a similar solution what @tyronebk showed. It also shows that this issue occurs with all section, not just surface or corridor.
Thank you guys,
Should this code work when I am in this situation?
I'll try to use it today at home. I must understand how leftoffset and rightoffset works because I have a void between them...
Thanks again,
Thank you guys,
Should this code work when I am in this situation?
I'll try to use it today at home. I must understand how leftoffset and rightoffset works because I have a void between them...
Thanks again,
Hi.
Have a look to this post:
Exactly.Be careful when you get the sectionPoint collection.
I did some methods to filter the collection and check if a sectionpoint really is on the surface section such as:
Checking if a sectionpoint, converted in x, y coordinates, has an elevation with the surface class: surface.GetElevationAtXY( )
Or you can get the border of the surface and convert to a mpolygon to check if the point ×, y in plan is inside the mpolygon.
Hi.
Have a look to this post:
Exactly.Be careful when you get the sectionPoint collection.
I did some methods to filter the collection and check if a sectionpoint really is on the surface section such as:
Checking if a sectionpoint, converted in x, y coordinates, has an elevation with the surface class: surface.GetElevationAtXY( )
Or you can get the border of the surface and convert to a mpolygon to check if the point ×, y in plan is inside the mpolygon.
Thank you @joantopo,
I am doing the same here. Checking surface correspondent data with GetElevationAtXY() at every section point.
This should be improved in API core. I'm working with many and long samplelines, and very triangulated surface (with gives me many section points)... it can be very time consuming 😕
I didn't have considered to check point x surface boundaries and it should be faster (once saving it as a list of coordinates, not using API, analyzing by math). I'll try later.
Thanks,
Thank you @joantopo,
I am doing the same here. Checking surface correspondent data with GetElevationAtXY() at every section point.
This should be improved in API core. I'm working with many and long samplelines, and very triangulated surface (with gives me many section points)... it can be very time consuming 😕
I didn't have considered to check point x surface boundaries and it should be faster (once saving it as a list of coordinates, not using API, analyzing by math). I'll try later.
Thanks,
Hi diegoal.
Look at the response of Rogersame in this post.
http://forums.augi.com/showthread.php?100954-Como-crear-reporte-de-secciones
We can extract this data from the XML file using an editor.
Regards.
Hi diegoal.
Look at the response of Rogersame in this post.
http://forums.augi.com/showthread.php?100954-Como-crear-reporte-de-secciones
We can extract this data from the XML file using an editor.
Regards.
I forgot to post this at the time, but I think I found a solution to this working with the COM API methods and properties. I have no idea if it's faster or slower than checking the points against the surface, but I thought I'd share it. I will admit that I don't fully understand when each of the SectionLinkType enums are used, but so far it has worked for my needs. Please offer improvements.
public static class Extensions_Section { public static IEnumerable<SectionPoint> GetValidSectionPoints( this Section section ) { var valid = new HashSet<Point3d>(); dynamic comSec = section.AcadObject; // AeccSection dynamic comLinks = comSec.Links; // AeccSectionLinks for ( int i = 0; i < comLinks.Count; i++ ) { dynamic comLink = comLinks.Item( i ); // AeccSectionLink if ( comLink.Type != 1 ) { valid.Add( new Point3d( comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ ) ); valid.Add( new Point3d( comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ ) ); } } return ( from sp in section.SectionPoints where valid.Contains( sp.Location ) select sp ); } public static IEnumerable<Section.SectionLink> GetSectionLinks( this Section section ) { dynamic comSec = section.AcadObject; // AeccSection dynamic comLinks = comSec.Links; // AeccSectionLinks for ( int i = 0; i < comLinks.Count; i++ ) { dynamic comLink = comLinks.Item( i ); // AeccSectionLink var start = ( from sp in section.SectionPoints where sp.Location.IsEqualTo( new Point3d( comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ ) ) select sp ).First(); var end = ( from sp in section.SectionPoints where sp.Location.IsEqualTo( new Point3d( comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ ) ) select sp ).First(); if ( start != null && end != null ) { yield return new Section.SectionLink( start, end, i, comLink.Type ); } } } public static IEnumerable<Section.SectionLink> GetValidSectionLinks( this Section section ) { return ( from sl in section.GetSectionLinks() where sl.Type != SectionLinkType.NoDraw select sl ); } } public static partial class Section { public class SectionLink { public SectionPoint StartPoint; public SectionPoint EndPoint; public readonly int Index; public readonly SectionLinkType Type; public SectionLink( SectionPoint startPoint, SectionPoint endPoint, int index, SectionLinkType type ) { StartPoint = startPoint; EndPoint = endPoint; Index = index; Type = type; } } } public enum SectionLinkType { None = 0, // aeccSectionLinkNone NoDraw = 1, // aeccSectionLinkNoDraw All = 2 // aeccSectionLinkAll }
I forgot to post this at the time, but I think I found a solution to this working with the COM API methods and properties. I have no idea if it's faster or slower than checking the points against the surface, but I thought I'd share it. I will admit that I don't fully understand when each of the SectionLinkType enums are used, but so far it has worked for my needs. Please offer improvements.
public static class Extensions_Section { public static IEnumerable<SectionPoint> GetValidSectionPoints( this Section section ) { var valid = new HashSet<Point3d>(); dynamic comSec = section.AcadObject; // AeccSection dynamic comLinks = comSec.Links; // AeccSectionLinks for ( int i = 0; i < comLinks.Count; i++ ) { dynamic comLink = comLinks.Item( i ); // AeccSectionLink if ( comLink.Type != 1 ) { valid.Add( new Point3d( comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ ) ); valid.Add( new Point3d( comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ ) ); } } return ( from sp in section.SectionPoints where valid.Contains( sp.Location ) select sp ); } public static IEnumerable<Section.SectionLink> GetSectionLinks( this Section section ) { dynamic comSec = section.AcadObject; // AeccSection dynamic comLinks = comSec.Links; // AeccSectionLinks for ( int i = 0; i < comLinks.Count; i++ ) { dynamic comLink = comLinks.Item( i ); // AeccSectionLink var start = ( from sp in section.SectionPoints where sp.Location.IsEqualTo( new Point3d( comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ ) ) select sp ).First(); var end = ( from sp in section.SectionPoints where sp.Location.IsEqualTo( new Point3d( comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ ) ) select sp ).First(); if ( start != null && end != null ) { yield return new Section.SectionLink( start, end, i, comLink.Type ); } } } public static IEnumerable<Section.SectionLink> GetValidSectionLinks( this Section section ) { return ( from sl in section.GetSectionLinks() where sl.Type != SectionLinkType.NoDraw select sl ); } } public static partial class Section { public class SectionLink { public SectionPoint StartPoint; public SectionPoint EndPoint; public readonly int Index; public readonly SectionLinkType Type; public SectionLink( SectionPoint startPoint, SectionPoint endPoint, int index, SectionLinkType type ) { StartPoint = startPoint; EndPoint = endPoint; Index = index; Type = type; } } } public enum SectionLinkType { None = 0, // aeccSectionLinkNone NoDraw = 1, // aeccSectionLinkNoDraw All = 2 // aeccSectionLinkAll }
Hey Jeff. Sorry, my post was in reply to your post but my comments were meant more for the community at large. I know that you always offer assistance when you have time.
Hey Jeff. Sorry, my post was in reply to your post but my comments were meant more for the community at large. I know that you always offer assistance when you have time.
HI @tyronebk
can you help me
I have this code and I don't know how to use the code he wrote
Is it possible to recognize him?
How can he make it work?
thank you
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using aGi = Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using CivDb = Autodesk.Civil.DatabaseServices;
using Autodesk.Civil;
namespace Extensions_Section
{
public class Extensions_Section
{
[CommandMethod("testExtensions_Section")]
public void stExtensions_SectiondA()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
CivilDocument civdoc = CivilApplication.ActiveDocument;
Editor ed = doc.Editor;
PromptEntityOptions entOpts = new PromptEntityOptions("Select section:");
entOpts.SetRejectMessage("...not a section, try again.");
entOpts.AddAllowedClass(typeof(CivDb.Section), true);
PromptEntityResult entRes = ed.GetEntity(entOpts);
if (entRes.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
CivDb.Section sec = (CivDb.Section)entRes.ObjectId.GetObject(OpenMode.ForRead);
var LL = GetSectionLinks(sec);
var LLPOINT = GetValidSectionPoints(sec);
tr.Commit();
}
}
}
public static class Extensions_Section
{
public static IEnumerable<SectionPoint> GetValidSectionPoints(this Section section)
{
var valid = new HashSet<Point3d>();
dynamic comSec = section.AcadObject; // AeccSection
dynamic comLinks = comSec.Links; // AeccSectionLinks
for (int i = 0; i < comLinks.Count; i++)
{
dynamic comLink = comLinks.Item(i); // AeccSectionLink
if (comLink.Type != 1)
{
valid.Add(new Point3d(comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ));
valid.Add(new Point3d(comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ));
}
}
return (from sp in section.SectionPoints
where valid.Contains(sp.Location)
select sp);
}
public static IEnumerable<Section.SectionLink> GetSectionLinks(this Section section)
{
dynamic comSec = section.AcadObject; // AeccSection
dynamic comLinks = comSec.Links; // AeccSectionLinks
for (int i = 0; i < comLinks.Count; i++)
{
dynamic comLink = comLinks.Item(i); // AeccSectionLink
var start = (from sp in section.SectionPoints
where sp.Location.IsEqualTo(new Point3d(comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ))
select sp).First();
var end = (from sp in section.SectionPoints
where sp.Location.IsEqualTo(new Point3d(comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ))
select sp).First();
if (start != null && end != null)
{
yield return new Section.SectionLink(start, end, i, comLink.Type);
}
}
}
public static IEnumerable<Section.SectionLink> GetValidSectionLinks(this Section section)
{
return (from sl in section.GetSectionLinks()
where sl.Type != SectionLinkType.NoDraw
select sl);
}
}
public static partial class Section
{
public class SectionLink
{
public SectionPoint StartPoint;
public SectionPoint EndPoint;
public readonly int Index;
public readonly SectionLinkType Type;
public SectionLink(SectionPoint startPoint, SectionPoint endPoint, int index, SectionLinkType type)
{
StartPoint = startPoint;
EndPoint = endPoint;
Index = index;
Type = type;
}
}
}
public enum SectionLinkType
{
None = 0, // aeccSectionLinkNone
NoDraw = 1, // aeccSectionLinkNoDraw
All = 2 // aeccSectionLinkAll
}
}
HI @tyronebk
can you help me
I have this code and I don't know how to use the code he wrote
Is it possible to recognize him?
How can he make it work?
thank you
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using aGi = Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using CivDb = Autodesk.Civil.DatabaseServices;
using Autodesk.Civil;
namespace Extensions_Section
{
public class Extensions_Section
{
[CommandMethod("testExtensions_Section")]
public void stExtensions_SectiondA()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
CivilDocument civdoc = CivilApplication.ActiveDocument;
Editor ed = doc.Editor;
PromptEntityOptions entOpts = new PromptEntityOptions("Select section:");
entOpts.SetRejectMessage("...not a section, try again.");
entOpts.AddAllowedClass(typeof(CivDb.Section), true);
PromptEntityResult entRes = ed.GetEntity(entOpts);
if (entRes.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
CivDb.Section sec = (CivDb.Section)entRes.ObjectId.GetObject(OpenMode.ForRead);
var LL = GetSectionLinks(sec);
var LLPOINT = GetValidSectionPoints(sec);
tr.Commit();
}
}
}
public static class Extensions_Section
{
public static IEnumerable<SectionPoint> GetValidSectionPoints(this Section section)
{
var valid = new HashSet<Point3d>();
dynamic comSec = section.AcadObject; // AeccSection
dynamic comLinks = comSec.Links; // AeccSectionLinks
for (int i = 0; i < comLinks.Count; i++)
{
dynamic comLink = comLinks.Item(i); // AeccSectionLink
if (comLink.Type != 1)
{
valid.Add(new Point3d(comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ));
valid.Add(new Point3d(comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ));
}
}
return (from sp in section.SectionPoints
where valid.Contains(sp.Location)
select sp);
}
public static IEnumerable<Section.SectionLink> GetSectionLinks(this Section section)
{
dynamic comSec = section.AcadObject; // AeccSection
dynamic comLinks = comSec.Links; // AeccSectionLinks
for (int i = 0; i < comLinks.Count; i++)
{
dynamic comLink = comLinks.Item(i); // AeccSectionLink
var start = (from sp in section.SectionPoints
where sp.Location.IsEqualTo(new Point3d(comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ))
select sp).First();
var end = (from sp in section.SectionPoints
where sp.Location.IsEqualTo(new Point3d(comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ))
select sp).First();
if (start != null && end != null)
{
yield return new Section.SectionLink(start, end, i, comLink.Type);
}
}
}
public static IEnumerable<Section.SectionLink> GetValidSectionLinks(this Section section)
{
return (from sl in section.GetSectionLinks()
where sl.Type != SectionLinkType.NoDraw
select sl);
}
}
public static partial class Section
{
public class SectionLink
{
public SectionPoint StartPoint;
public SectionPoint EndPoint;
public readonly int Index;
public readonly SectionLinkType Type;
public SectionLink(SectionPoint startPoint, SectionPoint endPoint, int index, SectionLinkType type)
{
StartPoint = startPoint;
EndPoint = endPoint;
Index = index;
Type = type;
}
}
}
public enum SectionLinkType
{
None = 0, // aeccSectionLinkNone
NoDraw = 1, // aeccSectionLinkNoDraw
All = 2 // aeccSectionLinkAll
}
}
1. You cannot have a class name the same as the Namespace, changing the class to ExtensionsSection solves this.
2. Extension methods need to be called like so:
var LL = sec.GetSectionLinks();
var LLPOINT = sec.GetValidSectionPoints();
3. Section is ambiguous (it is defined in more than one assembly) so all of the extension methods need to be modified like so:
(this CivDb.Section section)
I think that should do it.
1. You cannot have a class name the same as the Namespace, changing the class to ExtensionsSection solves this.
2. Extension methods need to be called like so:
var LL = sec.GetSectionLinks();
var LLPOINT = sec.GetValidSectionPoints();
3. Section is ambiguous (it is defined in more than one assembly) so all of the extension methods need to be modified like so:
(this CivDb.Section section)
I think that should do it.
Hi @Jeff_M
Sorry I couldn't change as you directed me
Due to poor of experience with C-Sharp
Attach the project
If you have time to look at it
to make the appropriate modification
thank you
Hi @Jeff_M
Sorry I couldn't change as you directed me
Due to poor of experience with C-Sharp
Attach the project
If you have time to look at it
to make the appropriate modification
thank you
@hosneyalaa I mistyped a portion of my previous response. It wasn't the class and namespace that was the issue, it was that you had 2 classes with the same name. This should work for you:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using aGi = Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using CivDb = Autodesk.Civil.DatabaseServices;
namespace Extensions_Section
{
public class Extensions_Section
{
[CommandMethod("testExtensions_Section")]
public void stExtensions_SectiondA()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
CivilDocument civdoc = CivilApplication.ActiveDocument;
Editor ed = doc.Editor;
PromptEntityOptions entOpts = new PromptEntityOptions("Select section:");
entOpts.SetRejectMessage("...not a section, try again.");
entOpts.AddAllowedClass(typeof(CivDb.Section), true);
PromptEntityResult entRes = ed.GetEntity(entOpts);
if (entRes.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
CivDb.Section sec = (CivDb.Section)entRes.ObjectId.GetObject(OpenMode.ForRead);
var LL = sec.GetSectionLinks();
var LLPOINT = sec.GetValidSectionPoints();
tr.Commit();
}
}
}
public static class ExtensionsSection
{
public static IEnumerable<SectionPoint> GetValidSectionPoints(this CivDb.Section section)
{
var valid = new HashSet<Point3d>();
dynamic comSec = section.AcadObject; // AeccSection
dynamic comLinks = comSec.Links; // AeccSectionLinks
for (int i = 0; i < comLinks.Count; i++)
{
dynamic comLink = comLinks.Item(i); // AeccSectionLink
if (comLink.Type != 1)
{
valid.Add(new Point3d(comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ));
valid.Add(new Point3d(comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ));
}
}
return (from sp in section.SectionPoints
where valid.Contains(sp.Location)
select sp);
}
public static IEnumerable<Section.SectionLink> GetSectionLinks(this CivDb.Section section)
{
dynamic comSec = section.AcadObject; // AeccSection
dynamic comLinks = comSec.Links; // AeccSectionLinks
for (int i = 0; i < comLinks.Count; i++)
{
dynamic comLink = comLinks.Item(i); // AeccSectionLink
var start = (from sp in section.SectionPoints
where sp.Location.IsEqualTo(new Point3d(comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ))
select sp).First();
var end = (from sp in section.SectionPoints
where sp.Location.IsEqualTo(new Point3d(comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ))
select sp).First();
if (start != null && end != null)
{
yield return new Section.SectionLink(start, end, i, comLink.Type);
}
}
}
public static IEnumerable<Section.SectionLink> GetValidSectionLinks(this CivDb.Section section)
{
return (from sl in section.GetSectionLinks()
where sl.Type != SectionLinkType.NoDraw
select sl);
}
}
public static partial class Section
{
public class SectionLink
{
public SectionPoint StartPoint;
public SectionPoint EndPoint;
public readonly int Index;
public readonly SectionLinkType Type;
public SectionLink(SectionPoint startPoint, SectionPoint endPoint, int index, SectionLinkType type)
{
StartPoint = startPoint;
EndPoint = endPoint;
Index = index;
Type = type;
}
}
}
public enum SectionLinkType
{
None = 0, // aeccSectionLinkNone
NoDraw = 1, // aeccSectionLinkNoDraw
All = 2 // aeccSectionLinkAll
}
}
@hosneyalaa I mistyped a portion of my previous response. It wasn't the class and namespace that was the issue, it was that you had 2 classes with the same name. This should work for you:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using aGi = Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using CivDb = Autodesk.Civil.DatabaseServices;
namespace Extensions_Section
{
public class Extensions_Section
{
[CommandMethod("testExtensions_Section")]
public void stExtensions_SectiondA()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
CivilDocument civdoc = CivilApplication.ActiveDocument;
Editor ed = doc.Editor;
PromptEntityOptions entOpts = new PromptEntityOptions("Select section:");
entOpts.SetRejectMessage("...not a section, try again.");
entOpts.AddAllowedClass(typeof(CivDb.Section), true);
PromptEntityResult entRes = ed.GetEntity(entOpts);
if (entRes.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
CivDb.Section sec = (CivDb.Section)entRes.ObjectId.GetObject(OpenMode.ForRead);
var LL = sec.GetSectionLinks();
var LLPOINT = sec.GetValidSectionPoints();
tr.Commit();
}
}
}
public static class ExtensionsSection
{
public static IEnumerable<SectionPoint> GetValidSectionPoints(this CivDb.Section section)
{
var valid = new HashSet<Point3d>();
dynamic comSec = section.AcadObject; // AeccSection
dynamic comLinks = comSec.Links; // AeccSectionLinks
for (int i = 0; i < comLinks.Count; i++)
{
dynamic comLink = comLinks.Item(i); // AeccSectionLink
if (comLink.Type != 1)
{
valid.Add(new Point3d(comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ));
valid.Add(new Point3d(comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ));
}
}
return (from sp in section.SectionPoints
where valid.Contains(sp.Location)
select sp);
}
public static IEnumerable<Section.SectionLink> GetSectionLinks(this CivDb.Section section)
{
dynamic comSec = section.AcadObject; // AeccSection
dynamic comLinks = comSec.Links; // AeccSectionLinks
for (int i = 0; i < comLinks.Count; i++)
{
dynamic comLink = comLinks.Item(i); // AeccSectionLink
var start = (from sp in section.SectionPoints
where sp.Location.IsEqualTo(new Point3d(comLink.StartPointX, comLink.StartPointY, comLink.StartPointZ))
select sp).First();
var end = (from sp in section.SectionPoints
where sp.Location.IsEqualTo(new Point3d(comLink.EndPointX, comLink.EndPointY, comLink.EndPointZ))
select sp).First();
if (start != null && end != null)
{
yield return new Section.SectionLink(start, end, i, comLink.Type);
}
}
}
public static IEnumerable<Section.SectionLink> GetValidSectionLinks(this CivDb.Section section)
{
return (from sl in section.GetSectionLinks()
where sl.Type != SectionLinkType.NoDraw
select sl);
}
}
public static partial class Section
{
public class SectionLink
{
public SectionPoint StartPoint;
public SectionPoint EndPoint;
public readonly int Index;
public readonly SectionLinkType Type;
public SectionLink(SectionPoint startPoint, SectionPoint endPoint, int index, SectionLinkType type)
{
StartPoint = startPoint;
EndPoint = endPoint;
Index = index;
Type = type;
}
}
}
public enum SectionLinkType
{
None = 0, // aeccSectionLinkNone
NoDraw = 1, // aeccSectionLinkNoDraw
All = 2 // aeccSectionLinkAll
}
}
Years ago i had to deal with the same problem.
It is 2022 and i found the solution accidentally.
Just in case someone has not realized it yet, autodesk solved our problem.
They exposed the SegmentTo property for the SectionPoint class
No longer any need to use workarounds.
Below is the link...
Copy-paste from the Civil 3D developer's API reference guide...
SectionPoint.SegmentTo
"Returns the index of the other section point that creates a line segment with this section point. If no segment can be drawn from this point, then -1 is returned. This can happen if there is no underlying surface to determine elevation, such as a hole in a tin/dtm surface, or if the terrain is narrower than the section or the sample line, such that it's not possible to compute all elevations of the section point elevations. For valid segments, only consider segments from this point to other points of index >= 0 "
Years ago i had to deal with the same problem.
It is 2022 and i found the solution accidentally.
Just in case someone has not realized it yet, autodesk solved our problem.
They exposed the SegmentTo property for the SectionPoint class
No longer any need to use workarounds.
Below is the link...
Copy-paste from the Civil 3D developer's API reference guide...
SectionPoint.SegmentTo
"Returns the index of the other section point that creates a line segment with this section point. If no segment can be drawn from this point, then -1 is returned. This can happen if there is no underlying surface to determine elevation, such as a hole in a tin/dtm surface, or if the terrain is narrower than the section or the sample line, such that it's not possible to compute all elevations of the section point elevations. For valid segments, only consider segments from this point to other points of index >= 0 "
Can't find what you're looking for? Ask the community or share your knowledge.