how to extract _AcDb.Surfce isolines

how to extract _AcDb.Surfce isolines

essam-salah
Collaborator Collaborator
566 Views
5 Replies
Message 1 of 6

how to extract _AcDb.Surfce isolines

essam-salah
Collaborator
Collaborator

hi

is it possible to extract Autodesk.Autocad.DatabaseServices.Surface  isolines and border using .Net ?

0 Likes
567 Views
5 Replies
Replies (5)
Message 2 of 6

essam-salah
Collaborator
Collaborator

i'm trying to use _AcDb.NurbSurface.GetIsolineAtU(du) after converting my _AcDb.Surface into NurbSurface using mySurface.ConvertToNurbSurface(),

the problem is i can't figure out how calculate du/dv for GetIsolineAtU GetIsolineAtV .

0 Likes
Message 3 of 6

ActivistInvestor
Mentor
Mentor

Have a look at this blog post.

 

It shows how to do it in native ObjectARX. The only potential problem I see is that the managed Surface class may not expose all of the needed apis, which means that you may need to resort to p/Invoke.

0 Likes
Message 4 of 6

hippe013
Advisor
Advisor

You are on the right track. See below two example commands for extracting the isolines (curve object) from an AutoCAD surface. 

 

I created a rectangle and then converted that rectangle to a plane surface using the PlaneSurf command. 

 

Using the following two commands (U & V) you can extract an isoline by inputting a value. A value of zero is the midpoint of the plane surface. Inputting a positive number goes in one direction while inputting a negative number goes in the other direction. The value inputted is a unit distance from the mid-point, at least in the example of a plane surface.

 

I hope this helps get you going in the right direction. 

 

 <CommandMethod("AcSurfExtractU")>
        Public Sub CmdAcSurfExtractU()
            Dim aDoc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = aDoc.Database
            Dim ed As Editor = aDoc.Editor

            Dim opt As New PromptEntityOptions(vbCrLf & "Select AutoCAD Surface: ")
            opt.SetRejectMessage(vbCrLf & "Selected entity must be a AutoCAD Surface. Try again.")
            opt.AddAllowedClass(GetType(Autodesk.AutoCAD.DatabaseServices.Surface), False)

            Dim res As PromptEntityResult = ed.GetEntity(opt)

            If res.Status <> PromptStatus.OK Then Exit Sub

            Using tr As Transaction = db.TransactionManager.StartTransaction
                Dim surf As Autodesk.AutoCAD.DatabaseServices.Surface = tr.GetObject(res.ObjectId, OpenMode.ForRead)
                Dim nurbs As Autodesk.AutoCAD.DatabaseServices.NurbSurface() = surf.ConvertToNurbSurface

                If Not nurbs.Length > 0 Then
                    Exit Sub
                End If

                Dim nurb As Autodesk.AutoCAD.DatabaseServices.NurbSurface = nurbs(0)

                Dim U_dblOpt As New PromptDoubleOptions(vbCrLf & "Enter U Value: ")

                Dim U_dblRes As PromptDoubleResult = ed.GetDouble(U_dblOpt)

                If U_dblRes.Status <> PromptStatus.OK Then
                    Exit Sub
                End If

                Dim blkTblRec As BlockTableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)

                Dim curves As Curve() = nurb.GetIsolineAtU(U_dblRes.Value)

                For Each crv As Curve In curves
                    blkTblRec.AppendEntity(crv)
                    tr.AddNewlyCreatedDBObject(crv, True)
                Next

                tr.Commit()
            End Using
        End Sub

        <CommandMethod("AcSurfExtractV")>
        Public Sub CmdAcSurfExtractV()
            Dim aDoc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = aDoc.Database
            Dim ed As Editor = aDoc.Editor

            Dim opt As New PromptEntityOptions(vbCrLf & "Select AutoCAD Surface: ")
            opt.SetRejectMessage(vbCrLf & "Selected entity must be a AutoCAD Surface. Try again.")
            opt.AddAllowedClass(GetType(Autodesk.AutoCAD.DatabaseServices.Surface), False)

            Dim res As PromptEntityResult = ed.GetEntity(opt)

            If res.Status <> PromptStatus.OK Then Exit Sub

            Using tr As Transaction = db.TransactionManager.StartTransaction
                Dim surf As Autodesk.AutoCAD.DatabaseServices.Surface = tr.GetObject(res.ObjectId, OpenMode.ForRead)
                Dim nurbs As Autodesk.AutoCAD.DatabaseServices.NurbSurface() = surf.ConvertToNurbSurface

                If Not nurbs.Length > 0 Then
                    Exit Sub
                End If

                Dim nurb As Autodesk.AutoCAD.DatabaseServices.NurbSurface = nurbs(0)

                Dim V_dblOpt As New PromptDoubleOptions(vbCrLf & "Enter V Value: ")

                Dim V_dblRes As PromptDoubleResult = ed.GetDouble(V_dblOpt)

                If V_dblRes.Status <> PromptStatus.OK Then
                    Exit Sub
                End If

                Dim blkTblRec As BlockTableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)

                Dim curves As Curve() = nurb.GetIsolineAtV(V_dblRes.Value)

                For Each crv As Curve In curves
                    blkTblRec.AppendEntity(crv)
                    tr.AddNewlyCreatedDBObject(crv, True)
                Next

                tr.Commit()
            End Using
        End Sub

 

 

 

