public static void AlignBlocks()
 {
     try {
         var options = new PromptEntityOptions("\nSelect polyline: ");
         options.SetRejectMessage("Objet non valide.");
         options.AddAllowedClass(typeof(Polyline), true);
         var result = Quick.Editor.GetEntity(options);
         if (result.Status != PromptStatus.OK)
         {
             return;
         }
         var lineId = result.ObjectId;
         var sel    = Quick.GetImpliedOrSelect();
         if (result.Status != PromptStatus.OK)
         {
             return;
         }
         var db = lineId.Database;
         foreach (var blockId in sel.GetObjectIds())
         {
             using (var trans = db.TransactionManager.StartTransaction()) {
                 try {
                     var line     = trans.GetObject(lineId, OpenMode.ForRead) as Polyline;
                     var blockRef = trans.GetObject(blockId, OpenMode.ForWrite) as BlockReference;
                     if (blockRef == null)
                     {
                         continue;
                     }
                     var blockpos = blockRef.Position;
                     // better use the center point, instead min/max
                     var pointOverLine = line.GetClosestPointTo(blockRef.Position, false);
                     //var vectorto = pointOverLine.GetVectorTo(blockRef.Position);
                     //var ang = vectorto.AngleOnPlane()
                     blockRef.Position = pointOverLine; // move
                     // assuming a well behaved 2D block aligned with XY
                     //Vector3d lineDirection = line.GetFirstDerivative(pointOverLine);
                     //double angleToRotate = Vector3d.XAxis.GetAngleTo(lineDirection, Vector3d.ZAxis);
                     //angel between block to the nearest point
                     var b2near = blockpos.Convert2d(new Plane()).GetVectorTo(pointOverLine.Convert2d(new Plane())).Angle *Rad2Deg;
                     //var pos1 = Math.Atan2(blockpos.Y - pointOverLine.Y, pointOverLine.X - blockpos.X) * Rad2Deg;
                     //var angeltoblock = lineDirection.GetAngleTo(blockRef.Position.GetAsVector())*Rad2Deg;
                     blockRef.Rotation = (b2near - 90) * Deg2Rad; //-90 to convert to block plane (0 is downwards).
                     trans.Commit();
                 } catch (Exception ex) {
                     Quick.WriteLine(ex.Message + "\n" + ex.StackTrace);
                 }
             }
         }
         Quick.SetSelected(sel);
     } catch (Exception ex) {
         Quick.WriteLine(ex.Message + "\n" + ex.StackTrace);
     }
 }
        /// <summary>
        ///     Shifts on line from a specific point for <paramref name="distance"/> length.<br></br>Returns true if successful, false if exceeded the limits - will return basepoint!
        /// </summary>
        /// <param name="ent">Ent</param>
        /// <param name="basepoint">the point to offset from</param>
        /// <param name="distance">The distance to offset</param>
        /// <returns>true if successful, false if exceeded the limits - will return basepoint!</returns>
        public static Tuple <Point2d, bool> OffsetToEnd(this Curve ent, Point2d basepoint, double distance)
        {
            var basepoint3 = ent.GetClosestPointTo(basepoint.ToPoint3D(), true);

            basepoint = basepoint3.ToPoint2D();
            try {
                var dis   = ent.GetDistAtPoint(basepoint3);
                var extra = dis + distance;
                var pt    = ent.GetPointAtDist(extra);
                return(Tuple.Create(pt.ToPoint2D(), true));
            } catch (Exception e) {
                Quick.WriteLine("\nInvalid Input, offset exceeds curve's limits.\n" + e);
                return(Tuple.Create(basepoint, false));
            }
        }
        public static void SelectInsideIntersectCommand()
        {
            var _e = new Point3d(double.MinValue, double.MinValue, double.MinValue);

            try {
                var imp = Quick.GetImpliedOrSelect();
                if (imp == null)
                {
                    Quick.WriteLine("[sii] No objects were selected.");
                    return;
                }
                var options = new PromptEntityOptions("\nSelect a point on a polyline: ");
                options.SetRejectMessage("Invalid Object.");
                options.AddAllowedClass(typeof(Curve), false);
                options.AllowObjectOnLockedLayer = false;

                var result = Quick.Editor.GetEntity(options);
                if (result.Status != PromptStatus.OK)
                {
                    return;
                }
                var curveId = result.ObjectId;

                using (var tr = new QuickTransaction()) {
                    var pl = (Polyline)tr.GetObject(curveId, OpenMode.ForRead, false);
                    var c  = imp.GetObjectIds()
                             .Select(o => tr.GetObject(o, OpenMode.ForRead, true))
                             .AreInsidePolyline(tr, pl)
                             .ToArray()
                             .ToSelectionSet()
                             .SetSelected();

                    /*var rest = c.Cast<DBObject>()
                     *  .IntersectBy(imp.Cast<SelectedObject>().Select(o=>tr.GetObject(o.ObjectId,false)).ToArray(), o => o.ObjectId.Handle.Value)
                     *  .Select(o => o.ObjectId)
                     *  .ToSelectionSet(SelectionMethod.Crossing)
                     *  .SetSelected();
                     */
                    //ent.BreakOnPoint(result.PickedPoint.ToPoint2D(), tr, true).SetSelected();
                }
            } catch (Autodesk.AutoCAD.Runtime.Exception ex) {
                Autodesk.AutoCAD.ApplicationServices.Core.Application.ShowAlertDialog(ex.Message + "\n" + ex.StackTrace);
            }
        }
        public static void WindowSwapCommand()
        {
            var imp = Quick.GetImpliedOrSelect();

            if (imp == null)
            {
                Quick.WriteLine("[ws] No objects were selected.");
                return;
            }
            var all = Quick.SelectAll();

            if (all == null)
            {
                Quick.WriteLine("[ws] Failed selecting All.");
                return;
            }
            var rest = all.Cast <SelectedObject>().ExceptBy(imp.Cast <SelectedObject>(), o => o.ObjectId.Handle.Value).Select(o => o.ObjectId).ToSelectionSet(SelectionMethod.Crossing);

            Quick.SetSelected(rest);
        }
        public static void AlignBlockCommand()
        {
            var options = new PromptEntityOptions("\nSelect polyline: ");

            options.SetRejectMessage("Objet non valide.");
            options.AddAllowedClass(typeof(Polyline), true);
            var result = Quick.Editor.GetEntity(options);

            if (result.Status != PromptStatus.OK)
            {
                return;
            }
            var lineId = result.ObjectId;

            options.Message = "\nSelect block: ";
            options.RemoveAllowedClass(typeof(Polyline));
            options.AddAllowedClass(typeof(BlockReference), true);
            result = Quick.Editor.GetEntity(options);
            if (result.Status != PromptStatus.OK)
            {
                return;
            }
            var blockId = result.ObjectId;
            var db      = lineId.Database;

            using (var trans = db.TransactionManager.StartTransaction()) {
                try {
                    var line          = trans.GetObject(lineId, OpenMode.ForRead) as Polyline;
                    var blockRef      = trans.GetObject(blockId, OpenMode.ForWrite) as BlockReference;
                    var blockpos      = blockRef.Position;
                    var pointOverLine = line.GetClosestPointTo(blockRef.Position, false);
                    blockRef.Position = pointOverLine; // move
                    //angel between block to the nearest point
                    var b2near = blockpos.Convert2d(new Plane()).GetVectorTo(pointOverLine.Convert2d(new Plane())).Angle *Rad2Deg;
                    blockRef.Rotation = (b2near - 90) * Deg2Rad; //-90 to convert to block plane (0 is downwards).
                    trans.Commit();
                } catch (Exception ex) {
                    Quick.WriteLine(ex.Message + "\n" + ex.StackTrace);
                }
            }
        }
        public static void WidthCommand()
        {
            var set = Quick.GetImpliedOrSelect();

            if (set == null || set.Count == 0)
            {
                Quick.WriteLine($"[{Quick.CurrentCommand}] No objects were selected.");
                return;
            }

            using (var tr = new QuickTransaction()) {
                var col = set.GetObjectIds().Select(o => tr.GetObject(o, true)).ToArray();
                var dbl = Quick.Editor.GetDouble(new PromptDoubleOptions("Please select width: ")
                {
                    AllowNegative = false, DefaultValue = Quick.Bag.Get("[w]width", 0.4d)
                });
                if (dbl.Status != PromptStatus.OK)
                {
                    Quick.WriteLine($"[{Quick.CurrentCommand}] Failed selecting double.");
                    return;
                }
                var val = (double)(Quick.Bag["[w]width"] = dbl.Value);
                //tr.Command("_.pedit", "_m", set, "_n", "_w", dbl.Value.ToString(), "");
                for (var i = 0; i < col.Length; i++)
                {
                    var e  = col[i];
                    var ee = e;
                    if (ee is Polyline2d)
                    {
                        ee     = ee.ConvertToPolyline(tr);
                        col[i] = ee;
                    }
                    if (ee is Polyline == false)
                    {
                        continue;
                    }
                    ((Polyline)ee).SetGlobalWidth(val);
                }
                tr.Commit();
            }
        }
        public static void WindowOnlyInsideCommand()
        {
            var imp = Quick.GetImpliedOrSelect();

            if (imp == null)
            {
                Quick.WriteLine("[ww] No objects were selected.");
                return;
            }
            Quick.ClearSelected();
            var all = Quick.GetImpliedOrSelect();

            if (all == null)
            {
                Quick.WriteLine("[ww] Failed selecting Other.");
                return;
            }
            var rest = all.Cast <SelectedObject>().IntersectBy(imp.Cast <SelectedObject>(), o => o.ObjectId.Handle.Value).Select(o => o.ObjectId).ToSelectionSet(SelectionMethod.Crossing);

            Quick.SetSelected(rest);
        }
 public static void MRotateCommand()
 {
     using (var tr = new QuickTransaction()) {
         // objects initializing
         var nomutt = Convert.ToInt32(Autodesk.AutoCAD.ApplicationServices.Core.Application.GetSystemVariable("nomutt"));
         try {
             // Get the current document and database
             // Start a transaction
             // Open the Block table for read
             var _sel = Quick.GetImpliedOrSelect();
             if (_sel == null || _sel.Count == 0)
             {
                 tr.Editor.WriteMessage("Nothing was selected.");
                 return;
             }
             var howmuch = tr.Editor.GetAngle("How many degrees (Anti Clockwise) to add (Negative will go Clockwise)");
             if (howmuch.Status == PromptStatus.Cancel)
             {
                 return;
             }
             var curUCSMatrix = tr.Doc.Editor.CurrentUserCoordinateSystem;
             var curUCS       = curUCSMatrix.CoordinateSystem3d;
             foreach (SelectedObject o in _sel)
             {
                 var obj    = (BlockReference)tr.GetObject(o.ObjectId) ?? throw new NullReferenceException("obj");
                 var matrix = Matrix3d.Rotation(howmuch.Value, curUCS.Zaxis, obj.Position);
                 obj.TransformBy(matrix);
             }
             // Add the new object to the block table record and the transaction
             // Save the new objects to the database
             tr.Commit();
             Quick.SetSelected(_sel);
         } catch (Exception ex) {
             Quick.WriteLine(ex.Message + "\n" + ex.StackTrace);
         } finally {
             Autodesk.AutoCAD.ApplicationServices.Core.Application.SetSystemVariable("nomutt", nomutt);
         }
     }
 }
        public static void AddCurveCommand()
        {
            double GetAngle(Point2d a, Point2d b)
            {
                double xDiff = b.X - a.X;
                double yDiff = b.Y - a.Y;

                return(Math.Atan2(yDiff, xDiff) * 180.0d / Math.PI);
            }

            try {
                var options = new PromptEntityOptions("\nSelect a point on a polyline: ");
                options.SetRejectMessage("Invalid Object.");
                options.AddAllowedClass(typeof(Polyline), true);
                options.AddAllowedClass(typeof(Polyline2d), true);
                options.AddAllowedClass(typeof(Polyline3d), true);

                var result = Quick.Editor.GetEntity(options);
                if (result.Status != PromptStatus.OK)
                {
                    return;
                }
                var lineId    = result.ObjectId;
                var pickpoint = result.PickedPoint.ToPoint2D();
                var qtarget   = Quick.Editor.GetPoint(new PromptPointOptions("Pick the strech point.")
                {
                    AllowNone = false, BasePoint = pickpoint.ToPoint3D(), UseBasePoint = true, UseDashedLine = true
                });
                if (qtarget.Status != PromptStatus.OK)
                {
                    return;
                }
                var target = qtarget.Value.ToPoint2D();
                using (var tr = new QuickTransaction()) {
                    try {
                        var poly = (Curve)tr.GetObject(lineId, OpenMode.ForWrite);
                        if (poly is Polyline2d)
                        {
                            poly = poly.ConvertToPolyline(tr);
                        }
                        if (poly is Polyline3d)
                        {
                            throw new InvalidCastException("Can't be applied on polyline of type Polyline3d.");
                        }
                        var distance = target.GetDistanceTo(pickpoint);

                        var pointRight = poly.OffsetToEnd(result.PickedPoint, distance);
                        var pointLeft  = poly.OffsetToStart(result.PickedPoint, distance);
                        if (!pointRight.Item2 || !pointLeft.Item2)
                        {
                            return;
                        }

                        var rightcut = poly.BreakOnPoint(pointRight.Item1, tr, false);
                        poly = (Polyline)rightcut[0];  //right poly
                        var rightpoly = (Polyline)rightcut[1];
                        var leftcut   = poly.BreakOnPoint(pointLeft.Item1, tr, false);
                        var leftpoly  = (Polyline)leftcut[0];
                        leftcut[1].UpgradeOpen();
                        leftcut[1].Erase();

                        var buldge = Math.Tan((90d * 0.85 * Deg2Rad) / 4);
                        leftpoly.AddVertexAt(leftpoly.NumberOfVertices, target, 0, leftpoly.GetStartWidthAt(leftpoly.NumberOfVertices - 1), leftpoly.GetEndWidthAt(leftpoly.NumberOfVertices - 1));
                        leftpoly.SetBulgeAt(leftpoly.NumberOfVertices - 2, buldge);
                        rightpoly.AddVertexAt(0, target, buldge, leftpoly.GetStartWidthAt(0), leftpoly.GetEndWidthAt(0));

                        void setdir(bool right)
                        {
                            if (right)
                            {
                                leftpoly.SetBulgeAt(leftpoly.NumberOfVertices - 2, buldge);
                                rightpoly.SetBulgeAt(0, buldge);
                            }
                            else
                            {
                                leftpoly.SetBulgeAt(leftpoly.NumberOfVertices - 2, -buldge);
                                rightpoly.SetBulgeAt(0, -buldge);
                            }
                        }

                        setdir(Settings.addcurve_direction as bool? ?? true);

                        tr.Transaction.TransactionManager.QueueForGraphicsFlush();

                        // ReSharper disable once AssignmentInConditionalExpression
                        var ask = (bool?)Quick.AskQuestion("Reverse Direction?", false) ?? false;
                        if (ask)
                        {
                            Settings.addcurve_direction = !(Settings.addcurve_direction as bool? ?? false);
                            setdir(Settings.addcurve_direction);
                        }
                        tr.Transaction.TransactionManager.QueueForGraphicsFlush();


                        // ReSharper disable once AssignmentInConditionalExpression
                        if (Settings["addcurve_join"] = Quick.AskQuestion("Join Polylines?", (Settings["addcurve_join"]) ?? !true))
                        {
                            new[] { leftpoly.Join(rightpoly, tr) }.SetSelected();
                        }
                        else
                        {
                            new[] { leftpoly, rightpoly }.SetSelected();
                        }
                        tr.Commit();
                    } catch (Exception ex) {
                        Quick.WriteLine(ex.Message + "\n" + ex.StackTrace);
                    }
                }
            } catch (Exception ex) {
                Quick.WriteLine(ex.Message + "\n" + ex.StackTrace);
            }
        }