private void bPulling_Click(object sender, EventArgs e) { if (_isPullingActive) { return; } var objectIds = Interaction.GetPickSet(); if (objectIds.Length == 0) { Acad.Alert($"Выделите притягиваемые кривые"); return; } lPulling.Text = $"Включен режим притягивания {objectIds.Length} объектов"; Acad.Editor.SetImpliedSelection(Array.Empty <ObjectId>()); App.LockAndExecute(() => Interaction.HighlightObjects(objectIds)); Acad.Write($"Выполняется притягивание {objectIds.Length} объектов"); _isPullingActive = true; while (true) { Interaction.SetActiveDocFocus(); var sideId = Interaction.GetEntity("\nВыберите притягиваемую сторону", typeof(Line)); if (sideId == ObjectId.Null) { break; } if (!objectIds.Contains(sideId)) { Acad.Write($"Притягиваемая сторона должна быть из числа притягиваемых кривых"); continue; } Acad.Editor.SetImpliedSelection(new ObjectId[] { sideId }); var guideId = Interaction.GetEntity("\nВыберите отрезок к которому выполнить притягивание", typeof(Line)); if (guideId == ObjectId.Null) { break; } Line guide = guideId.QOpenForRead <Line>(); Line side = sideId.QOpenForRead <Line>(); var isObjLeft = !side.IsTurnRight(objectIds.GetCenter()); double.TryParse(tbDist.Text, out double dist); var normalVector = guide.Delta.GetNormal().GetPerpendicularVector() * dist; if (cbMove.Checked) { Interaction.SetActiveDocFocus(); using (Acad.ActiveDocument.LockDocument()) { Interaction.HighlightObjects(new[] { guideId }); Acad.Editor.SetImpliedSelection(objectIds); PromptSelectionResult psr = Acad.Editor.SelectImplied(); PromptPointResult ppr = Acad.Editor.Drag(psr.Value, "\nУкажите точку вставки объектов: ", (Point3d pt, ref Matrix3d mtx) => { mtx = CalcMatrix(pt, guide, side, normalVector, isObjLeft); return(SamplerStatus.OK); }); if (ppr.Status == PromptStatus.OK) { var matrix = CalcMatrix(ppr.Value, guide, side, normalVector, isObjLeft); objectIds.QForEach <Entity>(dbobject => dbobject.TransformBy(matrix)); } App.LockAndExecute(() => Interaction.UnhighlightObjects(new ObjectId[] { guideId })); } } else { var mt = CalcMatrix(side.StartPoint, guide, side, normalVector, isObjLeft); App.LockAndExecute(() => objectIds.QForEach <Curve>(p => p.TransformBy(mt))); } Acad.Editor.SetImpliedSelection(Array.Empty <ObjectId>()); App.LockAndExecute(() => Interaction.HighlightObjects(objectIds)); } Acad.Editor.SetImpliedSelection(Array.Empty <ObjectId>()); App.LockAndExecute(() => Interaction.UnhighlightObjects(objectIds)); lPulling.Text = ""; Acad.Write($"Притягивание завершено"); _isPullingActive = false; Matrix3d CalcMatrix(Point3d point, Line guide, Line side, Vector3d normalVector, bool isObjLeft) { var isPointLeft = !guide.IsTurnRight(point); var rotAngle = side.GetVector2d().ZeroTo2PiAngleTo((isObjLeft ^ isPointLeft) ? guide.GetVector2d().Negate() : guide.GetVector2d()); var rotCenter = side.StartPoint; var rotationMatrix = Matrix3d.Rotation(rotAngle, Vector3d.ZAxis, rotCenter); point = guide.GetClosestPointTo(point, true); point += isPointLeft ? normalVector : -normalVector; var displacementMatrix = Matrix3d.Displacement(rotCenter.GetVectorTo(point)); return(displacementMatrix * rotationMatrix); } }