.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Draw on selected face

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
prahtYHGMJ
626 Views, 5 Replies

Draw on selected face

prahtYHGMJ
Explorer
Explorer

I want to accomplish this workflow:

1) Select face of a solid

2) select two points (midpoints) on the edges of face

3) draw circles on the line connecting selected points,

      ( circles must lie on selected face)

4) presspull circles toward solid and outward of solid

5) draw another circle at center of one side of presspulled solid, perpendicular to it

 

Any hint about some of those tasks would help me. I am new to autocad and programming it, need it

to automate repetitive tasks in furniture drawings where there are lot of holes for connecting pieces.

0 Likes

Draw on selected face

I want to accomplish this workflow:

1) Select face of a solid

2) select two points (midpoints) on the edges of face

3) draw circles on the line connecting selected points,

      ( circles must lie on selected face)

4) presspull circles toward solid and outward of solid

5) draw another circle at center of one side of presspulled solid, perpendicular to it

 

Any hint about some of those tasks would help me. I am new to autocad and programming it, need it

to automate repetitive tasks in furniture drawings where there are lot of holes for connecting pieces.

Tags (2)
5 REPLIES 5
Message 2 of 6
seabrahenrique
in reply to: prahtYHGMJ

seabrahenrique
Advocate
Advocate

Something like that:

 

[CommandMethod("CirclesInFaceSolid")]
public static void CirclesInFaceSolid()
{
    Document acDoc = Application.DocumentManager.MdiActiveDocument;
    Database acDb = acDoc.Database;
    Editor acEd = acDoc.Editor;

    // Select a face of a solid
    PromptEntityResult faceResult = acEd.GetEntity("Select a face of a solid: ");
    ObjectId faceId = faceResult.ObjectId;

    // Select the first point
    PromptPointResult point1Result = acEd.GetPoint("Select the first point: ");

    // Select the second point
    PromptPointResult point2Result = acEd.GetPoint("Select the second point: ");

    Point3d point1 = point1Result.Value;
    Point3d point2 = point2Result.Value;

    // Draw circles on the line connecting the selected points
    Circle circle1 = new Circle();
    circle1.Center = point1;
    circle1.Radius = point1.DistanceTo(point2) / 2.0;

    Circle circle2 = new Circle();
    circle2.Center = point2;
    circle2.Radius = point1.DistanceTo(point2) / 2.0;

    using (Transaction acTrans = acDb.TransactionManager.StartTransaction())
    {
        BlockTable acBlkTbl = acTrans.GetObject(acDb.BlockTableId, OpenMode.ForRead) as BlockTable;
        BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

        acBlkTblRec.AppendEntity(circle1);
        acBlkTblRec.AppendEntity(circle2);

        acTrans.AddNewlyCreatedDBObject(circle1, true);
        acTrans.AddNewlyCreatedDBObject(circle2, true);

        acTrans.Commit();
    }

 

Is not all, but i hope can help!

0 Likes

Something like that:

 

[CommandMethod("CirclesInFaceSolid")]
public static void CirclesInFaceSolid()
{
    Document acDoc = Application.DocumentManager.MdiActiveDocument;
    Database acDb = acDoc.Database;
    Editor acEd = acDoc.Editor;

    // Select a face of a solid
    PromptEntityResult faceResult = acEd.GetEntity("Select a face of a solid: ");
    ObjectId faceId = faceResult.ObjectId;

    // Select the first point
    PromptPointResult point1Result = acEd.GetPoint("Select the first point: ");

    // Select the second point
    PromptPointResult point2Result = acEd.GetPoint("Select the second point: ");

    Point3d point1 = point1Result.Value;
    Point3d point2 = point2Result.Value;

    // Draw circles on the line connecting the selected points
    Circle circle1 = new Circle();
    circle1.Center = point1;
    circle1.Radius = point1.DistanceTo(point2) / 2.0;

    Circle circle2 = new Circle();
    circle2.Center = point2;
    circle2.Radius = point1.DistanceTo(point2) / 2.0;

    using (Transaction acTrans = acDb.TransactionManager.StartTransaction())
    {
        BlockTable acBlkTbl = acTrans.GetObject(acDb.BlockTableId, OpenMode.ForRead) as BlockTable;
        BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

        acBlkTblRec.AppendEntity(circle1);
        acBlkTblRec.AppendEntity(circle2);

        acTrans.AddNewlyCreatedDBObject(circle1, true);
        acTrans.AddNewlyCreatedDBObject(circle2, true);

        acTrans.Commit();
    }

 

Is not all, but i hope can help!

Message 3 of 6
prahtYHGMJ
in reply to: seabrahenrique

prahtYHGMJ
Explorer
Explorer

Thank You very much, i can work from there.

0 Likes

Thank You very much, i can work from there.

Message 4 of 6
_gile
in reply to: prahtYHGMJ

_gile
Mentor
Mentor

Hi,

 

The task you want to accomplish is not that simple, especially if you are new to AutoCAD programming with .NET.

 


@prahtYHGMJ  a écrit :

1) Select face of a solid


Selecting a sub-entity of a solid is not so trivial (see this topic). You should also have to use the BREP API to check if the selected face is planar.

 


@prahtYHGMJ  a écrit :

2) select two points (midpoints) on the edges of face


