Programmatically Getting a Polyline of intersection of Loft and a plane

Programmatically Getting a Polyline of intersection of Loft and a plane

ekoneo
Advocate Advocate
1,857 Views
12 Replies
Message 1 of 13

Programmatically Getting a Polyline of intersection of Loft and a plane

ekoneo
Advocate
Advocate

Hi,

How can I get a polyline that is an intersection of a plane and loft object programmatically in c#? Plane can be any object. In fact I need a cross sectional polyline object.

I try to figure with a image. There is a rectangular plane and a loft object. I need this intersection polyline as shown:

 

IntersectionOfPlaneLoft.png

 

 

 

 

Thanks.

0 Likes
Accepted solutions (3)
1,858 Views
12 Replies
Replies (12)
Message 2 of 13

R.Gerritsen4967
Advocate
Advocate

Have a look here. (especially @SEANT61's post)

 

It's not perfect, but it will get you started.

I have used this piece of code before, but in the case of your drawing it will, unfortunately, give you only a part of the intersection.

Message 3 of 13

_gile
Consultant
Consultant

Hi,

 

If the "loft object" is a Solid3d, you could use the Solid3d.GetSection() method.

But according to your screencast, it seems to be a Surface. In this case, you could use the Surface.SliceByPlane() method on a temporary clone of the "loft object" and use the Brep API to retrieve the edges of the concerned face (this is not that trivial).



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 13

R.Gerritsen4967
Advocate
Advocate
Accepted solution

@_gile,

I see there is also a Surface.SliceBySurface method. This seems to be a bit more versatile if you also want to get sections with non-planar surfaces.

 

Do you perhaps know how to convert the SurfaceSliceResults (result of SliceBy... method) to a curve?

Or do you make a new surface with SurfaceSliceResults.NewSurface and then extract the edges?

0 Likes
Message 5 of 13

_gile
Consultant
Consultant

As far as I know there's no way to directly convert a Surface (as returned by SurfaceSliceResults.NegativeHalfSurface or SurfaceSliceResults.NewSurface) into a curve. You have to extract the edges of one of the slice resulting surfaces.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 6 of 13

_gile
Consultant
Consultant
Accepted solution

Here's an example slicing the selected Surface with an horizontal plane at specified elevation.

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.BoundaryRepresentation;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

using System.Linq;

using static System.Math;

namespace SelectViewportSample
{
    using AcDb = Autodesk.AutoCAD.DatabaseServices;
    using AcRx = Autodesk.AutoCAD.Runtime;
    public class Commands
    {
        [CommandMethod("TEST")]
        public static void Test()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var peo = new PromptEntityOptions("\nSelect Surface: ");
            peo.SetRejectMessage("\nSelected object is not a Surface.");
            peo.AddAllowedClass(typeof(AcDb.Surface), false);
            var per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK)
                return;

            var pdr = ed.GetDouble("\nEnter the plane elevation: ");
            if (pdr.Status != PromptStatus.OK)
                return;
            double elevation = pdr.Value;

            using (var tr = db.TransactionManager.StartTransaction())
            {
                var surface = (AcDb.Surface)tr.GetObject(per.ObjectId, OpenMode.ForWrite);

                var plane = new Plane(new Point3d(0.0, 0.0, elevation), Vector3d.ZAxis);

                try
                {
                    var sliceResults = surface.SliceByPlane(plane);
                    using (var negativeHalfResult = sliceResults.NegativeHalfSurface)
                    using (sliceResults.NewSurface)
                    using (var brep = new Brep(sliceResults.NegativeHalfSurface))
                    {
                        var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                        var edges = brep.Edges
                            .Where(e => Abs(e.Vertex1.Point.Z - elevation) < 1e-12 && Abs(e.Vertex2.Point.Z - elevation) < 1e-12)
                            .Select(e => Curve.CreateFromGeCurve(((ExternalCurve3d)e.Curve).NativeCurve));
                        foreach (var edge in edges)
                        {
                            edge.ColorIndex = 1;
                            curSpace.AppendEntity(edge);
                            tr.AddNewlyCreatedDBObject(edge, true);
                        }
                    }
                    tr.Commit();
                }
                catch (AcRx.Exception ex) when (ex.ErrorStatus == AcRx.ErrorStatus.NoIntersections)
                {
                    ed.WriteMessage("\nThe Plane does not slice the Surface.");
                }
                catch (System.Exception ex)
                {
                    ed.WriteMessage($"\n{ex.Message}");
                }
            }
        }
    }
}

 

 

 

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 7 of 13

ekoneo
Advocate
Advocate

Hi @_gile  and @R.Gerritsen4967 ,

 

Thanks for your help and interest. Thank you for helping for this kind of difficult problem for me. I try your advices. 

 

0 Likes
Message 8 of 13

ekoneo
Advocate
Advocate

@_gile I try your sample. It works perfectly. Result is 4 piece of splines that are on the intersection plane an the surface. My thanks are less than your helps.  

0 Likes
Message 9 of 13

ekoneo
Advocate
Advocate

Hi @_gile,

 

Depending on loft surface shape, the result intersection objects can be more than 1 objects as spline, polyline, circle etc.

I try to join if there are more than 1 pieces.

Green, Red, Yellow and Magenta colored splinesGreen, Red, Yellow and Magenta colored splines

 

 

 

int count = 0;
foreach (var edge in edges)
{
   edge.ColorIndex = 1;
   curSpace.AppendEntity(edge);
   tr.AddNewlyCreatedDBObject(edge, true);
   if (count == 0)
   {
       obj = edge;
   }
   else if (count == 1)
   {
       obj.JoinEntity(edge);
       count++;
   }
}
tr.AddNewlyCreatedDBObject(obj, true);

 

 

 

Unfortunatelly, I couldn't get success result. How can I join result objects? 

Thanks again.

 

0 Likes
Message 10 of 13

_gile
Consultant
Consultant

As far as I know, you cannot join splines.

The only way to get a single entity is to create a Region from the resulting curves with Region.CreateFromCurves method.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 11 of 13

ekoneo
Advocate
Advocate

Thanks.. Is it possible to use "DistanceTo" function with region? I need distance between Cogo point and the polyline, spline or region.

 

On the other hand, after your code produced splines, I can manually join them.

 

Thanks @_gile 

0 Likes
Message 12 of 13

_gile
Consultant
Consultant
Accepted solution

You can generate a polyline which approximate the spline with the Spline.ToPolyline method if you accept to loose a little accuracy.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 13 of 13

ekoneo
Advocate
Advocate

Thank you @_gile. I try your advice. 

0 Likes