/// <summary> /// Поиск номера узла последней созданной узловой выноски /// </summary> private static string FindLastNodeNumber() { if (!MainSettings.Instance.NodalLeaderContinueNodeNumber) { return(string.Empty); } var allValues = new List <string>(); AcadUtils.GetAllIntellectualEntitiesInCurrentSpace <NodalLeader>(typeof(NodalLeader)).ForEach(a => { allValues.Add(a.NodeNumber); }); return(allValues.OrderBy(s => s, new OrdinalStringComparer()).LastOrDefault()); }
private static void DocumentManager_DocumentLockModeChanged( object sender, Autodesk.AutoCAD.ApplicationServices.DocumentLockModeChangedEventArgs e) { try { if (!UseBedit) { if (e.GlobalCommandName == "BEDIT") { e.Veto(); } } } catch (System.Exception exception) { AcadUtils.WriteMessageInDebug($"\nException {exception.Message}"); } }
/// <summary> /// Поиск последних цифровых и буквенных значений разрезов на текущем виде /// </summary> private static void FindLastSectionValues(ref string sectionLastLetterValue, ref string sectionLastIntegerValue) { if (MainSettings.Instance.SectionSaveLastTextAndContinueNew) { var sections = AcadUtils.GetAllIntellectualEntitiesInCurrentSpace <Section>(typeof(Section)); if (sections.Any()) { sections.Sort((s1, s2) => string.Compare(s1.BlockRecord.Name, s2.BlockRecord.Name, StringComparison.Ordinal)); var v = sections.Last().Designation; if (int.TryParse(v, out var i)) { sectionLastIntegerValue = i.ToString(); } else { sectionLastLetterValue = v; } } } }
/// <summary> /// Наполнение стиля свойствами со значениями по умолчанию /// </summary> /// <param name="style">Стиль <see cref="IntellectualEntityStyle"/></param> /// <param name="entityType">Тип интеллектуального объекта</param> public static void FillStyleDefaultProperties(this IntellectualEntityStyle style, Type entityType) { foreach (var propertyInfo in entityType.GetProperties()) { var attribute = propertyInfo.GetCustomAttribute <EntityPropertyAttribute>(); if (attribute != null && attribute.Name != "Style") { if (attribute.PropertyScope != PropertyScope.PaletteAndStyleEditor) { continue; } if (attribute.Name == "Scale") { style.Properties.Add(new IntellectualEntityProperty( attribute, entityType, AcadUtils.AnnotationScaleFromString(attribute.DefaultValue.ToString()), ObjectId.Null)); } else if (attribute.Name == "LayerName") { style.Properties.Add(new IntellectualEntityProperty( attribute, entityType, AcadUtils.Layers.Contains(attribute.DefaultValue.ToString()) ? attribute.DefaultValue : Language.GetItem(Invariables.LangItem, "defl"), ObjectId.Null)); } else { style.Properties.Add(new IntellectualEntityProperty( attribute, entityType, attribute.DefaultValue, ObjectId.Null)); } } } }
private void CreateEntities(Point3d insertionPoint, List <Point3d> middlePoints, Point3d endPoint, double scale) { var strokesWidth = StrokeWidth * scale; // top and bottom strokes var topStrokeEndPoint = GetTopStrokeEndPoint(insertionPoint, endPoint, middlePoints, scale); var bottomStrokeEndPoint = GetBottomStrokeEndPoint(insertionPoint, endPoint, middlePoints, scale); _topStroke = new Polyline(2); _topStroke.AddVertexAt(0, topStrokeEndPoint.ConvertPoint3dToPoint2d(), 0.0, strokesWidth, strokesWidth); _topStroke.AddVertexAt(1, insertionPoint.ConvertPoint3dToPoint2d(), 0.0, strokesWidth, strokesWidth); _bottomStroke = new Polyline(2); _bottomStroke.AddVertexAt(0, endPoint.ConvertPoint3dToPoint2d(), 0.0, strokesWidth, strokesWidth); _bottomStroke.AddVertexAt(1, bottomStrokeEndPoint.ConvertPoint3dToPoint2d(), 0.0, strokesWidth, strokesWidth); var topStrokeNormalVector = (topStrokeEndPoint - insertionPoint).GetNormal(); var bottomStrokeNormalVector = (bottomStrokeEndPoint - endPoint).GetNormal(); // shelf lines var topShelfStartPoint = insertionPoint + (topStrokeNormalVector * GetShelfOffset() * scale); var topShelfEndPoint = topShelfStartPoint + (topStrokeNormalVector.GetPerpendicularVector() * ShelfLength * scale); TopShelfEndPoint = topShelfEndPoint.TransformBy(BlockTransform); _topShelfLine = new Line { StartPoint = topShelfStartPoint, EndPoint = topShelfEndPoint }; var bottomShelfStartPoint = endPoint + (bottomStrokeNormalVector * GetShelfOffset() * scale); var bottomShelfEndPoint = bottomShelfStartPoint + (bottomStrokeNormalVector.GetPerpendicularVector().Negate() * ShelfLength * scale); BottomShelfEndPoint = bottomShelfEndPoint.TransformBy(BlockTransform); _bottomShelfLine = new Line { StartPoint = bottomShelfStartPoint, EndPoint = bottomShelfEndPoint }; // shelf arrows var topShelfArrowStartPoint = topShelfStartPoint + (topStrokeNormalVector.GetPerpendicularVector() * ShelfArrowLength * scale); _topShelfArrow = new Polyline(2); _topShelfArrow.AddVertexAt(0, topShelfArrowStartPoint.ConvertPoint3dToPoint2d(), 0.0, ShelfArrowWidth * scale, 0.0); _topShelfArrow.AddVertexAt(1, topShelfStartPoint.ConvertPoint3dToPoint2d(), 0.0, 0.0, 0.0); var bottomShelfArrowStartPoint = bottomShelfStartPoint + (bottomStrokeNormalVector.GetPerpendicularVector().Negate() * ShelfArrowLength * scale); _bottomShelfArrow = new Polyline(2); _bottomShelfArrow.AddVertexAt(0, bottomShelfArrowStartPoint.ConvertPoint3dToPoint2d(), 0.0, ShelfArrowWidth * scale, 0.0); _bottomShelfArrow.AddVertexAt(1, bottomShelfStartPoint.ConvertPoint3dToPoint2d(), 0.0, 0.0, 0.0); // text var textContentsForTopText = GetTextContents(true); var textContentsForBottomText = GetTextContents(false); if (!string.IsNullOrEmpty(textContentsForTopText) && !string.IsNullOrEmpty(textContentsForBottomText)) { var textStyleId = AcadUtils.GetTextStyleIdByName(TextStyle); var textHeight = MainTextHeight * scale; _topMText = new MText { TextStyleId = textStyleId, Contents = textContentsForTopText, TextHeight = textHeight, Attachment = AttachmentPoint.MiddleCenter }; _bottomMText = new MText { TextStyleId = textStyleId, Contents = textContentsForBottomText, TextHeight = textHeight, Attachment = AttachmentPoint.MiddleCenter }; // TextActualHeight = _topMText.ActualHeight; // TextActualWidth = _topMText.ActualWidth; var check = 1 / Math.Sqrt(2); // top var alongShelfTextOffset = _topMText.ActualWidth / 2; var acrossShelfTextOffset = _topMText.ActualHeight / 2; if (double.IsNaN(AlongTopShelfTextOffset) && double.IsNaN(AcrossTopShelfTextOffset)) { if ((topStrokeNormalVector.X > check || topStrokeNormalVector.X < -check) && (topStrokeNormalVector.Y < check || topStrokeNormalVector.Y > -check)) { alongShelfTextOffset = _topMText.ActualHeight / 2; acrossShelfTextOffset = _topMText.ActualWidth / 2; } var tempPoint = topShelfEndPoint + ((topShelfStartPoint - topShelfEndPoint).GetNormal() * alongShelfTextOffset); var topTextCenterPoint = tempPoint + (topStrokeNormalVector * ((2 * scale) + acrossShelfTextOffset)); _topMText.Location = topTextCenterPoint; } else { var tempPoint = topShelfEndPoint + ((topShelfStartPoint - topShelfEndPoint).GetNormal() * (AlongTopShelfTextOffset + (_topMText.ActualWidth / 2))); var topTextCenterPoint = tempPoint + (topStrokeNormalVector * ((2 * scale) + (AcrossTopShelfTextOffset + (_topMText.ActualHeight / 2)))); _topMText.Location = topTextCenterPoint; } TopDesignationPoint = _topMText.GeometricExtents.MinPoint.TransformBy(BlockTransform); // bottom alongShelfTextOffset = _bottomMText.ActualWidth / 2; acrossShelfTextOffset = _bottomMText.ActualHeight / 2; if (double.IsNaN(AlongBottomShelfTextOffset) && double.IsNaN(AcrossBottomShelfTextOffset)) { if ((bottomStrokeNormalVector.X > check || bottomStrokeNormalVector.X < -check) && (bottomStrokeNormalVector.Y < check || bottomStrokeNormalVector.Y > -check)) { alongShelfTextOffset = _topMText.ActualHeight / 2; acrossShelfTextOffset = _topMText.ActualWidth / 2; } var tempPoint = bottomShelfEndPoint + ((bottomShelfStartPoint - bottomShelfEndPoint).GetNormal() * alongShelfTextOffset); var bottomTextCenterPoint = tempPoint + (bottomStrokeNormalVector * ((2 * scale) + acrossShelfTextOffset)); _bottomMText.Location = bottomTextCenterPoint; } else { var tempPoint = bottomShelfEndPoint + ((bottomShelfStartPoint - bottomShelfEndPoint).GetNormal() * (AlongBottomShelfTextOffset + (_bottomMText.ActualWidth / 2))); var bottomTextCenterPoint = tempPoint + (bottomStrokeNormalVector * ((2 * scale) + (AcrossBottomShelfTextOffset + (_bottomMText.ActualHeight / 2)))); _bottomMText.Location = bottomTextCenterPoint; } BottomDesignationPoint = _bottomMText.GeometricExtents.MinPoint.TransformBy(BlockTransform); } _middleStrokes.Clear(); // middle strokes if (MiddlePoints.Any()) { var middleStrokeLength = MiddleStrokeLength * scale; var points = new List <Point3d> { insertionPoint }; points.AddRange(middlePoints); points.Add(endPoint); for (var i = 1; i < points.Count - 1; i++) { var previousPoint = points[i - 1]; var currentPoint = points[i]; var nextPoint = points[i + 1]; var middleStrokePolyline = new Polyline(3); middleStrokePolyline.AddVertexAt( 0, (currentPoint + ((previousPoint - currentPoint).GetNormal() * middleStrokeLength)).ConvertPoint3dToPoint2d(), 0, strokesWidth, strokesWidth); middleStrokePolyline.AddVertexAt(1, currentPoint.ConvertPoint3dToPoint2d(), 0, strokesWidth, strokesWidth); middleStrokePolyline.AddVertexAt( 2, (currentPoint + ((nextPoint - currentPoint).GetNormal() * middleStrokeLength)).ConvertPoint3dToPoint2d(), 0, strokesWidth, strokesWidth); _middleStrokes.Add(middleStrokePolyline); } } }
/// <inheritdoc/> public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return(AcadUtils.AnnotationScaleFromString(value?.ToString())); }
private IEnumerable <Polyline> CreateStrokesOnMainPolylineSegment( Point3d segmentEndPoint, Point3d segmentStartPoint, double scale, Vector3d?previousSegmentVector, Vector3d?nextSegmentVector) { var strokes = new List <Polyline>(); var lineThickness = LineThickness * scale; var segmentVector = segmentEndPoint - segmentStartPoint; var previousToCurrentCrossProductIndex = 1.0; if (previousSegmentVector != null) { previousToCurrentCrossProductIndex = previousSegmentVector.Value.CrossProduct(segmentVector).GetNormal().Z; } var currentToNextCrossProductIndex = 1.0; if (nextSegmentVector != null) { currentToNextCrossProductIndex = segmentVector.CrossProduct(nextSegmentVector.Value).GetNormal().Z; } var angleToPreviousSegment = previousSegmentVector != null ? previousSegmentVector.Value.GetAngleTo(segmentVector) : 0.0; var startBackOffset = 0.0; if (previousToCurrentCrossProductIndex < 0 && angleToPreviousSegment > 0.0) { startBackOffset = Math.Abs(lineThickness * Math.Tan(Math.PI - (angleToPreviousSegment / 2.0))); } var angleToNextSegment = nextSegmentVector != null ? segmentVector.GetAngleTo(nextSegmentVector.Value) : 0.0; var endBackOffset = 0.0; if (currentToNextCrossProductIndex < 0 && angleToNextSegment > 0.0) { endBackOffset = Math.Abs(lineThickness * Math.Tan(Math.PI - (angleToNextSegment / 2.0))); } var segmentLength = segmentVector.Length; var perpendicular = segmentVector.GetPerpendicularVector().Negate(); var distanceAtSegmentStart = _mainPolyline.GetDistAtPoint(segmentStartPoint); var overflowIndex = 0; var sumDistanceAtSegment = 0.0; var isSpace = true; var isStart = true; while (true) { overflowIndex++; double distance; if (isStart) { if (FirstStrokeOffset == WaterProofingFirstStrokeOffset.ByHalfStrokeOffset) { distance = StrokeOffset / 2.0 * scale; } else if (FirstStrokeOffset == WaterProofingFirstStrokeOffset.ByStrokeOffset) { distance = StrokeOffset * scale; } else { distance = 0.0; } distance += startBackOffset; isStart = false; } else { if (isSpace) { distance = StrokeOffset * scale; } else { distance = StrokeLength * scale; } } sumDistanceAtSegment += distance; if (!isSpace) { var firstStrokePoint = _mainPolyline.GetPointAtDist(distanceAtSegmentStart + sumDistanceAtSegment - distance) + (perpendicular * lineThickness / 2.0); if ((sumDistanceAtSegment - distance) < (sumDistanceAtSegment - endBackOffset)) { // Если индекс, полученный из суммы векторов (текущий и следующий) отрицательный и последний штрих // попадает на конец сегмента полилинии, то его нужно построить так, чтобы он попал на точку не основной // полилинии, а второстепенной Point3d secondStrokePoint; if (sumDistanceAtSegment >= segmentLength) { AcadUtils.WriteMessageInDebug($"segment vector: {segmentVector.GetNormal()}"); secondStrokePoint = segmentEndPoint - (segmentVector.GetNormal() * endBackOffset) + (perpendicular * lineThickness / 2.0); AcadUtils.WriteMessageInDebug($"{nameof(secondStrokePoint)}: {secondStrokePoint}"); } else { secondStrokePoint = _mainPolyline.GetPointAtDist(distanceAtSegmentStart + sumDistanceAtSegment) + (perpendicular * lineThickness / 2.0); } var stroke = new Polyline(2); stroke.AddVertexAt(0, firstStrokePoint.ConvertPoint3dToPoint2d(), 0.0, lineThickness, lineThickness); stroke.AddVertexAt(1, secondStrokePoint.ConvertPoint3dToPoint2d(), 0.0, lineThickness, lineThickness); SetImmutablePropertiesToNestedEntity(stroke); strokes.Add(stroke); } } if (sumDistanceAtSegment >= segmentLength) { break; } if (overflowIndex >= 1000) { break; } isSpace = !isSpace; } return(strokes); }
/// <summary> /// Применить к указанному интеллектуальному примитиву свойства из стиля /// </summary> /// <param name="entity">Экземпляр примитива</param> /// <param name="style">Стиль</param> /// <param name="isOnEntityCreation">True - применение стиля происходит при создании примитива. /// False - применение стиля происходит при выборе стиля в палитре</param> public static void ApplyStyle(this IntellectualEntity entity, IntellectualEntityStyle style, bool isOnEntityCreation) { var type = entity.GetType(); foreach (var propertyInfo in type.GetProperties()) { var attribute = propertyInfo.GetCustomAttribute <EntityPropertyAttribute>(); if (attribute != null) { var propertyFromStyle = style.Properties.FirstOrDefault(sp => sp.Name == attribute.Name); if (propertyFromStyle != null) { if (attribute.Name == "Scale") { if (isOnEntityCreation) { if (MainSettings.Instance.UseScaleFromStyle) { propertyInfo.SetValue(entity, propertyFromStyle.Value); } else { entity.Scale = AcadUtils.GetCurrentScale(); } } else { propertyInfo.SetValue(entity, propertyFromStyle.Value); } } else if (attribute.Name == "LayerName") { var layerName = propertyFromStyle.Value.ToString(); if (string.IsNullOrEmpty(layerName)) { layerName = Language.GetItem(Invariables.LangItem, "defl"); } if (isOnEntityCreation) { if (MainSettings.Instance.UseLayerFromStyle) { propertyInfo.SetValue(entity, layerName); AcadUtils.SetLayerByName(entity.BlockId, layerName, style.LayerXmlData); } } else { propertyInfo.SetValue(entity, layerName); AcadUtils.SetLayerByName(entity.BlockId, layerName, style.LayerXmlData); } } else if (attribute.Name == "LineType") { var lineType = propertyFromStyle.Value.ToString(); AcadUtils.SetLineType(entity.BlockId, lineType); } else if (attribute.Name == "TextStyle") { var apply = false; if (isOnEntityCreation) { if (MainSettings.Instance.UseTextStyleFromStyle) { apply = true; } } else { apply = true; } if (apply) { var textStyleName = propertyFromStyle.Value.ToString(); if (TextStyleUtils.HasTextStyle(textStyleName)) { propertyInfo.SetValue(entity, textStyleName); } else { if (MainSettings.Instance.IfNoTextStyle == 1 && TextStyleUtils.CreateTextStyle(style.TextStyleXmlData)) { propertyInfo.SetValue(entity, textStyleName); } } } } else { propertyInfo.SetValue(entity, propertyFromStyle.Value); } } } else { if (propertyInfo.Name == "StyleGuid") { propertyInfo.SetValue(entity, style.Guid); } } } }
/// <summary> /// Загрузка пользовательских стилей из xml-файла для указанного типа примитива /// </summary> /// <param name="entityType">Тип примитива</param> private static void LoadStylesFromXmlFile(Type entityType) { var stylesFile = Path.Combine(MainFunction.StylesPath, $"{entityType.Name}Styles.xml"); if (File.Exists(stylesFile)) { for (var i = EntityStyles.Count - 1; i >= 0; i--) { var style = EntityStyles[i]; if (style.StyleType == StyleType.System) { continue; } if (style.EntityType != entityType) { continue; } EntityStyles.RemoveAt(i); } var fXel = XElement.Load(stylesFile); foreach (var styleXel in fXel.Elements("UserStyle")) { var style = new IntellectualEntityStyle(entityType) { StyleType = StyleType.User }; style.Name = styleXel.Attribute(nameof(style.Name))?.Value; style.Description = styleXel.Attribute(nameof(style.Description))?.Value; // Guid беру, если есть атрибут. Иначе создаю новый var guidAttr = styleXel.Attribute(nameof(style.Guid)); style.Guid = guidAttr?.Value ?? Guid.NewGuid().ToString(); if (HasStyle(style)) { continue; } // get layer xml data var layerData = styleXel.Element("LayerTableRecord"); style.LayerXmlData = layerData ?? null; // get text style xml data var textStyleData = styleXel.Element("TextStyleTableRecord"); style.TextStyleXmlData = textStyleData ?? null; // get properties from file foreach (var propertyInfo in entityType.GetProperties()) { var attribute = propertyInfo.GetCustomAttribute <EntityPropertyAttribute>(); if (attribute != null) { var xmlProperty = styleXel.Elements("Property").FirstOrDefault(e => e.Attribute("Name")?.Value == attribute.Name); if (xmlProperty != null) { var xmlValue = xmlProperty.Attribute("Value")?.Value; var valueType = attribute.DefaultValue.GetType(); if (attribute.Name == "Scale") { style.Properties.Add(new IntellectualEntityProperty( attribute, entityType, AcadUtils.AnnotationScaleFromString(xmlValue), ObjectId.Null)); } else { if (valueType == typeof(string)) { style.Properties.Add(new IntellectualEntityProperty( attribute, entityType, xmlProperty.Attribute("Value").Value, ObjectId.Null)); } else if (valueType == typeof(int)) { style.Properties.Add(new IntellectualEntityProperty( attribute, entityType, int.TryParse(xmlValue, out var i) ? i : attribute.DefaultValue, ObjectId.Null)); } else if (valueType == typeof(double)) { style.Properties.Add(new IntellectualEntityProperty( attribute, entityType, double.TryParse(xmlValue, out var d) ? d : attribute.DefaultValue, ObjectId.Null)); } else if (valueType == typeof(bool)) { style.Properties.Add(new IntellectualEntityProperty( attribute, entityType, bool.TryParse(xmlValue, out var b) ? b : attribute.DefaultValue, ObjectId.Null)); } else if (valueType.IsEnum) { try { style.Properties.Add(new IntellectualEntityProperty( attribute, entityType, Enum.Parse(attribute.DefaultValue.GetType(), xmlValue), ObjectId.Null)); } catch { style.Properties.Add(new IntellectualEntityProperty( attribute, entityType, attribute.DefaultValue, ObjectId.Null)); } } } } } } style.CheckMissedProperties(entityType); // add style EntityStyles.Add(style); } } }
/// <summary> /// Применить к указанному интеллектуальному примитиву свойства из стиля /// </summary> /// <param name="entity">Экземпляр примитива</param> /// <param name="style">Стиль</param> /// <param name="isOnEntityCreation">True - применение стиля происходит при создании примитива. /// False - применение стиля происходит при выборе стиля в палитре</param> public static void ApplyStyle(this SmartEntity entity, SmartEntityStyle style, bool isOnEntityCreation) { var type = entity.GetType(); foreach (var propertyInfo in type.GetProperties()) { var attribute = propertyInfo.GetCustomAttribute <EntityPropertyAttribute>(); if (attribute != null) { var propertyFromStyle = style.Properties.FirstOrDefault(sp => sp.Name == attribute.Name); if (propertyFromStyle != null) { if (attribute.Name == "Scale") { if (isOnEntityCreation) { if (MainSettings.Instance.UseScaleFromStyle) { propertyInfo.SetValue(entity, propertyFromStyle.Value); } else { entity.Scale = AcadUtils.GetCurrentScale(); } } else { propertyInfo.SetValue(entity, propertyFromStyle.Value); } } else if (attribute.Name == "LayerName") { var layerName = propertyFromStyle.Value.ToString(); if (string.IsNullOrEmpty(layerName)) { layerName = Language.GetItem("defl"); } if (isOnEntityCreation) { if (MainSettings.Instance.UseLayerFromStyle) { propertyInfo.SetValue(entity, layerName); AcadUtils.SetLayerByName(entity.BlockId, layerName, style.LayerXmlData); } } else { propertyInfo.SetValue(entity, layerName); AcadUtils.SetLayerByName(entity.BlockId, layerName, style.LayerXmlData); } } else if (attribute.Name == "LineType") { var lineType = propertyFromStyle.Value.ToString(); AcadUtils.SetLineType(entity.BlockId, lineType); } else if (attribute.Name == "TextStyle") { var apply = false; if (isOnEntityCreation) { if (MainSettings.Instance.UseTextStyleFromStyle) { apply = true; } } else { apply = true; } if (apply) { var textStyleName = propertyFromStyle.Value.ToString(); if (TextStyleUtils.HasTextStyle(textStyleName)) { propertyInfo.SetValue(entity, textStyleName); } else { if (MainSettings.Instance.IfNoTextStyle == 1 && TextStyleUtils.CreateTextStyle(style.TextStyleXmlData)) { propertyInfo.SetValue(entity, textStyleName); } } } } else if (attribute.Name == "NumberSeparator") { switch (MainSettings.Instance.GlobalNumberSeparator) { case GlobalNumberSeparator.FromModPlusSettings: propertyInfo.SetValue( entity, Variables.Separator == "." ? NumberSeparator.Dot : NumberSeparator.Comma); break; case GlobalNumberSeparator.FromStyle: propertyInfo.SetValue(entity, propertyFromStyle.Value); break; case GlobalNumberSeparator.Dot: propertyInfo.SetValue(entity, NumberSeparator.Dot); break; case GlobalNumberSeparator.Comma: propertyInfo.SetValue(entity, NumberSeparator.Comma); break; default: throw new ArgumentOutOfRangeException(); } } else { propertyInfo.SetValue(entity, propertyFromStyle.Value); } } } else { if (propertyInfo.Name == "StyleGuid") { propertyInfo.SetValue(entity, style.Guid); } } } }