Selecting edges of a solid is the same process as for a face. You should also have to use the BREP API to check if the selected edges owns to a loop of the previously selected face.

 


@prahtYHGMJ  a écrit :

3) draw circles on the line connecting selected points,

      ( circles must lie on selected face)


This is the simplest task of your workflow, you just need to set the Circle.Normal property to match with the normal of the plane of the selected face.

 


@prahtYHGMJ  a écrit :

4) presspull circles toward solid and outward of solid


You have to extrude the circle (create an extruded solid).

 


@prahtYHGMJ  a écrit :

5) draw another circle at center of one side of presspulled solid, perpendicular to it


Sorry, I do not fully understand this one, but it seems to be the same as the previous one with some geometry calculations.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Hi,

 

The task you want to accomplish is not that simple, especially if you are new to AutoCAD programming with .NET.

 


@prahtYHGMJ  a écrit :

1) Select face of a solid


Selecting a sub-entity of a solid is not so trivial (see this topic). You should also have to use the BREP API to check if the selected face is planar.

 


@prahtYHGMJ  a écrit :

2) select two points (midpoints) on the edges of face


Selecting edges of a solid is the same process as for a face. You should also have to use the BREP API to check if the selected edges owns to a loop of the previously selected face.

 


@prahtYHGMJ  a écrit :

3) draw circles on the line connecting selected points,

      ( circles must lie on selected face)


This is the simplest task of your workflow, you just need to set the Circle.Normal property to match with the normal of the plane of the selected face.

 


@prahtYHGMJ  a écrit :

4) presspull circles toward solid and outward of solid


You have to extrude the circle (create an extruded solid).

 


@prahtYHGMJ  a écrit :

5) draw another circle at center of one side of presspulled solid, perpendicular to it


Sorry, I do not fully understand this one, but it seems to be the same as the previous one with some geometry calculations.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 6
_gile
in reply to: _gile

_gile
Mentor
Mentor
Accepted solution

