[EntityController(typeof(CustomDwgEntityController))] [DesignAlias("CUSTOMDWGENTITY")] public class CustomDwgEntity : DwgEntity, IPointObject { public const string PARENT_SMDX = "SmdxElement"; private ImElement m_Element; private Vector3D m_Position; private Vector3D m_Normal = new Vector3D(0, 0, 1); private double m_Angle = 0; private Drawing m_Plan; #region Properties [Browsable(false)] public Matrix Matrix { get { return Matrix.CreateExtrudedInsertion(m_Position, Vector3D.One, m_Normal, m_Angle); } } [DisplayName("Положение")] public Vector3D Position { get { return m_Position; } set { if (Position != value) { m_Position = value; } } } [Angle] [DisplayName("Угол поворота")] public double Angle { get { return m_Angle; } set { if (Angle != value) { m_Angle = value; } } } Vector3D IPointObject.BasePoint { get { return m_Position; } } [DisplayName("3D модель"), ImObjectPropertyProvider(PARENT_SMDX, false)] public ImElement Element { get { return m_Element; } set { BeginUpdate(); try { m_Element = value; m_Plan = null; Invalidate(); } finally { EndUpdate(); } } } [Browsable(false)] public Vector3D Normal { get { return m_Normal; } set { if (Normal != value) { Vector3D position, scale; double angle; var view1 = Matrix.GetElementView(out position, out scale, out angle); m_Normal = value; var view2 = Matrix.GetElementView(out position, out scale, out angle); if (view1 != view2) { m_Plan = null; } Invalidate(); } } } public override bool IsBreakable { get { return (m_Element != null) && (m_Element.IsAssembly); } } public override bool IsPurged { get { return m_Element == null; } } public override bool IsProxyGraphics { get { return false; } } public override string EntityName { get { return TypeExplorer.GetSerializableString(GetType()); } } [Browsable(false)] public BoundingBox3D Bounds3d { get { if (IsInvalid) { Regen(EventArgs.Empty); } var cache = GetCache(); if (cache != null) { var bounds = cache.Bounds; bounds.Min += m_Position; bounds.Max += m_Position; return bounds; } return new BoundingBox3D(); } } #endregion protected override void OnRegen(EventArgs e) { var matrix = Matrix; var plan = GetPlan(1.0); if ((plan != null) && (plan.Count > 0)) { Vector3D position, scale; double angle; matrix.GetElementView(out position, out scale, out angle); Bounds = plan.Bounds * Matrix.CreateInsertion(position, scale, angle); } else { Invalidate(); } } protected override void OnBreak(IList list) { if (m_Element != null) { var matrix = Matrix; var model = m_Element.GetModel(); if (model != null) { var element = new Static3DElement( m_Element.Name, m_Element.GetObjectType(), m_Element.GetProperties().Clone(), model, new ImDocuments(m_Element)); ExtractEntities(list, matrix, model, element); } if (m_Element.IsAssembly) { foreach (var item in m_Element.GetReferences()) { var m = item.GetMatrix() * matrix; ExtractEntities(list, m, model, item.Element); } } } } protected override void OnAssign(DwgEntity source) { var entity = source as CustomDwgEntity; if (entity != null) { if (entity.m_Element != null) { m_Element = entity.m_Element.Clone(); m_Plan = entity.m_Plan; m_Position = entity.m_Position; m_Normal = entity.m_Normal; m_Angle = entity.m_Angle; } else { m_Element = null; } } } protected override void OnTransform(Matrix matrix) { var scale = Vector3D.One; (Matrix * matrix).GetExtrudedInsertion(out m_Position, out scale, out m_Normal, out m_Angle); } protected override void OnSaveToStg(StgNode node) { m_Position.SaveToStg(node.AddNode("Position")); m_Normal.SaveToStg(node.AddNode("Normal"), Vector3D.UnitZ); node.AddDouble("Angle", m_Angle, 0.0); } protected override void OnSaveToStg(StgNode node, ISerializationContext context) { base.OnSaveToStg(node, context); if (m_Element != null) { m_Element.SaveToStg(node.AddNode("Model"), context); } if (m_Plan != null) { node.AddInt32("PlanSign", context.AddSerializable(m_Plan)); } } protected override void OnLoadFromStg(StgNode node) { if (node.IsExists("Element")) { var context = new SerializationContext(this); context.LoadFromStg(node.GetNode("Context")); m_Element = ImElement.LoadFromStg(node.GetNode("Element"), context); } m_Position = Vector3D.LoadFromStg(node.GetNode("Position")); m_Normal = Vector3D.LoadFromStg(node.GetNode("Normal"), Vector3D.UnitZ); m_Angle = node.GetDouble("Angle", 0); } protected override void OnLoadFromStg(StgNode node, ISerializationContext context) { base.OnLoadFromStg(node, context); if (node.IsExists("Model")) { m_Element = ImElement.LoadFromStg(node.GetNode("Model"), context); } if (node.IsExists("PlanSign")) { m_Plan = context.GetSerializable(node.GetInt32("PlanSign")); } } public double? Fire(Ray3D ray) { if (IsInvalid) { Regen(EventArgs.Empty); } var cache = GetCache(); if (cache != null) { ray.Position -= Position; return cache.Fire(ray); } return null; } [Browsable(false)] public DwgBlock GetPlan(double mapscale) { var sscale = mapscale.ToString(CultureInfo.InvariantCulture); if (m_Plan == null) { if (m_Element != null) { Vector3D position, scale; double angle; var view = Matrix.GetElementView(out position, out scale, out angle); m_Plan = new Drawing(); var vel = m_Element as ImViewElement; if (vel != null) { try { vel.GetView(view, m_Plan.Blocks.Add(sscale), Matrix.Identity, mapscale); } catch { } } } } if (m_Plan == null) { return null; } var block = m_Plan.Blocks[sscale]; if (block == null) { if (m_Element != null) { Vector3D position, scale; double angle; var view = Matrix.GetElementView(out position, out scale, out angle); m_Plan = new Drawing(); var vel = m_Element as ImViewElement; if (vel != null) { try { block = m_Plan.Blocks.Add(sscale); vel.GetView(view, block, Matrix.Identity, mapscale); } catch { } } } } return block; } public GeometryModelsCache GetCache() { var builder = new GeometryModelsCacheBuilder(Position); var cache = builder.Create(Element, Matrix); return cache; } private void ExtractEntities(IList list, Matrix matrix, GeometryModel3D model, ImElement element) { Vector3D position, scale, normal; double angle; matrix.GetExtrudedInsertion(out position, out scale, out normal, out angle); var e = new CustomDwgEntity(); e.CopyProperties(this); e.Position = position; e.Normal = normal; e.Angle = angle; e.Element = element; e.m_Plan = null; list.Add(e); } }