/// <summary> /// /// </summary> /// <param name="doc"></param> /// <returns></returns> public static bool RunCommand(Document doc) { ObjectId polylineId = GetPolyline(doc.Editor); if (polylineId == ObjectId.Null) { return(false); } int numberOfFloors = 0; if (!GetNumberOfFloors(doc.Editor, ref numberOfFloors)) { return(false); } double floorHeight = 0; if (!GetFloorHeight(doc.Editor, ref floorHeight)) { return(false); } double buildingHeight = floorHeight * numberOfFloors; if (buildingHeight < 0.0001) { return(false); } using (Transaction tr = doc.Database.TransactionManager.StartTransaction()) { BlockTable bt = tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord ms = tr.GetObject(doc.Database.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; Polyline pl = tr.GetObject(polylineId, OpenMode.ForRead) as Polyline; doc.Editor.WriteMessage($"Selected polyline with surface: {pl.Area.ToString("0.00")} m2\n"); Solid3d solid = new Solid3d(); ms.AppendEntity(solid); tr.AddNewlyCreatedDBObject(solid, true); Line l = new Line() { StartPoint = pl.StartPoint, EndPoint = pl.StartPoint.Add(new Vector3d(0, 0, buildingHeight)) }; SweepOptionsBuilder sob = new SweepOptionsBuilder(); sob.Align = SweepOptionsAlignOption.AlignSweepEntityToPath; sob.BasePoint = l.StartPoint; solid.CreateSweptSolid(pl, l, sob.ToSweepOptions()); doc.Editor.WriteMessage($"Created Solid with volume: {(solid.MassProperties.Volume).ToString("0.000")}m3\n"); l.Dispose(); tr.Commit(); } return(true); }
private bool GenerateTube( double profRad, Point3dCollection pts, out Solid3d sol ) { bool readyToBreak; // Let's start by creating our spline path using (Spline path = new Spline(pts, 0, 0.0)) { double pathLen = path.GetDistanceAtParameter(path.EndParam); readyToBreak = (pathLen > _profSide * _segFactor); // And our sweep profile Circle profile = new Circle(pts[0], pts[1] - pts[0], profRad); using (profile) { // Then our sweep options SweepOptionsBuilder sob = new SweepOptionsBuilder(); // Align the entity to sweep to the path sob.Align = SweepOptionsAlignOption.AlignSweepEntityToPath; // The base point is the start of the path sob.BasePoint = path.StartPoint; // The profile will rotate to follow the path sob.Bank = true; using (SweepOptions sweepOpts = sob.ToSweepOptions()) { sol = new Solid3d(); sol.ColorIndex = ColorIndex; // Sweep our profile along our path sol.CreateSweptSolid(profile, path, sweepOpts); } } } _lastDrawnVertex = pts.Count - 1; return(readyToBreak); }
public static Solid3d CreateStair3D(int steps, double riser, double tread, double landing, double width, double slope) { Solid3d stair3d = new Solid3d { RecordHistory = true }; Polyline pline = CreateStairPolyline(steps, riser, tread, landing, slope); Polyline path = MyFunctions.CreateStairSweepPath(width); stair3d.CreateSweptSolid(pline, path, MyFunctions.CreateSweepOptions(path).ToSweepOptions()); return(stair3d); }
private bool GenerateTube( double profRad, Point3dCollection pts, out Solid3d sol ) { bool readyToBreak; // Let's start by creating our spline path using (Spline path = new Spline(pts, 0, 0.0)) { double pathLen = path.GetDistanceAtParameter(path.EndParam); readyToBreak = (pathLen > _profSide * _segFactor); // And our sweep profile Circle profile = new Circle(pts[0], pts[1] - pts[0], profRad); using (profile) { // Then our sweep options SweepOptionsBuilder sob = new SweepOptionsBuilder(); // Align the entity to sweep to the path sob.Align = SweepOptionsAlignOption.AlignSweepEntityToPath; // The base point is the start of the path sob.BasePoint = path.StartPoint; // The profile will rotate to follow the path sob.Bank = true; using (SweepOptions sweepOpts = sob.ToSweepOptions()) { sol = new Solid3d(); sol.ColorIndex = ColorIndex; // Sweep our profile along our path sol.CreateSweptSolid(profile, path, sweepOpts); } } } _lastDrawnVertex = pts.Count - 1; return readyToBreak; }
public void drawSpring() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //??ask about gauge of spring back vs seat //seat 8 gauge .1285" //back 12 gauge .0808" #region get ends of spring to get total distance //ask user for points for spring to exist PromptPointOptions ppo = new PromptPointOptions("First end of spring:"); PromptPointResult ppr = ed.GetPoint(ppo); if (ppr.Status != PromptStatus.OK) { return; } Point3d startPoint = ppr.Value; ppo.Message = "Second end of spring"; ppr = ed.GetPoint(ppo); if (ppr.Status != PromptStatus.OK) { return; } //calculate distance from chosen points #endregion double totalLength = startPoint.DistanceTo(ppr.Value); #region get spring Type (length) //given total length, calculate ideal spring length which is total minus some percentage double theorySpgLength = (Math.Round(.9 * totalLength * 2)) / 2; //find the nearest spring length that is less than or equal to total length(springs tend to come in 1/2" increments) //compare to list of spring lengths in stock **(eventually get springs from SQL) //present any springs withen an accaptable margin of diviation (maybe 8%)?? //if none are easily exceptable but might work within a special circumstance, present that with warning (10%)?? //if none are accaptable at all, then give different warning and end command (user will need to move spring rail or order diff springs) //**idealy replace with a user dialoge to choose from springs in system //ask user for spring length desired(may prompt with options from list) based on orignal distance PromptDoubleOptions pdo = new PromptDoubleOptions("Enter spring length:"); //needs to pull these dynamically*************** pdo.Keywords.Add(theorySpgLength.ToString()); pdo.Keywords.Add((theorySpgLength - .5).ToString()); PromptDoubleResult pdr = ed.GetDouble(pdo); if (pdr.Status != PromptStatus.OK) { return; } #endregion double springLength = pdr.Value; #region Create top view of spring //1 Calculate rungs //spring length / average gap int rungCount = Convert.ToInt32(springLength / .875);//guessing at the avg rung gap for starters double rungGap = totalLength / rungCount; double rungWidth = 2 - rungGap; //springs tend to be approx 2" wide //rung widths are 2" - rung gap (the two radii of bends) //add all parts to object collection then convert to polyline DBObjectCollection springParts = new DBObjectCollection(); //construct first rung (has hooked end) springParts = createEnd(springParts, startPoint, rungGap, rungWidth, true, true); //construct rungs/bends in middle //and bends on alternating runs for (int i = 0; i < rungCount; i++) { Line rung = new Line( new Point3d(startPoint.X - rungWidth / 2, startPoint.Y + i * rungGap, startPoint.Z), new Point3d(startPoint.X + rungWidth / 2, startPoint.Y + i * rungGap, startPoint.Z)); //add rungs except for either end if (i != 0 && i != rungCount) { springParts.Add(rung); } //add bends to either side depending on if it is an even or odd rung if (i % 2 == 0) { //even Arc leftBend = new Arc(new Point3d(startPoint.X - 1 + rungGap / 2, startPoint.Y + rungGap * i + rungGap / 2, startPoint.Z), rungGap / 2, Math.PI / 2, 3 * Math.PI / 2); springParts.Add(leftBend); } else { //odd Arc rightBend = new Arc(new Point3d(startPoint.X + 1 - rungGap / 2, startPoint.Y + rungGap * i + rungGap / 2, startPoint.Z), rungGap / 2, 3 * Math.PI / 2, Math.PI / 2); springParts.Add(rightBend); } } //construct end //if rungCount is even it opens same as first bool secondOpen = true; if (rungCount % 2 == 0) { secondOpen = false; } springParts = createEnd(springParts, new Point3d(startPoint.X, startPoint.Y + totalLength, startPoint.Z), rungGap, rungWidth, secondOpen, false); ////just for testing ** //using (Transaction trans = db.TransactionManager.StartTransaction()) //{ // BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable; // BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // foreach (DBObject dbo in springParts) // { // Entity ent = dbo as Entity; // btr.AppendEntity(ent); // trans.AddNewlyCreatedDBObject(ent, true); // } // trans.Commit(); //} Polyline pLine = BuildPLine.drawPolyLine(springParts); //move spring polyline to the correct Z coordinate, converting to a polyline cuts off z coords leaving it at 0**** //*************************** #endregion #region create side view (crown) //need to account for creating arc along different plane //arc is start point, and then total length vertical from first point (same plane) *we'll rotate later //for now all springs will use same crown, need a formula later and need an element that accounts for flat vs curly springs //create arc flat along same plane as spring polyline, then rotate it?? Arc crown = new Arc(); Point3d startArc = new Point3d(startPoint.X - 2, startPoint.Y, startPoint.Z); Point3d endArc = new Point3d(startArc.X, startArc.Y + totalLength, startArc.Z); Point3d arcMid = new Point3d(startArc.X - 1.5, startArc.Y + (totalLength / 2), startArc.Z); //assuming crown is 1.5 until we derive a diff system //radius = height/2 + width^2/height(8) crown.Radius = .75 + (Math.Pow(startArc.DistanceTo(endArc), 2) / 12); //given that we always will have our arc aligned vertically center is easter to calculate crown.Center = new Point3d(arcMid.X + crown.Radius, arcMid.Y, arcMid.Z); Matrix3d ocs2wcs = Matrix3d.PlaneToWorld(crown.Normal); Plane plane = new Plane(ocs2wcs.CoordinateSystem3d.Origin, ocs2wcs.CoordinateSystem3d.Xaxis, ocs2wcs.CoordinateSystem3d.Yaxis); //need start and end angles //double startAngle = tanAngle(arcCenter, startArc); //double endAngle = tanAngle(arcCenter, endArc); crown.EndAngle = (startArc - crown.Center).AngleOnPlane(plane); crown.StartAngle = (endArc - crown.Center).AngleOnPlane(plane); //Arc crown = new Arc(arcCenter,radius,startAngle,endAngle); // Rotate the 3D solid 30 degrees around the axis that is defined by the points Vector3d turnArc = crown.StartPoint.GetVectorTo(crown.EndPoint); crown.TransformBy(Matrix3d.Rotation(3 * (Math.PI / 2), turnArc, crown.StartPoint)); #endregion //convert collection to polyline using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable; BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //Have to have both views inserted to turn into extruded surface btr.AppendEntity(pLine); tr.AddNewlyCreatedDBObject(pLine, true); btr.AppendEntity(crown); tr.AddNewlyCreatedDBObject(crown, true); #region Extrude surfaces from open curves, polylines //extrude two shapes Profile3d profileCrown = new Profile3d(crown); Profile3d profileSpring = new Profile3d(pLine); Vector3d polylineDir = new Vector3d(0, 0, 4); Vector3d crownDir = (crown.StartPoint).GetVectorTo(new Point3d(crown.StartPoint.X + 4, crown.StartPoint.Y, crown.StartPoint.Z)); SweepOptions sweepOp = new SweepOptions(); //need a different vector for crown ObjectId surfaceId = Autodesk.AutoCAD.DatabaseServices.Surface.CreateExtrudedSurface( profileCrown, crownDir, sweepOp, true); ObjectId surfaceSpringId = Autodesk.AutoCAD.DatabaseServices.Surface.CreateExtrudedSurface( profileSpring, polylineDir, sweepOp, true); //remove original lines pLine.Erase(true); crown.Erase(true); #endregion //intersect both regions(observe how extrusions work with ucs) Autodesk.AutoCAD.DatabaseServices.Surface crownEnt = tr.GetObject(surfaceId, OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.Surface; Autodesk.AutoCAD.DatabaseServices.Surface springEnt = tr.GetObject(surfaceSpringId, OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.Surface; //convert both surfaces to nurbs //the polyline extrusion creates many surfaces in nurb form, loop through intersections creating splines and lines springParts = Intersect_Surfaces.IntersectSurf(crownEnt, springEnt); //delete surfaces crownEnt.Erase(true); springEnt.Erase(true); //join intersection pieces as spline (maynot be possible) //convert collection of splines/lines to single 3Dspline Spline springSpline = Intersect_Surfaces.mergeSpline(springParts); btr.AppendEntity(springSpline); tr.AddNewlyCreatedDBObject(springSpline, true); //loft along spline try { //create circle to to sweep Circle wireGauge = new Circle(); wireGauge.Center = springSpline.StartPoint; wireGauge.Radius = .06425;//diameter .1285 //Entity sweepEnt = tr.GetObject(); Curve pathEnt = tr.GetObject(springSpline.Id, OpenMode.ForRead) as Curve; //Curve pathEnt = tr.GetObject(pLine.Id, OpenMode.ForRead) as Curve; if (wireGauge == null || pathEnt == null) { ed.WriteMessage("\nProblem getting spline made"); return; } //builder object to create sweepoptions SweepOptionsBuilder sob = new SweepOptionsBuilder(); //align the entity to sweep to the path sob.Align = SweepOptionsAlignOption.AlignSweepEntityToPath; //the base point is the start of the path sob.BasePoint = pathEnt.StartPoint; //the profile will rotate to follow the path sob.Bank = true; Entity ent; Solid3d sol = new Solid3d(); sol.CreateSweptSolid(wireGauge, pathEnt, sob.ToSweepOptions()); ent = sol; //and add it to the modelspace btr.AppendEntity(ent); tr.AddNewlyCreatedDBObject(ent, true); } catch { } //re-align spring to first points chosen by user tr.Commit(); } }
public void Cmd_WeldBead() { if (!LicensingAgent.Check()) { return; } var acCurDoc = Application.DocumentManager.MdiActiveDocument; var acCurDb = acCurDoc.Database; var acCurEd = acCurDoc.Editor; //Prompt user to select a 3dFace var userSel = acCurEd.SelectSubentities(SubentityType.Edge); if (userSel.Count <= 0) { return; } var wSize = acCurEd.GetPositiveDouble("\nEnter weld bead size: ", SettingsUser.WeldBeadSize); SettingsUser.WeldBeadSize = wSize; using (var acTrans = acCurDb.TransactionManager.StartTransaction()) { foreach (var pair in userSel) { var acSol = acTrans.GetObject(pair.Item1, OpenMode.ForRead) as Solid3d; if (acSol == null) { continue; } foreach (var subId in pair.Item2) { var c = acSol.GetSubentity(subId) as Curve; using (var weldBead = new Circle(c.StartPoint, Vector3d.XAxis, wSize / 2)) { acCurDb.AppendEntity(weldBead); var sOptsBuilder = new SweepOptionsBuilder { Align = SweepOptionsAlignOption.AlignSweepEntityToPath, BasePoint = weldBead.Center }; var dSol = new Solid3d(); acCurDb.AddLayer(SettingsUser.RcWelds, Colors.LayerColorWelds, SettingsUser.RcWeldsLt, acTrans); dSol.Layer = SettingsUser.RcWelds; dSol.Linetype = SettingsUser.RcWeldsLt; dSol.Transparency = new Transparency(75); dSol.CreateSweptSolid(weldBead, c, sOptsBuilder.ToSweepOptions()); acCurDb.AppendEntity(dSol, acTrans); weldBead.Erase(); } } acTrans.Commit(); } } }
protected override bool WorldDrawData(WorldDraw draw) { if (!base.WorldDrawData(draw)) { return(false); } short origCol = draw.SubEntityTraits.Color; // If we're currently drawing... if (_drawing) { try { // Let's start by creating our spline path if ((_path == null && _vertices.Count > 1) || (_path != null && _vertices.Count > _path.NumFitPoints)) { if (_path != null) { _path.Dispose(); } _path = new Spline(_vertices, 0, 0.0); // And our sweep profile, if we don't have one if (_profile != null) { _profile.Dispose(); } _profile = new Circle( _vertices[0], _vertices[1] - _vertices[0], _profRad ); // And our sweep options, if we don't have one if (_sweepOpts == null) { var sob = new SweepOptionsBuilder(); // Align the entity to sweep to the path sob.Align = SweepOptionsAlignOption.AlignSweepEntityToPath; // The base point is the start of the path sob.BasePoint = _path.StartPoint; // The profile will rotate to follow the path sob.Bank = true; _sweepOpts = sob.ToSweepOptions(); } // Finally create a blank solid, if it's null if (_tube == null) { _tube = new Solid3d(); } // And sweep our profile along our path _tube.CreateSweptSolid(_profile, _path, _sweepOpts); } } catch (Autodesk.AutoCAD.Runtime.Exception ex) { _sweepBroken = true; _tube.Dispose(); _tube = null; _doc.Editor.WriteMessage( "\nException: {0}", ex.Message ); } // Draw our path, if we have one if (_path != null) { draw.SubEntityTraits.Color = transPathColor; _path.WorldDraw(draw); } // And our solid if (_tube != null) { draw.SubEntityTraits.Color = transSolColor; _tube.WorldDraw(draw); } if (_vertices.Count > 0) { // Get the last point (at which our cursor should // be located, if it exists) var lastPt = _vertices[_vertices.Count - 1]; if (_cursor == null) { // Create a cursor sphere _cursor = new Solid3d(); ((Solid3d)_cursor).CreateSphere(_profRad); _curPt = Point3d.Origin; } // Move it to the current point _cursor.TransformBy( Matrix3d.Displacement(lastPt - _curPt) ); _curPt = lastPt; // Draw the cursor draw.SubEntityTraits.Color = (_sweepBroken ? transPathColor : transSolColor); _cursor.WorldDraw(draw); } } draw.SubEntityTraits.Color = origCol; return(true); }
public void Cmd_DogEar() { if (!LicensingAgent.Check()) { return; } var acCurDoc = Application.DocumentManager.MdiActiveDocument; var acCurDb = acCurDoc.Database; var acCurEd = acCurDoc.Editor; //Call user to select a face var sweepSel = acCurEd.SelectSubentity(SubentityType.Edge, "\nSelect EDGE to use as cutting path: "); if (sweepSel == null) { return; } if (sweepSel.Item1 == ObjectId.Null) { return; } if (sweepSel.Item2 == SubentityId.Null) { return; } //Call user to select a face var dirSel = acCurEd.SelectSubentity(SubentityType.Edge, "\nSelect EDGE to cut dog ear into: "); if (dirSel == null) { return; } if (dirSel.Item1 == ObjectId.Null) { return; } if (dirSel.Item2 == SubentityId.Null) { return; } //Get the Joint depth from the user var userDistOpt = new PromptDistanceOptions(string.Empty) { DefaultValue = SettingsUser.DogEarDiam, UseDefaultValue = true, Message = "\n Enter drill diameter: ", AllowNone = false, AllowNegative = false, AllowZero = false }; //Set the join depth var distRes = acCurEd.GetDistance(userDistOpt); if (distRes.Status != PromptStatus.OK) { return; } SettingsUser.DogEarDiam = distRes.Value; //Open a transaction using (var acTrans = acCurDb.TransactionManager.StartTransaction()) { var acSol = acTrans.GetObject(sweepSel.Item1, OpenMode.ForWrite) as Solid3d; var solPath = new FullSubentityPath(new[] { acSol.ObjectId }, new SubentityId(SubentityType.Null, IntPtr.Zero)); var sweepSubId = sweepSel.Item2; var dirSubId = dirSel.Item2; VertExt sweepInfo1 = null; VertExt sweepInfo2 = null; VertExt dirInfo1 = null; VertExt dirInfo2 = null; using (var brep = new Brep(solPath)) { foreach (var face in brep.Faces) { foreach (var loop in face.Loops) { foreach (var edge in loop.Edges) { var eId = edge.SubentityPath.SubentId; if (sweepSubId == eId) { sweepInfo1 = new VertExt(edge.Vertex1, loop); sweepInfo2 = new VertExt(edge.Vertex2, loop); } else if (dirSubId == eId) { dirInfo1 = new VertExt(edge.Vertex1, loop); dirInfo2 = new VertExt(edge.Vertex2, loop); } } } } } if (sweepInfo1 != null && sweepInfo2 != null && dirInfo1 != null && dirInfo2 != null) { var cutDiam = SettingsUser.DogEarDiam; var cutRad = cutDiam / 2; var sw1 = sweepInfo1.VertPoint; var sw2 = sweepInfo2.VertPoint; var dr1 = dirInfo1.VertPoint; var dr2 = dirInfo2.VertPoint; var rotAxis = sw1.GetVectorTo(sw2); var vertsMatch = false; while (!vertsMatch) { if (sw1 == dr1) { vertsMatch = true; continue; } if (sw1 == dr2) { var tempExt = dr1; dr1 = dr2; dr2 = tempExt; continue; } if (sw2 == dr1) { var tempExt = sw1; sw1 = sw2; sw2 = tempExt; continue; } if (sw2 == dr2) { var tempExt = dr1; dr1 = dr2; dr2 = tempExt; tempExt = sw1; sw1 = sw2; sw2 = tempExt; continue; } acTrans.Abort(); return; } var dr3 = dr1.GetAlong(dr2, cutDiam); using (var pathLine = new Line(sw1, sw2)) { using (var cutCirc = new Circle(dr1.GetMidPoint(dr3), rotAxis, cutRad)) { acCurDb.AppendEntity(pathLine); acCurDb.AppendEntity(cutCirc); var sOptsBuilder = new SweepOptionsBuilder { Align = SweepOptionsAlignOption.NoAlignment, BasePoint = cutCirc.Center, Bank = true }; using (var dSol = new Solid3d()) { dSol.CreateSweptSolid(cutCirc, pathLine, sOptsBuilder.ToSweepOptions()); acSol.BooleanOperation(BooleanOperationType.BoolSubtract, dSol); } pathLine.Erase(); cutCirc.Erase(); } } } acTrans.Commit(); } }