Here's a "quick" example which prompt the user to select a face of a solid and two edges on this face. Then, it computes the midlle points of the selected edges and the midlle point of these points and "drills" a hole (diameter 8, depth 30) in the solid.

        [CommandMethod("TEST")]
        public static void Test()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            // Select a sub entity of a solid 3d
            var options = new PromptSelectionOptions();
            options.MessageForAdding = "\nSelect face of a solid";
            options.SingleOnly = true;
            options.SinglePickInSpace = true;
            options.ForceSubSelections = true;
            var filter = new SelectionFilter(new[] { new TypedValue(0, "3DSOLID") });
            var result = ed.GetSelection(options, filter);
            if (result.Status != PromptStatus.OK)
            {
                return;
            }
            var selectedObject = result.Value[0];
            var subSelectedObject = selectedObject.GetSubentities()[0];
            var subEntityType = subSelectedObject.FullSubentityPath.SubentId.Type;

            // Check if the sub entity is a face
            if (subEntityType != SubentityType.Face)
            {
                ed.WriteMessage($"\nSelected sub-entity is not a Face ({subEntityType})");
                return;
            }

            using (var tr = db.TransactionManager.StartTransaction())
            {
                var solidId = selectedObject.ObjectId;
                var solid = (Solid3d)tr.GetObject(solidId, OpenMode.ForRead);
                var subentityId = subSelectedObject.FullSubentityPath.SubentId;
                var facePath = new FullSubentityPath(new ObjectId[] { solid.ObjectId }, subentityId);
                var entityPath = new FullSubentityPath(new ObjectId[] { solid.ObjectId }, new SubentityId(SubentityType.Null, IntPtr.Zero));
                using (var brep = new Brep(entityPath))
                {
                    var face = brep.Faces.First(f => f.SubentityPath == facePath);

                    // Check if the face is planar
                    var boundedSurface = (ExternalBoundedSurface)face.Surface;
                    if (!boundedSurface.IsPlane)
                    {
                        ed.WriteMessage($"\nSelected Face is not planar");
                        return;
                    }

                    // Select the first edge
                    options.MessageForAdding = "\nSelect the first edge: ";
                    result = ed.GetSelection(options, filter);
                    if (result.Status != PromptStatus.OK)
                    {
                        return;
                    }
                    selectedObject = result.Value[0];
                    if (selectedObject.ObjectId != solidId)
                    {
                        ed.WriteMessage($"\nSelected Edge is not on same solid");
                        return;
                    }
                    subSelectedObject = selectedObject.GetSubentities()[0];
                    subEntityType = subSelectedObject.FullSubentityPath.SubentId.Type;

                    // Check if the sub entity is an edge
                    if (subEntityType != SubentityType.Edge)
                    {
                        ed.WriteMessage($"\nSelected sub-entity is not an Edge ({subEntityType})");
                        return;
                    }
                    subentityId = subSelectedObject.FullSubentityPath.SubentId;
                    var firstEdgePath = new FullSubentityPath(new ObjectId[] { solid.ObjectId }, subentityId);

                    // Check if the edge is on the face
                    var firstEdge = face.Loops.SelectMany(l => l.Edges).FirstOrDefault(e => e.SubentityPath == firstEdgePath);
                    if (firstEdge == null)
                    {
                        ed.WriteMessage($"\nSelected Edge is not on the face");
                        return;
                    }

                    // Select the second edge
                    options.MessageForAdding = "\nSelect the second edge: ";
                    result = ed.GetSelection(options, filter);
                    if (result.Status != PromptStatus.OK)
                    {
                        return;
                    }
                    selectedObject = result.Value[0];
                    if (selectedObject.ObjectId != solidId)
                    {
                        ed.WriteMessage($"\nSelected Edge is not on same solid");
                        return;
                    }
                    subSelectedObject = selectedObject.GetSubentities()[0];
                    subEntityType = subSelectedObject.FullSubentityPath.SubentId.Type;

                    // Check if the sub entity is an edge
                    if (subEntityType != SubentityType.Edge)
                    {
                        ed.WriteMessage($"\nSelected sub-entity is not an Edge ({subEntityType})");
                        return;
                    }
                    subentityId = subSelectedObject.FullSubentityPath.SubentId;
                    var secondEdgePath = new FullSubentityPath(new ObjectId[] { solid.ObjectId }, subentityId);

                    // Check if the edge is on the face
                    var secondEdge = face.Loops.SelectMany(l => l.Edges).FirstOrDefault(e => e.SubentityPath == secondEdgePath);
                    if (secondEdge == null)
                    {
                        ed.WriteMessage($"\nSelected Edge is not on the face");
                        return;
                    }

                    // Create the circle
                    var curve = ((ExternalCurve3d)firstEdge.Curve).NativeCurve;
                    var pt1 = curve.EvaluatePoint(
                        (curve.GetParameterOf(curve.EndPoint) - curve.GetParameterOf(curve.StartPoint)) / 2.0);
                    curve = ((ExternalCurve3d)secondEdge.Curve).NativeCurve;
                    var pt2 = curve.EvaluatePoint(
                        (curve.GetParameterOf(curve.EndPoint) - curve.GetParameterOf(curve.StartPoint)) / 2.0);
                    var center = new LineSegment3d(pt1, pt2).MidPoint;

                    // Get the Normal vector of the plane
                    var plane = (Plane)boundedSurface.BaseSurface;
                    var normal = plane.Normal;

                    // Negate the normal direction if it goes outside of the solid
                    var point = center + normal * 1e-6;
                    using (var brepFace = brep.GetPointContainment(point, out PointContainment containment))
                    {
                        if (containment == PointContainment.Outside)
                            normal = normal.Negate();
                    }

                    double radius = 4.0;
                    using (var circle = new Circle(center, normal, radius))
                    {
                        // Extrude the circle and substract it to the solid
                        using (var regions = Region.CreateFromCurves(new DBObjectCollection() { circle }))
                        using (var region = (Region)regions[0])
                        using (var hole = new Solid3d())
                        {
                            hole.Extrude(region, 30.0, 0.0);
                            tr.GetObject(selectedObject.ObjectId, OpenMode.ForWrite);
                            solid.BooleanOperation(BooleanOperationType.BoolSubtract, hole);
                        }
                    }
                }
                tr.Commit();
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Here's a "quick" example which prompt the user to select a face of a solid and two edges on this face. Then, it computes the midlle points of the selected edges and the midlle point of these points and "drills" a hole (diameter 8, depth 30) in the solid.

        [CommandMethod("TEST")]
        public static void Test()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            // Select a sub entity of a solid 3d
            var options = new PromptSelectionOptions();
            options.MessageForAdding = "\nSelect face of a solid";
            options.SingleOnly = true;
            options.SinglePickInSpace = true;
            options.ForceSubSelections = true;
            var filter = new SelectionFilter(new[] { new TypedValue(0, "3DSOLID") });
            var result = ed.GetSelection(options, filter);
            if (result.Status != PromptStatus.OK)
            {
                return;
            }
            var selectedObject = result.Value[0];
            var subSelectedObject = selectedObject.GetSubentities()[0];
            var subEntityType = subSelectedObject.FullSubentityPath.SubentId.Type;

            // Check if the sub entity is a face
            if (subEntityType != SubentityType.Face)
            {
                ed.WriteMessage($"\nSelected sub-entity is not a Face ({subEntityType})");
                return;
            }

            using (var tr = db.TransactionManager.StartTransaction())
            {
                var solidId = selectedObject.ObjectId;
                var solid = (Solid3d)tr.GetObject(solidId, OpenMode.ForRead);
                var subentityId = subSelectedObject.FullSubentityPath.SubentId;
                var facePath = new FullSubentityPath(new ObjectId[] { solid.ObjectId }, subentityId);
                var entityPath = new FullSubentityPath(new ObjectId[] { solid.ObjectId }, new SubentityId(SubentityType.Null, IntPtr.Zero));
                using (var brep = new Brep(entityPath))
                {
                    var face = brep.Faces.First(f => f.SubentityPath == facePath);

                    // Check if the face is planar
                    var boundedSurface = (ExternalBoundedSurface)face.Surface;
                    if (!boundedSurface.IsPlane)
                    {
                        ed.WriteMessage($"\nSelected Face is not planar");
                        return;
                    }

                    // Select the first edge
                    options.MessageForAdding = "\nSelect the first edge: ";
                    result = ed.GetSelection(options, filter);
                    if (result.Status != PromptStatus.OK)
                    {
                        return;
                    }
                    selectedObject = result.Value[0];
                    if (selectedObject.ObjectId != solidId)
                    {
                        ed.WriteMessage($"\nSelected Edge is not on same solid");
                        return;
                    }
                    subSelectedObject = selectedObject.GetSubentities()[0];
                    subEntityType = subSelectedObject.FullSubentityPath.SubentId.Type;

                    // Check if the sub entity is an edge
                    if (subEntityType != SubentityType.Edge)
                    {
                        ed.WriteMessage($"\nSelected sub-entity is not an Edge ({subEntityType})");
                        return;
                    }
                    subentityId = subSelectedObject.FullSubentityPath.SubentId;
                    var firstEdgePath = new FullSubentityPath(new ObjectId[] { solid.ObjectId }, subentityId);

                    // Check if the edge is on the face
                    var firstEdge = face.Loops.SelectMany(l => l.Edges).FirstOrDefault(e => e.SubentityPath == firstEdgePath);
                    if (firstEdge == null)
                    {
                        ed.WriteMessage($"\nSelected Edge is not on the face");
                        return;
                    }

                    // Select the second edge
                    options.MessageForAdding = "\nSelect the second edge: ";
                    result = ed.GetSelection(options, filter);
                    if (result.Status != PromptStatus.OK)
                    {
                        return;
                    }
                    selectedObject = result.Value[0];
                    if (selectedObject.ObjectId != solidId)
                    {
                        ed.WriteMessage($"\nSelected Edge is not on same solid");
                        return;
                    }
                    subSelectedObject = selectedObject.GetSubentities()[0];
                    subEntityType = subSelectedObject.FullSubentityPath.SubentId.Type;

                    // Check if the sub entity is an edge
                    if (subEntityType != SubentityType.Edge)
                    {
                        ed.WriteMessage($"\nSelected sub-entity is not an Edge ({subEntityType})");
                        return;
                    }
                    subentityId = subSelectedObject.FullSubentityPath.SubentId;
                    var secondEdgePath = new FullSubentityPath(new ObjectId[] { solid.ObjectId }, subentityId);

                    // Check if the edge is on the face
                    var secondEdge = face.Loops.SelectMany(l => l.Edges).FirstOrDefault(e => e.SubentityPath == secondEdgePath);
                    if (secondEdge == null)
                    {
                        ed.WriteMessage($"\nSelected Edge is not on the face");
                        return;
                    }

                    // Create the circle
                    var curve = ((ExternalCurve3d)firstEdge.Curve).NativeCurve;
                    var pt1 = curve.EvaluatePoint(
                        (curve.GetParameterOf(curve.EndPoint) - curve.GetParameterOf(curve.StartPoint)) / 2.0);
                    curve = ((ExternalCurve3d)secondEdge.Curve).NativeCurve;
                    var pt2 = curve.EvaluatePoint(
                        (curve.GetParameterOf(curve.EndPoint) - curve.GetParameterOf(curve.StartPoint)) / 2.0);
                    var center = new LineSegment3d(pt1, pt2).MidPoint;

                    // Get the Normal vector of the plane
                    var plane = (Plane)boundedSurface.BaseSurface;
                    var normal = plane.Normal;

                    // Negate the normal direction if it goes outside of the solid
                    var point = center + normal * 1e-6;
                    using (var brepFace = brep.GetPointContainment(point, out PointContainment containment))
                    {
                        if (containment == PointContainment.Outside)
                            normal = normal.Negate();
                    }

                    double radius = 4.0;
                    using (var circle = new Circle(center, normal, radius))
                    {
                        // Extrude the circle and substract it to the solid
                        using (var regions = Region.CreateFromCurves(new DBObjectCollection() { circle }))
                        using (var region = (Region)regions[0])
                        using (var hole = new Solid3d())
                        {
                            hole.Extrude(region, 30.0, 0.0);
                            tr.GetObject(selectedObject.ObjectId, OpenMode.ForWrite);
                            solid.BooleanOperation(BooleanOperationType.BoolSubtract, hole);
                        }
                    }
                }
                tr.Commit();
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 6 of 6
prahtYHGMJ
in reply to: _gile

prahtYHGMJ
Explorer
Explorer

Thank You, going to work on it on weekend.

0 Likes

Thank You, going to work on it on weekend.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report