NetArx2010新特性-规则重定义
本帖最后由 作者 于 2009-5-14 14:46:31 编辑.NetArx终于在AutoCad2010版实现了自定义实体的子集--规则重定义,算是个好消息,
虽然很晚,而且功能没有ObjectArx的自定义实体强,但好歹没有强:)
下面的例子利用多行文字重定义为序号球,
更多的相关例子请看这里
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
namespace TlsCad
{
class TlsApplication : IExtensionApplication
{
void IExtensionApplication.Initialize()
{
XhqHelper.OverruleStart();
Overrule.Overruling = true;
}
void IExtensionApplication.Terminate()
{
XhqHelper.OverruleEnd();
Overrule.Overruling = false;
}
}
#region Helper
static class XhqHelper
{
public readonly static string RegAppName = "TlsCad.Xhq";
public readonly static double Radius = 8;
public readonly static double TextHeight = 8;
//获取起点
public static Point3d GetPoint(MText mtxt)
{
ResultBuffer rb = mtxt.GetXDataForApplication(RegAppName);
return (Point3d)rb.AsArray().Value;
}
//设置起点,注意这里使用1011组码保存点,支持Copy、Move、Mirror等命令时实时更新XData
public static void SetPoint(MText mtxt, Point3d point)
{
ResultBuffer rb = new ResultBuffer(new TypedValue[] { new TypedValue(1001, RegAppName), new TypedValue(1011, point) });
mtxt.XData = rb;
}
public static void XHQ()
{
PromptIntegerResult res1 = CadHelper.Editor.GetInteger(new PromptIntegerOptions("\n请输入序号:"));
PromptPointResult res2 = CadHelper.Editor.GetPoint(new PromptPointOptions("\n请输入起点:"));
XhqJig jig = new XhqJig(res2.Value, res1.Value.ToString());
PromptResult res = CadHelper.Editor.Drag(jig);
if (res.Status == PromptStatus.OK)
{
Database db = Application.DocumentManager.MdiActiveDocument.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
db.CurrentSpaceId,
OpenMode.ForWrite,
false);
MText mtxt = jig.GetEntity();
btr.AppendEntity(mtxt);
tr.AddNewlyCreatedDBObject(mtxt, true);
RegAppTable rat =
(RegAppTable)tr.GetObject(
db.RegAppTableId,
OpenMode.ForRead,
false);
if (!rat.Has(RegAppName))
{
rat.UpgradeOpen();
RegAppTableRecord regapp = new RegAppTableRecord();
regapp.Name = RegAppName;
rat.Add(regapp);
tr.AddNewlyCreatedDBObject(regapp, true);
}
SetPoint(mtxt, res2.Value);
tr.Commit();
}
}
}
public static void OverruleStart()
{
Overrule.AddOverrule(RXObject.GetClass(typeof(MText)), XhqDrawOverrule.TheOverrule, false);
Overrule.AddOverrule(RXObject.GetClass(typeof(MText)), XhqGripOverrule.TheOverrule, false);
Overrule.AddOverrule(RXObject.GetClass(typeof(MText)), XhqOsnapOverrule.TheOverrule, false);
Overrule.AddOverrule(RXObject.GetClass(typeof(MText)), XhqTransformOverrule.TheOverrule, false);
}
public static void OverruleEnd()
{
Overrule.RemoveOverrule(RXObject.GetClass(typeof(MText)), XhqDrawOverrule.TheOverrule);
Overrule.RemoveOverrule(RXObject.GetClass(typeof(MText)), XhqGripOverrule.TheOverrule);
Overrule.RemoveOverrule(RXObject.GetClass(typeof(MText)), XhqOsnapOverrule.TheOverrule);
Overrule.RemoveOverrule(RXObject.GetClass(typeof(MText)), XhqTransformOverrule.TheOverrule);
}
}
#endregion
#region Jig
//序号球拖动类
class XhqJig : DrawJig
{
Point3d m_Location;
Line m_Line;
MText m_MText;
Circle m_Circle;
public XhqJig(Point3d FirstPoint, string No)
{
m_MText = new MText();
m_MText.Attachment = AttachmentPoint.MiddleCenter;
m_MText.Location = FirstPoint;
m_MText.TextHeight = XhqHelper.TextHeight;
m_MText.Contents = No;
m_Line = new Line(FirstPoint, FirstPoint);
m_Circle = new Circle();
m_Circle.Center = FirstPoint;
m_Circle.Radius = XhqHelper.Radius;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
JigPromptPointOptions jigOpts = new JigPromptPointOptions();
jigOpts.UserInputControls =
UserInputControls.Accept3dCoordinates |
UserInputControls.NoZeroResponseAccepted |
UserInputControls.NoNegativeResponseAccepted;
jigOpts.Message = "\n请输入终点:";
PromptPointResult res = prompts.AcquirePoint(jigOpts);
Point3d positionTemp = res.Value;
if (positionTemp != m_Location)
{
m_Location = positionTemp;
}
else
return SamplerStatus.NoChange;
if (res.Status == PromptStatus.Cancel)
return SamplerStatus.Cancel;
else
return SamplerStatus.OK;
}
protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
{
try
{
Update();
draw.Geometry.Draw(m_Circle);
draw.Geometry.Draw(m_Line);
draw.Geometry.Draw(m_MText);
}
catch (System.Exception)
{
return false;
}
return true;
}
private void Update()
{
m_Circle.Center = m_Location;
Vector3d vec = m_Location - m_Line.StartPoint;
if (vec.Length <= m_Circle.Radius)
{
m_Line.EndPoint = m_Line.StartPoint;
}
else
{
vec = vec / vec.Length * m_Circle.Radius;
m_Line.EndPoint = m_Location - vec;
}
m_MText.Location = m_Location;
}
public MText GetEntity()
{
Update();
return m_MText;
}
}
#endregion
#region Overrule
//夹点重定义
public class XhqGripOverrule : GripOverrule
{
public static XhqGripOverrule TheOverrule = new XhqGripOverrule();
public XhqGripOverrule()
{
SetXDataFilter(XhqHelper.RegAppName);
}
public override void GetGripPoints(Entity entity, Point3dCollection gripPoints, IntegerCollection snapModes, IntegerCollection geometryIds)
{
MText mtxt = (MText)entity;
Point3d pt = mtxt.Location;
gripPoints.Add(pt + new Vector3d(0, XhqHelper.Radius, 0));
gripPoints.Add(pt + new Vector3d(XhqHelper.Radius, 0, 0));
gripPoints.Add(pt - new Vector3d(0, XhqHelper.Radius, 0));
gripPoints.Add(pt - new Vector3d(XhqHelper.Radius, 0, 0));
gripPoints.Add(XhqHelper.GetPoint(mtxt));
}
public override void MoveGripPointsAt(Entity entity, IntegerCollection indices, Vector3d offset)
{
MText mtxt = (MText)entity;
foreach (int index in indices)
{
switch (index)
{
case 0:
case 1:
case 2:
case 3:
mtxt.Location += offset;
break;
case 4:
XhqHelper.SetPoint(mtxt, XhqHelper.GetPoint(mtxt) + offset);
break;
}
}
}
}
//捕捉重定义
public class XhqOsnapOverrule : OsnapOverrule
{
public static XhqOsnapOverrule TheOverrule = new XhqOsnapOverrule();
public XhqOsnapOverrule()
{
SetXDataFilter(XhqHelper.RegAppName);
}
public override void GetObjectSnapPoints(Entity entity, ObjectSnapModes snapMode, System.IntPtr gsSelectionMark, Point3d pickPoint, Point3d lastPoint, Matrix3d viewTransform, Point3dCollection snapPoints, IntegerCollection geometryIds, Matrix3d insertionMat)
{
MText mtxt = (MText)entity;
switch (snapMode)
{
case ObjectSnapModes.ModeEnd:
snapPoints.Add(XhqHelper.GetPoint(mtxt));
break;
case ObjectSnapModes.ModeQuad:
Point3d pt = mtxt.Location;
snapPoints.Add(pt + new Vector3d(0, XhqHelper.Radius, 0));
snapPoints.Add(pt + new Vector3d(XhqHelper.Radius, 0, 0));
snapPoints.Add(pt + new Vector3d(0, -XhqHelper.Radius, 0));
snapPoints.Add(pt + new Vector3d(-XhqHelper.Radius, 0, 0));
break;
}
}
}
//
public class XhqTransformOverrule : TransformOverrule
{
public static XhqTransformOverrule TheOverrule = new XhqTransformOverrule();
public XhqTransformOverrule()
{
SetXDataFilter(XhqHelper.RegAppName);
}
public override void Explode(Entity entity, DBObjectCollection entitySet)
{
base.Explode(entity, entitySet);
MText mtxt = (MText)entity;
entitySet.Add(new Circle(mtxt.Location, mtxt.Normal, XhqHelper.Radius));
Point3d pt1 = XhqHelper.GetPoint(mtxt);
Vector3d vec = mtxt.Location - pt1;
if (vec.Length > XhqHelper.Radius)
{
vec = vec / vec.Length * XhqHelper.Radius;
entitySet.Add(new Line(pt1, mtxt.Location - vec));
}
}
}
//MText->序号球
public class XhqDrawOverrule : DrawableOverrule
{
public static XhqDrawOverrule TheOverrule = new XhqDrawOverrule();
public XhqDrawOverrule()
{
SetXDataFilter(XhqHelper.RegAppName);
}
public override bool WorldDraw(Drawable drawable, WorldDraw wd)
{
MText mtxt = (MText)drawable;
wd.Geometry.Circle(mtxt.Location, XhqHelper.Radius, new Vector3d(0, 0, 1));
Point3d pt1 = XhqHelper.GetPoint(mtxt);
Vector3d vec = mtxt.Location - pt1;
if (vec.Length > XhqHelper.Radius)
{
vec = vec / vec.Length * XhqHelper.Radius;
wd.Geometry.WorldLine(pt1, mtxt.Location - vec);
}
return base.WorldDraw(drawable, wd);
}
}
#endregion
}
雪山飞狐_lzh 发表于 2009-5-14 23:31
来自于Autodesk开发者网络课程上的例子,会变色的温度计
当你移动当中三个空心的圆圈时,对应的温度数值会 ...
这个例子 现在加载好像没有反应
终于找到,我想要的东西了感谢感谢 我正在弄标号,可惜我弄得的CAD2008 本帖最后由 作者 于 2009-5-15 7:49:14 编辑
来自于Autodesk开发者网络课程上的例子,会变色的温度计
当你移动当中三个空心的圆圈时,对应的温度数值会自动变化。
用netload命令加载下面的文件体验一下
命令TestOn,然后选择直线
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
namespace abc
{
#region "HelperClass"
// Global helper class (singleton). Contains central definitions of some global constants,
// and a few helper functions
public class HelperClass
{
const String mExtDictName = "SGP_MyDict";
// Defines Dictionary name for the Extension Dictionary demo
const String mXRecName = "SGP_MyDATA";
// Defines Dictionary name for the Extension Dictionary demo
private static HelperClass mMe;
// Name of our dictionary in extension dictionary
public String DictionaryName
{
get
{
return mExtDictName;
}
}
// Name of our XRecord
public String XRecordName
{
get
{
return mXRecName;
}
}
// Protected constructor - to enforce singleton behavior
protected HelperClass()
{
}
// static function to retrieve one and only instance of singleton
public static HelperClass GetSingleton
{
get
{
if (mMe == null)
{
mMe = new HelperClass();
}
return mMe;
}
}
// Retrieve data (as resbuf) from or Xrecord.
// Returns null object if there's a problem
public ResultBuffer GetXRecordData(DBObject obj)
{
Xrecord xRec = null;
ObjectId id = obj.ExtensionDictionary;
// Make sure we have an ext dict befoore proceeding
if (id.IsValid)
{
// Retrieve data using a transaction
Database db = Application.DocumentManager.MdiActiveDocument.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
DBDictionary extDict = (DBDictionary)tr.GetObject(id, OpenMode.ForRead, false);
if (extDict.Contains(DictionaryName))
{
// We're assuming that if my dictionary exists, then so will the XRecord in it.
ObjectId dictId = extDict.GetAt((String)DictionaryName);
DBDictionary myDict = (DBDictionary)tr.GetObject(dictId, OpenMode.ForRead);
xRec = (Xrecord)tr.GetObject(myDict.GetAt((String)XRecordName),
OpenMode.ForRead);
}
}
}
if (xRec == null)
{
return null;
}
else
{
return xRec.Data;
}
}
// Modifies data in our XRecord.
// (creates ou rdictionary and XRecoird if it doesn't already exist)
public void SetXRecordData(DBObject obj, ResultBuffer myData)
{
Database db = Application.DocumentManager.MdiActiveDocument.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
DBDictionary myDict = default(DBDictionary);
Xrecord xRec = null;
ObjectId id = obj.ExtensionDictionary;
if (id == ObjectId.Null)
{
obj.CreateExtensionDictionary();
id = obj.ExtensionDictionary;
}
DBDictionary extDict = (DBDictionary)tr.GetObject(id, OpenMode.ForWrite);
if (extDict.Contains(DictionaryName))
{
ObjectId dictId = extDict.GetAt((String)DictionaryName);
myDict = (DBDictionary)tr.GetObject(dictId, OpenMode.ForWrite);
}
else
{
myDict = new DBDictionary();
extDict.SetAt((String)DictionaryName, myDict);
tr.AddNewlyCreatedDBObject(myDict, true);
}
if (myDict.Contains(XRecordName))
{
xRec = (Xrecord)tr.GetObject(myDict.GetAt((String)XRecordName),
OpenMode.ForWrite);
}
else
{
xRec = new Xrecord();
myDict.SetAt((String)XRecordName, xRec);
tr.AddNewlyCreatedDBObject(xRec, true);
}
xRec.Data = myData;
tr.Commit();
}
}
}
#endregion
// Grip overrule to add our custom grips to the line
public class MyGripOverrule : GripOverrule
{
public class MyGrip : GripData
{
private int mGripNum;
public int Ordinal
{
get
{
return mGripNum;
}
set
{
mGripNum = value;
}
}
// Call this to tell the grip to move itself
public void Move(Vector3d vec)
{
GripPoint = GripPoint + vec;
}
public override bool ViewportDraw(ViewportDraw worldDraw, ObjectId entityId,
GripData.DrawType type, Point3d? imageGripPoint, int gripSizeInPixels)
{
Point2d unit = worldDraw.Viewport.GetNumPixelsInUnitSquare(GripPoint);
worldDraw.Geometry.Circle(GripPoint, 1.5 * gripSizeInPixels / unit.X,
worldDraw.Viewport.ViewDirection);
return true;
}
}
// Array to hold our 3 grips
GripData[] mGripData = new GripData;
public override void GetGripPoints(Entity entity, GripDataCollection grips,
double curViewUnitSize, int gripSize, Vector3d curViewDir, GetGripPointsFlags bitFlags)
{
ResultBuffer rb = HelperClass.GetSingleton.GetXRecordData(entity);
// We assume entity is a line
Line myLine = (Line)entity;
// Set grip positions to represent temperatures (we're using Celsius)
// min temperature
int temp = (int)rb.AsArray().Value;
double pos = myLine.StartParam + (temp / 100.0) * (myLine.EndParam - myLine.StartParam);
Point3d pt = myLine.GetPointAtParameter(pos);
MyGrip grip = new MyGrip();
grip.Ordinal = 0;
grip.GripPoint = pt;
mGripData = grip;
// max temperature
temp = (int)rb.AsArray().Value;
pos = myLine.StartParam + (temp / 100.0) * (myLine.EndParam - myLine.StartParam);
pt = myLine.GetPointAtParameter(pos);
grip = new MyGrip();
grip.Ordinal = 1;
grip.GripPoint = pt;
mGripData = grip;
// current temperature
temp = (int)rb.AsArray().Value;
pos = myLine.StartParam + (temp / 100.0) * (myLine.EndParam - myLine.StartParam);
pt = myLine.GetPointAtParameter(pos);
grip = new MyGrip();
grip.Ordinal = 2;
grip.GripPoint = pt;
mGripData = grip;
// Add our grips to the list
foreach (MyGrip g in mGripData)
{
grips.Add(g);
}
// Get the standard line grip points as well
base.GetGripPoints(entity, grips, curViewUnitSize, gripSize, curViewDir, bitFlags);
Point3d qq1 = grips.GripPoint;
Point3d qq2 = grips.GripPoint;
}
public override void MoveGripPointsAt(Entity entity, GripDataCollection grips,
Vector3d offset, MoveGripPointsFlags bitFlags)
{
// We only take action when we get this call on a database resident entity
// Dragging operation makes shallow clone of line,
// and setting clomeMeForDragging to false is generally a bad idea.
// (If you do set clone me for dragging to false, then don't call bae class overriden methods).
if (entity.Id.IsValid)
{
// Cast to a Line so we can access properties
Line myLine = (Line)entity;
Vector3d lineDir = (myLine.EndPoint - myLine.StartPoint);
lineDir = lineDir.GetNormal();
// Direction of Line
double offsetDist = lineDir.DotProduct(offset);
// Component of mouse translation along like
// Iterate through list of all grips being moved
foreach (GripData g in grips)
{
if (g is MyGrip)
{
MyGrip grip = (MyGrip)g;
// Cast to our grip type
// Make sure offset never takes grip beyond either end of line
if (offsetDist >= 0)
{
if (offsetDist > (myLine.EndPoint - grip.GripPoint).Length)
{
offsetDist = (myLine.EndPoint - grip.GripPoint).Length;
}
}
else
{
if (-offsetDist > (myLine.StartPoint - grip.GripPoint).Length)
{
offsetDist = -(myLine.StartPoint - grip.GripPoint).Length;
}
}
lineDir = lineDir * offsetDist;
// retrieve stored data and edit the changed value
ResultBuffer rb = HelperClass.GetSingleton.GetXRecordData(entity);
TypedValue[] typeValue = rb.AsArray();
String val1 = (String)typeValue.Value;
int[] intVal = new int;
intVal = (int)typeValue.Value;
// min
intVal = (int)typeValue.Value;
// max
intVal = (int)typeValue.Value;
// current
// Tell grip to move itself long the line
grip.Move(lineDir);
// Calculate new temperature from grip position along the line
double newParam = myLine.GetParameterAtPoint(grip.GripPoint);
int newTemp = (int)(100 * (newParam - myLine.StartParam) / (myLine.EndParam - myLine.StartParam));
// Don't let min temp value rise above max temp
// And don't let max temp go below min temp
if (grip.Ordinal == 0)
{
if (newTemp < intVal)
{
intVal = newTemp;
}
else
{
intVal = intVal - 1;
}
}
else if (grip.Ordinal == 1)
{
if (newTemp > intVal)
{
intVal = newTemp;
}
else
{
intVal = intVal + 1;
}
}
else
{
intVal = newTemp;
}
// Create new resbuf with new data and put back in Xrecord
ResultBuffer newRb = new ResultBuffer(new TypedValue((int)DxfCode.Text, val1),
new TypedValue((int)DxfCode.Int32, intVal),
new TypedValue((int)DxfCode.Int32, intVal),
new TypedValue((int)DxfCode.Int32, intVal));
HelperClass.GetSingleton.SetXRecordData(myLine, newRb);
}
}
}
// Remove our grips from the list befroe calling base class function
// (Doesn't seem to like my grips)
for (int i = grips.Count - 1; i >= 0; i += -1)
{
if (grips is MyGrip)
{
grips.Remove(grips);
}
}
// If any grips left, then we call base class function
if (grips.Count > 0)
{
base.MoveGripPointsAt(entity, grips, offset, bitFlags);
}
}
}
#region "Simple DrawableOverrule "
// This overrule adds our custom graphhics to the Line
// We're going to turn our Line into a Thermometer
public class MyDrawOverrule : DrawableOverrule
{
const int mSize = 30;
// Universal scaling constant - so I don't have to edit every calculation
// if I want the thermometer thicker or thinner
// This is the function that gets called to add/replace an entity's WorldDraw graphics
public override bool WorldDraw(Drawable drawable, WorldDraw wd)
{
// Is it a line? (It should be)
if (!(drawable is Line))
{
return base.WorldDraw(drawable, wd);
}
Line myLine = (Line)drawable;
Point3dCollection pts = new Point3dCollection();
// Read Xrecord values to populate prompt defauls
ResultBuffer resbuf = HelperClass.GetSingleton.GetXRecordData(myLine);
TypedValue[] typeValue = resbuf.AsArray();
// Room name
String myText = (String)typeValue.Value;
// Min temp
int lowerTemp = (int)typeValue.Value;
// max temp
int upperTemp = (int)typeValue.Value;
// Current temp
int curTemp = (int)typeValue.Value;
double curPos = curTemp / 100.0;
Vector3d perpVec = (myLine.EndPoint - myLine.StartPoint).CrossProduct(myLine.Normal).GetNormal();
double startParam = myLine.GetParameterAtPoint(myLine.StartPoint);
double endParam = myLine.GetParameterAtPoint(myLine.EndPoint);
var oldColIndex = wd.SubEntityTraits.Color;
FillType oldFillType = wd.SubEntityTraits.FillType;
double posParam = 0;
IntPtr gsMarker = default(IntPtr);
// Draw thermometer body
wd.SubEntityTraits.FillType = FillType.FillNever;
// right body edge
pts.Clear();
pts.Add(myLine.StartPoint + perpVec * myLine.Length * 2.5 / mSize);
pts.Add(myLine.EndPoint + perpVec * myLine.Length * 2.5 / mSize);
gsMarker = (System.IntPtr)1;
wd.Geometry.Polyline(pts, myLine.Normal, gsMarker);
// left body edge
pts.Clear();
pts.Add(myLine.EndPoint - perpVec * myLine.Length * 2.5 / mSize);
pts.Add(myLine.StartPoint - perpVec * myLine.Length * 2.5 / mSize);
gsMarker = (System.IntPtr)2;
wd.Geometry.Polyline(pts, myLine.Normal, gsMarker);
// top body edge
wd.Geometry.CircularArc(myLine.EndPoint - perpVec * myLine.Length * 2.5 / mSize,
myLine.EndPoint + (myLine.EndPoint - myLine.StartPoint) * 2.5 / mSize,
myLine.EndPoint + perpVec * myLine.Length * 2.5 / mSize, ArcType.ArcSimple);
// bottom body edge
double theta = Math.PI / 6;
double rad = (myLine.Length * 2.5 / mSize) / Math.Sin(theta);
double a = (myLine.Length * 2.5 / mSize) / Math.Tan(theta);
Point3d bowlCenter = myLine.StartPoint + (myLine.StartPoint - myLine.EndPoint).GetNormal() * a;
wd.Geometry.CircularArc(myLine.StartPoint + perpVec * myLine.Length * 2.5 / mSize,
myLine.StartPoint + (myLine.StartPoint - myLine.EndPoint).GetNormal() * (rad + a),
myLine.StartPoint - perpVec * myLine.Length * 2.5 / mSize, ArcType.ArcSimple);
// Draw upper temperature marker (in red)
wd.SubEntityTraits.Color = 1;
posParam = startParam + (endParam - startParam) * (upperTemp / 100.0);
pts.Clear();
pts.Add(myLine.GetPointAtParameter(posParam) - perpVec * myLine.Length * 3 / mSize);
pts.Add(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 3 / mSize);
gsMarker = (System.IntPtr)3;
wd.Geometry.Polyline(pts, myLine.Normal, gsMarker);
wd.Geometry.Text(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 4 / mSize,
myLine.Normal, perpVec, myLine.Length * 1.2 / mSize, 1, 0,
"Max. Temp = " + upperTemp.ToString());
// Draw lower temperature marker (in blue)
wd.SubEntityTraits.Color = 5;
posParam = startParam + (endParam - startParam) * (lowerTemp / 100.0);
pts.Clear();
pts.Add(myLine.GetPointAtParameter(posParam) - perpVec * myLine.Length * 3 / mSize);
pts.Add(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 3 / mSize);
gsMarker = (System.IntPtr)3;
wd.Geometry.Polyline(pts, myLine.Normal, gsMarker);
wd.Geometry.Text(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 4 / mSize,
myLine.Normal, perpVec, myLine.Length * 1.2 / mSize, 1, 0,
"Min. Temp = " + lowerTemp.ToString());
// Draw current temperature marker in different color depending on position w.r.t. min and max temps
short colIndex = 0;
if (curTemp <= lowerTemp)
{
colIndex = 5;
// Blue
}
else if (curTemp >= upperTemp)
{
colIndex = 1;
// Red
}
else
{
colIndex = 94;
// Dark green
}
// Draw current Temperature marker
wd.SubEntityTraits.Color = colIndex;
posParam = startParam + (endParam - startParam) * (curTemp / 100.0);
pts.Clear();
pts.Add(myLine.GetPointAtParameter(posParam) - perpVec * myLine.Length * 3 / mSize);
pts.Add(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 3 / mSize);
gsMarker = (System.IntPtr)4;
wd.Geometry.Polyline(pts, myLine.Normal, gsMarker);
wd.Geometry.Text(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 4 / mSize,
myLine.Normal, perpVec, myLine.Length * 1.2 / mSize, 1, 0,
myText + " Temp = " + curTemp.ToString());
// We want to draw filled primitives (polygon and circle) to
// represent the mercury in the thermometer
wd.SubEntityTraits.FillType = FillType.FillAlways;
// drawable mercury - line first, then bowl
pts.Clear();
Vector3d offset = perpVec * myLine.Length / mSize;
Point3d pt1 = myLine.StartPoint + offset;
pts.Add(bowlCenter + offset);
pts.Add(bowlCenter - offset);
pts.Add(myLine.GetPointAtParameter(posParam) - offset);
pts.Add(myLine.GetPointAtParameter(posParam) + offset);
wd.Geometry.Polygon(pts);
// mercury bowl
theta = Math.PI / 6;
rad = 1.5 * (offset.Length) / Math.Sin(theta);
a = (offset.Length) / Math.Tan(theta);
wd.Geometry.Circle(bowlCenter, rad, myLine.Normal);
// Set old subentitytrait values, then call overriden class worlddraw fn
wd.SubEntityTraits.FillType = oldFillType;
wd.SubEntityTraits.Color = oldColIndex;
return base.WorldDraw(drawable, wd);
}
}
#endregion
#region "Implementation of the commands"
public class TestOverrule : IExtensionApplication
{
// Setup some global variables
static MyDrawOverrule mDrawOverrule;
// One and only instance of this DrawableOverrule
static MyGripOverrule mGripOverrule;
// One and only instance of this TransformOverrule
// Called when DLL is loaded by AutoCAD.
public void Initialize()
{
// Instantiate our global Overrule and set it to overrule lines with my data attached
mDrawOverrule = new MyDrawOverrule();
Overrule.AddOverrule(RXObject.GetClass(typeof(Line)), mDrawOverrule, false);
mDrawOverrule.SetExtensionDictionaryEntryFilter(HelperClass.GetSingleton.DictionaryName);
// Instantiate our global Overrule and set it to overrule lines with my data attached
mGripOverrule = new MyGripOverrule();
Overrule.AddOverrule(RXObject.GetClass(typeof(Line)), mGripOverrule, false);
mGripOverrule.SetExtensionDictionaryEntryFilter(HelperClass.GetSingleton.DictionaryName);
// Turn overruling on
Overrule.Overruling = true;
}
// Clean up after ourselves.
public void Terminate()
{
Overrule.RemoveOverrule(RXObject.GetClass(typeof(Line)), mDrawOverrule);
mDrawOverrule = null;
Overrule.RemoveOverrule(RXObject.GetClass(typeof(Line)), mGripOverrule);
mDrawOverrule = null;
}
// Toggles all overrules on and off.
public void ToggleOverrule()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
Overrule.Overruling = !Overrule.Overruling;
ed.WriteMessage("\n*** Overrule is now " + Overrule.Overruling.ToString() + " ***\n");
ed.Regen();
}
// Demo of Extension Dictionary filter.
// There's also an Xdata filter, but we won't demonstrate it here - its basically the same).
// This command needs tidying up to use HelperClass functions for XData access. (Currently does its own thing).
public void AddXDictFilter()
{
// Select a line
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptEntityOptions opts = new PromptEntityOptions("\nSelect a line to add Extension dictionary to:");
opts.SetRejectMessage("\nSorry dude! That's not a line\n");
opts.AddAllowedClass(typeof(Line), true);
PromptEntityResult res = ed.GetEntity(opts);
// Only continue if a circle was selected
if (res.Status != PromptStatus.OK)
{
return;
}
// Open circle and make sure it has our dictionary in its extension dictionary
ObjectId objId = res.ObjectId;
Database db = objId.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Entity ent = (Entity)tr.GetObject(objId, OpenMode.ForRead);
ObjectId extId = ent.ExtensionDictionary;
// Create ext dict if necessary
if (extId == ObjectId.Null)
{
ent.UpgradeOpen();
ent.CreateExtensionDictionary();
extId = ent.ExtensionDictionary;
}
// Open ext dict
DBDictionary extDict = (DBDictionary)tr.GetObject(extId, OpenMode.ForWrite);
// make sure we clone data when entity is cloned for dragging
extDict.TreatElementsAsHard = true;
// If it doesn't contain our dictionary, we add one
PromptIntegerOptions temp1Opts = new PromptIntegerOptions("\nEnter Lower Temperature:");
PromptIntegerOptions temp2Opts = new PromptIntegerOptions("\nEnter Upper Temperature:");
PromptIntegerOptions temp3Opts = new PromptIntegerOptions("\nEnter Current Temperature:");
PromptStringOptions nameOpts = new PromptStringOptions("\nEnter Name:");
temp1Opts.LowerLimit = 0;
temp1Opts.UpperLimit = 100;
temp2Opts.LowerLimit = 0;
temp2Opts.UpperLimit = 100;
temp3Opts.LowerLimit = 0;
temp1Opts.UpperLimit = 100;
ObjectId xRecObjID;
Xrecord xRec;
DBDictionary myDict;
if (!extDict.Contains(HelperClass.GetSingleton.XRecordName))
{
// If dict is not present, then we add it and set up default Xrec to be edited later
extDict.UpgradeOpen();
myDict = new DBDictionary();
// make sure we clone data when entity is cloned for dragging
myDict.TreatElementsAsHard = true;
extDict.SetAt(HelperClass.GetSingleton.DictionaryName, myDict);
tr.AddNewlyCreatedDBObject(myDict, true);
temp1Opts.DefaultValue = 20;
temp2Opts.DefaultValue = 30;
temp3Opts.DefaultValue = 25;
nameOpts.DefaultValue = "San Rafael";
xRec = new Xrecord();
xRec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, nameOpts.DefaultValue),
new TypedValue((int)DxfCode.Int32, temp1Opts.DefaultValue),
new TypedValue((int)DxfCode.Int32, temp2Opts.DefaultValue),
new TypedValue((int)DxfCode.Int32, temp3Opts.DefaultValue));
xRecObjID = myDict.SetAt(HelperClass.GetSingleton.XRecordName, xRec);
tr.AddNewlyCreatedDBObject(xRec, true);
}
else
{
// If dict exists, then we extract values from XRecord to populate default values from prompt
// We're assuming that if my dictionary exists, then so will the XRecord in it.
ObjectId dictId = extDict.GetAt(HelperClass.GetSingleton.DictionaryName);
myDict = (DBDictionary)tr.GetObject(dictId, OpenMode.ForWrite, false);
temp1Opts.DefaultValue = 20;
temp1Opts.DefaultValue = 30;
xRecObjID = myDict.GetAt(HelperClass.GetSingleton.XRecordName);
xRec = (Xrecord)tr.GetObject(xRecObjID, OpenMode.ForRead, false);
}
// xRec now points to our XRecord, which is open for write.
// Read Xrecord values to populate prompt defauls
TypedValue[] typeValue = xRec.Data.AsArray();
TypedValue val1 = typeValue;
// Room name
TypedValue val2 = typeValue;
// Min temp
TypedValue val3 = typeValue;
// Max temp
TypedValue val4 = typeValue;
// Current temp
nameOpts.DefaultValue = (String)val1.Value;
temp1Opts.DefaultValue = (int)val2.Value;
temp2Opts.DefaultValue = (int)val3.Value;
temp3Opts.DefaultValue = (int)val4.Value;
// Prompt for new values
PromptResult nameRes = ed.GetString(nameOpts);
if (nameRes.Status == PromptStatus.OK)
{
val1 = new TypedValue((int)DxfCode.Text, nameRes.StringResult);
}
PromptIntegerResult temp1Res = ed.GetInteger(temp1Opts);
if (temp1Res.Status == PromptStatus.OK)
{
val2 = new TypedValue((int)DxfCode.Int32, temp1Res.Value);
}
PromptIntegerResult temp2Res = ed.GetInteger(temp2Opts);
if (temp2Res.Status == PromptStatus.OK)
{
val3 = new TypedValue((int)DxfCode.Int32, temp2Res.Value);
}
PromptIntegerResult temp3Res = ed.GetInteger(temp3Opts);
if (temp3Res.Status == PromptStatus.OK)
{
val4 = new TypedValue((int)DxfCode.Int32, temp3Res.Value);
}
// Now set Xrecord contents to new values
xRec.Data = new ResultBuffer(val1, val2, val3, val4);
tr.Commit();
}
// Display new results
ed.Regen();
}
}
#endregion
}
<p>问个问题,2010能不能存成低版本的,如果可以,存成低版本后,自定义实体会变成什么样子的,是否会消失?</p> <p>可以存成低版本的,但别说存低版本,就是不加载Dll,Overrule就会还原</p><p>注意Overrule是规则重定义,采取的手段只是在现有的实体上附加数据(XData或LData),然后由dll读取数据解释为重定义后形式</p><p>感觉这一版的Overrule要么是自动桌子的一次尝试,可能下一版本会推出真的自定义实体(严重怀疑)</p><p>要么就是内部开发人员在Net这块出现了分歧,不打算支持自定义实体(自己猜的)</p><p>不过现阶段真正的自定义实体可以用ObjectArx实现,然后NetArx去调用</p>Overrule的用途现在想到的只有图纸加密:重要的东西规则重定义,别人没有我的Dll就看不见,:) <p>GripOverrule...需要引用什么才可以用?</p><p>我用的是2008!</p> 注意AutoCad要2010版本 <p>GripOverrule...需要引用什么才可以用?</p> <p>飞狐兄,这些真是不错啊·但可惜的是必须要高版本的·</p><p>支持!</p><p>支持!</p><p></p>
页:
[1]
2