0 Likes
Message 5 of 6

essam-salah
Collaborator
Collaborator

hi @ActivistInvestor 


@ActivistInvestor wrote:

Have a look at this blog post.

 

It shows how to do it in native ObjectARX. The only potential problem I see is that the managed Surface class may not expose all of the needed apis, which means that you may need to resort to p/Invoke.


yes, i already tried to use this blog post, here is my code so far:

// prompt for _AcDbSurface, and get surfId

var db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;
using (var tr = db.TransactionManager.StartTransaction())
{
    var dbSurface = (_AcDb.Surface)tr.GetObject(surfId, _AcDb.OpenMode.ForWrite);
    // convert to nurb
    var dbNurbSurfaces = dbSurface.ConvertToNurbSurface();
    if (dbNurbSurfaces.Length < 1)
    {
        return;
    }
    var dbNurbSurface = dbNurbSurfaces[0]; // pNS in original code
    var uIsoDensity = dbSurface.UIsoLineDensity;
    var vIsoDensity = dbSurface.VIsoLineDensity;

    using (var brep = new _AcBr.Brep(dbSurface))
    {
        foreach (var face in brep.Faces)
        {
            var pGeSurface = face.Surface; 

            var intervals = pGeSurface.GetEnvelope();
            var intervalU = intervals[0];
            var intervalV = intervals[1];

            // get min/max bounds 
            var boundMinU = intervalU.LowerBound;
            var boundMaxU = intervalU.UpperBound;
            var boundMinV = intervalV.LowerBound;
            var boundMaxV = intervalV.UpperBound;

            var isClosedInU = pGeSurface.IsClosedInU(tolerance);
            var isClosedInV = pGeSurface.IsClosedInV(tolerance);
            var paramIncrU = (boundMaxU - boundMinU) / (isClosedInU ? uIsoDensity : (uIsoDensity + 1));
            var paramIncrV = (boundMaxV - boundMinV) / (isClosedInV ? vIsoDensity : (vIsoDensity + 1));

            var ucMax = isClosedInU ? uIsoDensity : uIsoDensity + 2;
            int vcMax = isClosedInV ? vIsoDensity : vIsoDensity + 2;

            var paramU = boundMinU;

            for (int uc = 0; uc < ucMax; uc++)
            {
                double paramV = boundMinV;
                for (int vc = 0; vc < vcMax; vc++)
                {
                    // u lines
                    var uIsoLines = dbNurbSurface.GetIsolineAtU(paramU);
                    foreach (var uCurve in uIsoLines)
                    {
                        uCurve.ColorIndex = 1;
                        // Add uCurve to Current drawing
                    }
                    // v lines
                    var vIsoLines = dbNurbSurface.GetIsolineAtV(paramV);
                    foreach (var vCurve in vIsoLines)
                    {
                        vCurve.ColorIndex = 2;
                        // Add vCurve to Current drawing
                    }
                    paramV += paramIncrV;
                }
                paramU += paramIncrU;
            }

        } // foreach face end
    } // brep end

    // apply changes
    tr.Commit();
}

 

but it doesn't work, it always drawy a 96 Spline as straight lines of length 0.095 at origin for every surface i select,

 

0 Likes
Message 6 of 6

ActivistInvestor
Mentor
Mentor

Just for kicks, I copied the C++ code from the original blog post and asked ChatGPT to convert it to C# .

 

I can't tell you if works, but it looks as though it can at least be useful for reducing some typing.

0 Likes