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.
Solved! Go to Solution.
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.
Solved! Go to Solution.
Solved by _gile. Go to Solution.
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!
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!
Thank You very much, i can work from there.
Thank You very much, i can work from there.
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.
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.
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();
}
}
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();
}
}
Thank You, going to work on it on weekend.
Thank You, going to work on it on weekend.
Can't find what you're looking for? Ask the community or share your knowledge.