Looks like the samples and tutorials favour VB.Net ...FINALLY!!! Right up my alley. It gets tiring seeing all of the C-base code samples and trying to translate to VB.
If you can code in VB or C#, you can learn the other in a weekend.My mind automatically translated that to: "If you can dodge a wrench, you can dodge a ball." :-D
Ingredients pieStuff = bird;
Ingredients pieStuff = (Ingredients )bird;
Option Explicit Off Option Strict Off
Dim attRef As AttributeReference = entity
Option Explicit On Option Strict On
Dim attRef As AttributeReference = CType(entity, AttributeReference)
Dim attRef As AttributeReference = entity
is AttributeReference attRef = entity;
AttributeReference attRef = (AttributeReference)entity;
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
becomesusing Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
Here is the KeepStraightOverrule class Public Class KeepStraightOverrule
Inherits TransformOverrule
'We want to change how an AttributeReference responds to being
' transformed (moved, rotated, etc.), so we override its
' standard TransformBy function.
Public Overrides Sub TransformBy(ByVal entity As Entity,
ByVal transform As Matrix3d)
'Call the normal TransformBy function for the attribute
' reference we're overruling.
MyBase.TransformBy(entity, transform)
'We know entity must be an AttributeReference because
' that is the only entity we registered the overrule for.
Dim attRef As AttributeReference = entity
'Set rotation of attribute reference to 0 (horizontal)
attRef.Rotation = 0.0
End Sub
End Class
Public Overridable Sub TransformBy(ByVal entity As Entity, ByVal transform As Matrix3d)
or in C#public virtual void TransformBy(Entity entity, Matrix3d transform)
Overridable = virtual The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class. For example, this method can be overridden by any class that inherits it:
The Overidable keyword specifies that a property or procedure can be overridden by an identically named property or procedure in a derived class.A derived class is one that inherits another class.
Dim d As Double = 45.25
Dim i As Integer = d
With option strict On it will throw a error with it off the compiler will do the conversion.AttributeReference attRef = entity as AttributeReference;
MyBase(VB) and base(C#) call the 'base'(The class you are inherting from) class method.using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
namespace HorizontalAttributesCSharp
{
public class Commands
{
private static KeepStraightOverrule myOverrule;
[CommandMethod("KeepStraight")]
public static void ImplementOverrule()
{
if (myOverrule == null)
{
myOverrule = new KeepStraightOverrule();
Overrule.AddOverrule(RXClass.GetClass(typeof(AttributeReference)), myOverrule, false);
}
Overrule.Overruling = true;
}
}
public class KeepStraightOverrule : TransformOverrule
{
public override void TransformBy(Entity entity, Matrix3d transform)
{
base.TransformBy(entity, transform);
AttributeReference attRef = entity as AttributeReference;
attRef.Rotation = 0.0;
}
}
}
< .. >I have the same translation.
Someone might want to double check it.
< .. >
< .. >I have the same translation.
Someone might want to double check it.
< .. >
Either we're both correct or both miserably wrong
:)
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
namespace HorizontalAttributesCSharp
{
public class Commands
{
private static KeepStraightOverrule myOverrule;
private static KeepStraightOverruleOnInsert myOverruleInsert;
[CommandMethod("KeepStraight")]
public static void ImplementOverrule()
{
if (myOverrule == null)
{
myOverrule = new KeepStraightOverrule();
myOverruleInsert = new KeepStraightOverruleOnInsert();
Overrule.AddOverrule(RXClass.GetClass(typeof(AttributeReference)), myOverrule, false);
Overrule.AddOverrule(RXClass.GetClass(typeof(AttributeReference)), myOverruleInsert, false);
}
Overrule.Overruling = true;
}
}
public class KeepStraightOverrule : TransformOverrule
{
public override void TransformBy(Entity entity, Matrix3d transform)
{
base.TransformBy(entity, transform);
AttributeReference attRef = entity as AttributeReference;
attRef.Rotation = 0.0;
}
}
public class KeepStraightOverruleOnInsert : DrawableOverrule
{
public override int SetAttributes(Drawable drawable, DrawableTraits traits)
{
AttributeReference attRef = drawable as AttributeReference;
attRef.Rotation = 0.0;
return base.SetAttributes(drawable, traits);
}
}
}
When I tried placing it in a OpenClose transaction public class KeepStraightOverruleOnInsert : DrawableOverrule
{
public override bool WorldDraw(Drawable drawable, WorldDraw wd)
{
return false;
}
// Called for each viewport so entity can draw itself differently
// depending on the view.
public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
{
// Cast drawable to type AttributeReference (we know it's an
// AttributeReference because that's the only class we register our
// overrule for).
AttributeReference attRef = drawable as AttributeReference;
// First calculate the transformation matrix to rotate from the
// BlockReference's current orientation to the view.
Point3d org = attRef.Position;
Vector3d zVec = vd.Viewport.ViewDirection;
Vector3d yVec = vd.Viewport.CameraUpVector;
Vector3d xVec = yVec.CrossProduct(zVec).GetNormal();
Matrix3d viewmat = Matrix3d.AlignCoordinateSystem(org, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, org, xVec, yVec, zVec);
// Then calculate the additional rotation required to compensate for
// the AttributeReference having a rotation.
Matrix3d rotMat = Matrix3d.Rotation(-attRef.Rotation, attRef.Normal, org);
// Apply the two transformations
vd.Geometry.PushModelTransform(viewmat);
vd.Geometry.PushModelTransform(rotMat);
//Draw the 'per viewport geometry
base.ViewportDraw(drawable, vd);
// Remove the transformation - we don't want any other objects
// to draw themselves in the view plane.
vd.Geometry.PopModelTransform();
vd.Geometry.PopModelTransform();
}
}
This works using a Insert, but is not persisent and need to somehow make it persistent.Overrule.AddOverrule(RXClass.GetClass(typeof(BlockReference)), myOverruleInsert, false);
public class KeepStraightOverruleOnInsert : ObjectOverrule
{
public override void Open(DBObject dbObject, OpenMode mode)
{
if (mode == OpenMode.ForWrite)
{
BlockReference blkRef = dbObject as BlockReference;
if (blkRef.AttributeCollection.Count != 0)
{
using (Transaction trx = dbObject.Database.TransactionManager.StartOpenCloseTransaction())
{
foreach (ObjectId attRefId in blkRef.AttributeCollection)
{
AttributeReference attRef = trx.GetObject(attRefId, OpenMode.ForWrite) as AttributeReference;
attRef.Rotation = 0.0;
}
trx.Commit();
}
}
}
base.Open(dbObject, mode);
}
}
Sigh! You C# guys and your semi-colon addictions 8-).Yes please!
C# versions of the projects will be added eventually (after I've received enough feedback to be confident I don't have to edit too much of the VB.NET code)...
Sigh! You C# guys and your semi-colon addictions 8-).Add me to that!!
C# versions of the projects will be added eventually (after I've received enough feedback to be confident.
I continue to hold the opinion that VB.NET is more suited to someone learning programming for the first time by working through tutorials like this - the code is that much more readable for mere mortals.
If necessary I (or someone here) can convert the code for members hereI can give a hand this way too (these days I work on the migration of 20 000 VBA code lines to C#, hope I won't become 'Dim' addict).
< .. >
I can give a hand this way too (these days I work on the migration of 20 000 VBA code lines to C#, hope I won't become 'Dim' addict).
I can try a F# translation too. F# isn't so 'unreadable' for those comming from LISP (neither 'Dim' nor semi-colon)...
hope I won't become 'Dim' addictBe careful what you ask for
I'll be jumped upon if I laugh about the 'Dim' addict quote ,,, so I'll just have a quiet smile to myself.Get ready for that smile to change to a cringe.
attRef = entity
& Private Shared myOverrule
Module Module1
Sub Main()
i = 10
s = "word"
d = 5.567
''answer = i * s ''-----This will compile but CRASH at runtime.
answer = i * d ''-----This will compile and work just fine.
Console.WriteLine(answer)
Console.ReadKey()
End Sub
End Module
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Namespace HorizontalAttributes
Public Class Commands
Private Shared myOverrule
<CommandMethod("KeepStraight")>
Public Shared Sub ImplementOverrule()
If myOverrule Is Nothing Then
myOverrule = New KeepStraightOverrule
Overrule.AddOverrule(
RXClass.GetClass(GetType(AttributeReference)),
myOverrule, False)
End If
Overrule.Overruling = True
End Sub
End Class
Public Class KeepStraightOverrule
Inherits TransformOverrule
Public Overrides Sub TransformBy(ByVal entity As Entity,
ByVal transform As Matrix3d)
MyBase.TransformBy(entity, transform)
attRef = entity
attRef.Rotation = 0.0
End Sub
End Class
End Namespace
Get ready for that smile to change to a cringe.
In VB you can always turn Option Strict & and Explicit OFF and get rid of the Dims
so you can end up with thisCode: [Select]attRef = entity
<...>
I think F# is a GREAT idea. We probably won't get many new dotNet AutoCAD customisers usinf F#, but it may help them to become familiar with reading it ... thus helping with understanding some of the samples floatong around.
module HorizontalAttributes
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.Geometry
open Autodesk.AutoCAD.Runtime
// Mutable value that indicates whether the overrule is registered
let mutable isRegistered = false
// No need to create a new type derived from TransformOverrule,
// just create an 'object expression' based on the TransformOverrule type
// and override the TransformBy method.
let keepStraightOverrule = { new TransformOverrule() with
override this.TransformBy(entity, transform) =
// Call the normal TransformBy function for the attribute
// reference we're overruling.
base.TransformBy(entity, transform)
// We know entity must be an AttributeReference because
// that is the only entity we registered the overrule for.
let attRef = entity :?> AttributeReference
// Set rotation of attribute reference to 0 (horizontal)
attRef.Rotation <- 0.}
[<CommandMethod("KeepStraight")>]
let implementOverrule() =
// We only want to register our overrule instance once,
// so we check if it is not already registered
// (i.e. this may be the 2nd time we've run the command)
if not isRegistered then
// Register the overrule
Overrule.AddOverrule(
RXClass.GetClass(typeof<AttributeReference>),
keepStraightOverrule, false)
isRegistered <- true
// Make sure overruling is turned on so our overrule works
Overrule.Overruling <- true
module ObjectOrientedSampleFs
open Autodesk.AutoCAD.Runtime
type Point() =
let mutable xCoord = 0
let mutable yCoord = 0
member this.SetLocation x y =
xCoord <- x
yCoord <- y
member this.X
with get() = xCoord
and set(value) = xCoord <- value
member this.Y
with get() = yCoord
and set(value) = yCoord <- value
type NewPoint() =
inherit Point()
let mutable zCoord = 0
member this.Z
with get() = zCoord
and set(value) = if value >= 0 then zCoord <- value
[<CommandMethod("RunTest")>]
let runTest() =
let pt1 = new Point()
// USe Step Into on the next line to step into SetLocation
pt1.SetLocation 10 10
let xVal1 = pt1.X
pt1.X <- 9
let xVal2 = pt1.X
let pt2 = new NewPoint()
// SetLocation, X and Y are inherited from Point class
pt2.SetLocation 20 20
let xVal3 = pt2.X
pt2.X <- 9
// Z is new to the NewPoint class
pt2.Z <- 12
let pt3 = pt2 :> Point
// pt3 is variable of type Point, but holds an object of type NewPoint
()
module HorizontalAttributes
open Autodesk.AutoCAD.ApplicationServices
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Geometry
open Autodesk.AutoCAD.Runtime
// Mutable value that indicates whether the overrule is registered
let mutable isRegistered = false
// No need to create a new type derived from TransformOverrule,
// just create an 'object expression' based on the TransformOverrule type
// and override the TransformBy method.
let keepStraightOverrule = { new TransformOverrule() with
override this.TransformBy(entity, transform) =
// Call the normal TransformBy function for the attribute
// reference we're overruling.
base.TransformBy(entity, transform)
// We know entity must be an AttributeReference because
// that is the only entity we registered the overrule for.
let attRef = entity :?> AttributeReference
// Set rotation of attribute reference to 0 (horizontal)
attRef.Rotation <- 0.}
[<CommandMethod("KeepStraight")>]
let implementOverrule() =
let doc = Application.DocumentManager.MdiActiveDocument
let ed = doc.Editor
// Select a block reference
let opts = new PromptEntityOptions("\nSelect a block reference: ")
opts.SetRejectMessage("\nMust be block reference...")
opts.AddAllowedClass(typeof<BlockReference>, true)
let res = ed.GetEntity(opts)
if res.Status = PromptStatus.OK then
let db = doc.Database
use trans = db.TransactionManager.StartTransaction()
// Open the BlockReference for read.
// We know its a BlockReference because we set a filter in
// our PromptEntityOptions
let blkRef = trans.GetObject(res.ObjectId, OpenMode.ForRead) :?> BlockReference
let attRefCol = blkRef.AttributeCollection
// Using a 'comprehension' to convert the ObjectIdCollection into an ObjectId array
let objIds = [| for id in attRefCol -> id |]
// We only want to register our overrule instance once,
// so we check if it is not already registered
// (i.e. this may be the 2nd time we've run the command)
if not isRegistered then
Overrule.AddOverrule(
RXClass.GetClass(typeof<AttributeReference>),
keepStraightOverrule, false)
isRegistered <- true
// Specify which Attributes will be overruled
keepStraightOverrule.SetIdFilter(objIds)
// Make sure overruling is turned on so our overrule works
Overrule.Overruling <- true
module HorizontalAttributes
open Autodesk.AutoCAD.ApplicationServices
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Geometry
open Autodesk.AutoCAD.Runtime
// Mutable value that indicates whether the overrule is registered
let mutable isRegistered = false
// Registered Application Id for Xdata
let regAppName = "ADSK_ATTRIBUTE_ZERO_OVERRULE"
// No need to create a new type derived from TransformOverrule,
// just create an 'object expression' based on the TransformOverrule type
// and override the TransformBy method.
let keepStraightOverrule = { new TransformOverrule() with
override this.TransformBy(entity, transform) =
// Call the normal TransformBy function for the attribute
// reference we're overruling.
base.TransformBy(entity, transform)
// We know entity must be an AttributeReference because
// that is the only entity we registered the overrule for.
let attRef = entity :?> AttributeReference
// Set rotation of attribute reference to 0 (horizontal)
attRef.Rotation <- 0.}
let addRegAppId (db:Database) =
use trans = db.TransactionManager.StartTransaction()
// First create our RegAppId (if it doesn't already exist)
let appTbl = trans.GetObject(db.RegAppTableId, OpenMode.ForRead) :?> RegAppTable
if not (appTbl.Has(regAppName)) then
let appTblRec = new RegAppTableRecord()
appTbl.UpgradeOpen()
appTblRec.Name <- regAppName
appTbl.Add(appTblRec) |> ignore
trans.AddNewlyCreatedDBObject(appTblRec, true)
trans.Commit()
[<CommandMethod("ActivateOverrule")>]
let activateOverrule() =
// We only want to register our overrule instance once,
// so we check if it is not already registered
// (i.e. this may be the 2nd time we've run the command)
if not isRegistered then
// Register the overrule
Overrule.AddOverrule(
RXClass.GetClass(typeof<AttributeReference>),
keepStraightOverrule, false)
isRegistered <- true
// Specify which Attributes will be overruled
keepStraightOverrule.SetXDataFilter(regAppName)
// Make sure overruling is turned on so our overrule works
Overrule.Overruling <- true
[<CommandMethod("KeepStraight")>]
let implementOverrule() =
let doc = Application.DocumentManager.MdiActiveDocument
let ed = doc.Editor
// Select a block reference
let opts = new PromptEntityOptions("\nSelect a block reference: ")
opts.SetRejectMessage("\nMust be block reference...")
opts.AddAllowedClass(typeof<BlockReference>, true)
let res = ed.GetEntity(opts)
if res.Status = PromptStatus.OK then
let db = doc.Database
addRegAppId(db)
use trans = db.TransactionManager.StartTransaction()
// Open the BlockReference for read.
// We know its a BlockReference because we set a filter in
// our PromptEntityOptions
let blkRef = trans.GetObject(res.ObjectId, OpenMode.ForRead) :?> BlockReference
let attRefCol = blkRef.AttributeCollection
// Iterate through ObjectIds of all AttributeReferences
// attached to the BlockReference, opening each
// AttributeReference and adding xdata to it.
blkRef.AttributeCollection
|> Seq.cast<ObjectId>
|> Seq.map(fun objId -> trans.GetObject(objId, OpenMode.ForWrite))
|> Seq.iter(fun attRef ->
// Create new xdata containing the overrule filter name
use resBuf = new ResultBuffer(new TypedValue(1001, regAppName), new TypedValue(1000, "Dummy text"))
// Add the xdata
attRef.XData <- resBuf)
trans.Commit()
// Create and register our overrule and turn overruling on.
activateOverrule()
[<CommandMethod("DontKeepStraight")>]
let removeXdata() =
let doc = Application.DocumentManager.MdiActiveDocument
let ed = doc.Editor
// Select a block reference
let opts = new PromptEntityOptions("\nSelect a block reference: ")
opts.SetRejectMessage("\nMust be block reference...")
opts.AddAllowedClass(typeof<BlockReference>, true)
let res = ed.GetEntity(opts)
if res.Status = PromptStatus.OK then
let db = doc.Database
addRegAppId(db)
use trans = db.TransactionManager.StartTransaction()
// Open the BlockReference for read.
// We know its a BlockReference because we set a filter in
// our PromptEntityOptions
let blkRef = trans.GetObject(res.ObjectId, OpenMode.ForRead) :?> BlockReference
let attRefCol = blkRef.AttributeCollection
// Iterate through ObjectIds of all AttributeReferences
// attached to the BlockReference, opening each
// AttributeReference and adding xdata to it.
blkRef.AttributeCollection
|> Seq.cast<ObjectId>
|> Seq.map(fun objId -> trans.GetObject(objId, OpenMode.ForWrite))
|> Seq.iter(fun attRef ->
// Create new xdata containing the overrule filter name
use resBuf = new ResultBuffer(new TypedValue(1001, regAppName))
// Add the xdata.
// Because we leave this blank except for the regappid,
// it erases any Xdata we previously added.
attRef.XData <- resBuf)
trans.Commit()
module HorizontalAttributes
open Autodesk.AutoCAD.ApplicationServices
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Geometry
open Autodesk.AutoCAD.GraphicsInterface
open Autodesk.AutoCAD.Runtime
// Mutable value that indicates whether the overrule is registered
let mutable isRegistered = false
// Registered Application Id for Xdata
let regAppName = "ADSK_ATTRIBUTE_ZERO_OVERRULE"
// No need to create a new type derived from DrawableOverrule,
// just create an 'object expression' based on the DrawableOverrule type
// and override the WorldDraw, ViewportDraw and SetAttributes methods.
let billboardAttributesOverrule = { new DrawableOverrule() with
// Returning False from WorldDraw tells AutoCAD this entity has
// viewport dependent graphics.
override this.WorldDraw(drawable, wd) = false;
// Called for each viewport so entity can draw itself differently
// viewport dependent graphics.
override this.ViewportDraw(drawable, vd) =
// Cast drawable to type AttributeReference (we know it's an
// AttributeReference because that's the only class we register our
// overrule for).
let attRef = drawable :?> AttributeReference
// First calculate the transformation matrix to rotate from the
// BlockReference's current orientation to the view.
let org =
match attRef.Justify with
| AttachmentPoint.BaseLeft
| AttachmentPoint.BaseAlign
| AttachmentPoint.BaseFit -> attRef.Position
| _ -> attRef.AlignmentPoint
let viewMat =
Matrix3d.PlaneToWorld(new Plane(org, vd.Viewport.ViewDirection)) *
Matrix3d.WorldToPlane(new Plane(org, attRef.Normal)) *
Matrix3d.Rotation(-attRef.Rotation, attRef.Normal, org)
// Apply the transformation
vd.Geometry.PushModelTransform(viewMat) |> ignore
// Draw the 'per viewport geometry
base.ViewportDraw(drawable, vd)
// Remove the transformation - we don't want any other objects
// to draw themselves in the view plane.
vd.Geometry.PopModelTransform() |> ignore
// This function tells AutoCAD to dynamically update the
// AttributeReference during view transitions (e.g. 3DORBIT).
// Comment it out to improve graphic update performance.
override this.SetAttributes(drawable, traits) =
base.SetAttributes(drawable, traits) ||| 2048
}
let addXdata id resBuf (db:Database) =
use trans = db.TransactionManager.StartTransaction()
// First create our RegAppId (if it doesn't already exist)
let appTbl = trans.GetObject(db.RegAppTableId, OpenMode.ForRead) :?> RegAppTable
if not (appTbl.Has(regAppName)) then
let appTblRec = new RegAppTableRecord()
appTbl.UpgradeOpen()
appTblRec.Name <- regAppName
appTbl.Add(appTblRec) |> ignore
trans.AddNewlyCreatedDBObject(appTblRec, true)
// Open the BlockReference for read.
// Iterate through ObjectIds of all AttributeReferences
// attached to the BlockReference, opening each
// AttributeReference and adding xdata to it.
(trans.GetObject(id, OpenMode.ForRead) :?> BlockReference).AttributeCollection
|> Seq.cast<ObjectId>
|> Seq.map(fun objId -> trans.GetObject(objId, OpenMode.ForWrite))
|> Seq.iter(fun attRef -> attRef.XData <- resBuf)
trans.Commit()
let getBlkRef (ed:Editor) =
let opts = new PromptEntityOptions("\nSelect a block reference: ")
opts.SetRejectMessage("\nMust be block reference...")
opts.AddAllowedClass(typeof<BlockReference>, true)
ed.GetEntity(opts)
[<CommandMethod("ActivateBillboardOverrule")>]
let activateOverrule() =
// We only want to register our overrule instance once,
// so we check if it is not already registered
// (i.e. this may be the 2nd time we've run the command)
if not isRegistered then
Overrule.AddOverrule(
RXClass.GetClass(typeof<AttributeReference>),
billboardAttributesOverrule, false)
isRegistered <- true
// Specify which Attributes will be overruled
billboardAttributesOverrule.SetXDataFilter(regAppName)
// Make sure overruling is turned on so our overrule works
Overrule.Overruling <- true
[<CommandMethod("BillboardAttributes")>]
let implementOverrule() =
let doc = Application.DocumentManager.MdiActiveDocument
// Select a block reference
let res = getBlkRef doc.Editor
if res.Status = PromptStatus.OK then
// Create and register our overrule and turn overruling on.
activateOverrule()
// Add xdata to all AttributeReferences of the selected block reference
use resBuf = new ResultBuffer(
new TypedValue(1001, regAppName),
new TypedValue(1000, "Dummy text"))
addXdata res.ObjectId resBuf doc.Database
[<CommandMethod("DontBillboardAttributes")>]
let removeXdata() =
let doc = Application.DocumentManager.MdiActiveDocument
// Select a block reference
let res = getBlkRef doc.Editor
if res.Status = PromptStatus.OK then
// Erases xdata to all AttributeReferences of the selected block reference.
use resBuf = new ResultBuffer(new TypedValue(1001, regAppName))
addXdata res.ObjectId resBuf doc.Database
I tried this and it makes the Attribute appear horizontal during the Jig of the Insert but crashes with a eOpenforWrite error after the rotation is selected......
I tried this and it makes the Attribute appear horizontal during the Jig of the Insert but crashes with a eOpenforWrite error after the rotation is selected......
I think that's because this simple example wasn't done correctly to start with (Sorry 'bout that Mr. Preston).
The TransformBy() method takes a Matrix3d and applies the transformation defined by the matrix.
If you want to alter the transformation in some way, you don't supermessage the base type and pass it the original Matrix3d parameter as supplied (which applies the tranformation), and then perform a second transformation, by setting the rotation property. Sorry again, but that is the classic definition of a kludge.
What the author should have done was modify the Matrix3d that was passed into the override of TransformBy() to eliminate any rotation, and then supermessage the base type and pass it the modified matrix.
As far as the errors you may be seeing, the object(s) involved are already open for write when the method is called, but may not always be open in a transaction in certain circumstances.
public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
{
// Cast drawable to type AttributeReference (we know it's an
// AttributeReference because that's the only class we register our
// overrule for).
AttributeReference attRef = (AttributeReference)drawable;
// First calculate the transformation matrix to rotate from the
// BlockReference's current orientation to the view.
Point3d org = attRef.Position;
Vector3d zVec = vd.Viewport.ViewDirection;
Vector3d yVec = vd.Viewport.CameraUpVector;
Vector3d xVec = yVec.CrossProduct(zVec).GetNormal();
Matrix3d viewMat =
Matrix3d.AlignCoordinateSystem(
Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
org, xVec, yVec, zVec) *
Matrix3d.WorldToPlane(new Plane(org, attRef.Normal)) *
Matrix3d.Rotation(-attRef.Rotation, attRef.Normal, org);
// Apply the transformation
vd.Geometry.PushModelTransform(viewMat);
// Draw the 'per viewport geometry
base.ViewportDraw(drawable, vd);
// Remove the transformation - we don't want any other objects
// to draw themselves in the view plane.
vd.Geometry.PopModelTransform();
}
Public Overrides Sub ViewportDraw(ByVal drawable As Drawable,
ByVal vd As ViewportDraw)
' Cast drawable to type AttributeReference (we know it's an
' AttributeReference because that's the only class we register our
' overrule for).
Dim attRef As AttributeReference = drawable
' First calculate the transformation matrix to rotate from the
' BlockReference's current orientation to the view.
Dim org As Point3d = attRef.Position
Dim zVec As Vector3d = vd.Viewport.ViewDirection
Dim yVec As Vector3d = vd.Viewport.CameraUpVector
Dim xVec As Vector3d = yVec.CrossProduct(zVec).GetNormal
Dim viewmat As Matrix3d =
Matrix3d.AlignCoordinateSystem(
Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
org, xVec, yVec, zVec) *
Matrix3d.WorldToPlane(New Plane(org, attRef.Normal)) *
Matrix3d.Rotation(-attRef.Rotation, attRef.Normal, org)
' Apply the transformation
vd.Geometry.PushModelTransform(viewmat)
'Draw the 'per viewport geometry
MyBase.ViewportDraw(drawable, vd)
' Remove the transformation - we don't want any other objects
' to draw themselves in the view plane.
vd.Geometry.PopModelTransform()
End Sub
Hi TheMaster,
I agree that one shouldn't call a method on an entity from an overrule for that method called for that same entity. For example, if I were to call Attribute.TransformBy from my overrule of Attribute.TransformBy.
However, your description implies that the Attribute.Rotation property 'set' function calls TransformBy in its implementation. It doesn't.
If it did, then my code would have crashed the first time it was run as the overruled function was recursively called. That being the case, I really don't consider setting the Rotation property in the overrule as being any different from (say) setting the Color property.
I understand your point about using the transformation matrix, but I remain satisfied that the solution I use efficiently achieves exactly the behavior I wanted to implement in a single line of code (not a kludge). It also serves the additional purpose of avoiding having to present a larger and more complicated chunk of matrix manipulation code in a beginner tutorial.
I'm happy to agree to differ on this - working through the transformation matrix is also a good solution if that is your preference.
Tony T.? Is that you?
I remember one case where an inexperienced LISP programmer was able to corrupt a very large dataset to the extent that repairing it ultimately cost over 1000 times the fee he was paid.
< .. > this remind me something:QuoteI remember one case where an inexperienced LISP programmer was able to corrupt a very large dataset to the extent that repairing it ultimately cost over 1000 times the fee he was paid.
< .. >
So how does one become a "professional" programmer? :?
... B.S.C.S. + MS Certifications (MCSD, MCAD, MCPD, etc.)?
So how does one become a "professional" programmer? :?
... B.S.C.S. + MS Certifications (MCSD, MCAD, MCPD, etc.)?
nope.
about 50000 lines of code almost gets you there though ...
.. and finding someone to pay for the coffee :)
If Career.CAD_Technician.Salary < Career.Programmer.Salary Then
Return True
Else
Return Nothing
End If
I *seriously* hope money isn't the reason to change a career.Code: [Select]If Career.CAD_Technician.Salary < Career.Programmer.Salary Then
Return True
Else
Return Nothing
End If
I *seriously* hope money isn't the reason to change a career.
I'd be happy to clarify, but that discussion is irrelevant to this thread; feel free to email me offline Alan.Not necessary. I was just curious about your claims to pursuits of more money.
So how does one become a "professional" programmer? :?
... B.S.C.S. + MS Certifications (MCSD, MCAD, MCPD, etc.)?
Smaller companies can't afford to have somebody dedicated to programming, nor can they afford to hire them in.
Companies around the world have been making use of talented individuals contributing in areas that are not their primary expertise; although some turn out badly thats no reason for a blanket exclusion.
The flip side of this disucssion is those whose primary profession is programming and keeping pace with programming methods & tools as suggested, are not spending the time necessary to stay current with the progam itself (e.g. AutoCAD, Civil3D) or the work processes in use by any given company, client, and/or industry. This leads to applications which don't mesh well with what the users are actually doing, followed by complaints of "Must have been created by a programmer!".
I tried this and it makes the Attribute appear horizontal during the Jig of the Insert but crashes with a eOpenforWrite error after the rotation is selected......
I think that's because this simple example wasn't done correctly to start with (Sorry 'bout that Mr. Preston).
The TransformBy() method takes a Matrix3d and applies the transformation defined by the matrix.
If you want to alter the transformation in some way, you don't supermessage the base type and pass it the original Matrix3d parameter as supplied (which applies the tranformation), and then perform a second transformation, by setting the rotation property. Sorry again, but that is the classic definition of a kludge.
What the author should have done was modify the Matrix3d that was passed into the override of TransformBy() to eliminate any rotation, and then supermessage the base type and pass it the modified matrix.
As far as the errors you may be seeing, the object(s) involved are already open for write when the method is called, but may not always be open in a transaction in certain circumstances.
was modify the Matrix3d that was passed into the override of TransformBy() to eliminate any rotation, and then supermessage the base type and pass it the modified matrix.Does anyone know how that is accomplished?
Does anyone know how that is accomplished?
I am sure it is just some simple nerd math.
Oops,Does anyone know how that is accomplished?
I am sure it is just some simple nerd math.
Doesn't the reply #40 (http://www.theswamp.org/index.php?topic=40471.msg458579#msg458579) accomplish it ?
A nicer way (thanks to kaefer to remind me the Viewport.EyeToWorldTransform property)
Replace:Code - C#: [Select]
Point3d org = attRef.Position; Vector3d zVec = vd.Viewport.ViewDirection; Vector3d yVec = vd.Viewport.CameraUpVector; Vector3d xVec = yVec.CrossProduct(zVec).GetNormal(); Matrix3d viewMat = Matrix3d.AlignCoordinateSystem( Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, org, xVec, yVec, zVec) * Matrix3d.Rotation(-attRef.Rotation, attRef.Normal, org);
With:Code - C#: [Select]
Point3d org = attRef.Position; Matrix3d viewMat = Matrix3d.Displacement(vd.Viewport.CameraTarget.GetVectorTo(org)) * vd.Viewport.EyeToWorldTransform * Matrix3d.Rotation(-attRef.Rotation, attRef.Normal, org);
the second version made attribute move way off.Curiously, it needs a kind of regeneration which occurs on starting a 3d orbit.
Point3d org = attRef.Justify == AttachmentPoint.BaseLeft ||
attRef.Justify == AttachmentPoint.BaseAlign ||
attRef.Justify == AttachmentPoint.BaseFit ?
attRef.Position : attRef.AlignmentPoint;
Matrix3d viewMat =
Matrix3d.PlaneToWorld(new Plane(org, vd.Viewport.ViewDirection)) *
Matrix3d.WorldToPlane(new Plane(org, attRef.Normal)) *
Matrix3d.Rotation(-attRef.Rotation, attRef.Normal, org);
public class ExtensionApplication : IExtensionApplication
{
public void Initialize()
{
Commands.ActivateOverrule();
}
public void Terminate() { }
}