Code Red > .NET

AttSync for .Net

(1/6) > >>

Andrey:
Hi all.
I have written .net-realization of command AttSync. If it is interesting to someone - the code here.

kaefer:
Hi Andrey,

that's pretty cool. I've always wondered how to implement that little gem myself.

Some observations:

I find it easier to reason about the various collections of AttributeReferences and AttributeDefinitions in terms of set-theoretical operations, that is set difference and set intersection.

--- Code: ---module Seq =
    let differenceBy f s t =
        Seq.filter (fun x -> Seq.exists (f x) s |> not) t
    let intersectBy f s t =
        Seq.filter (fun x -> Seq.exists (f x) s) t

--- End code ---

Further, why don't you use Reflection to copy the various properties, all the more as the Textstyle property will fall flat from 2010 onwards: it's TextstyleId now.

And finally, the canonical way to effect attribute justification will involve a test for AttachmentPoint.Baseleft, like

--- Code: ---                        let just = ad.Justify
                        attref.Justify <- just
                        if just = AttachmentPoint.BaseLeft then
                            attref.Position <- ad.Position.TransformBy br.BlockTransform
                        else
                            attref.AlignmentPoint <- ad.AlignmentPoint.TransformBy br.BlockTransform

--- End code ---

Andrey:
2 kaefer

My test code:


--- Code: ---        [CommandMethod("MySynch", CommandFlags.Modal)]
        public void MySynch() {
            Document dwg = acad.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;
            Database db = dwg.Database;
            TypedValue[] types = new TypedValue[] { new TypedValue((int) DxfCode.Start, "INSERT") };
            SelectionFilter sf = new SelectionFilter(types);
            PromptSelectionOptions pso = new PromptSelectionOptions();
            pso.MessageForAdding = "Select block reference";
            pso.SingleOnly = true;
            pso.AllowDuplicates = false;
           
            PromptSelectionResult psr = ed.GetSelection(pso, sf);
            if (psr.Status == PromptStatus.OK) {
                using (Transaction t = db.TransactionManager.StartTransaction()) {
                    BlockTable bt = (BlockTable) t.GetObject(db.BlockTableId, OpenMode.ForRead);
                    BlockReference br = (BlockReference) t.GetObject(psr.Value[0].ObjectId, OpenMode.ForRead);
                    BlockTableRecord btr = (BlockTableRecord) t.GetObject(bt[br.Name], OpenMode.ForRead);
                    btr.AttSync(t, false, true, false);
                    t.Commit();
                }
            }
            else
                ed.WriteMessage("Bad selectionа.\n");
        }

--- End code ---

Yes, I wrote this code for AutoCAD 2009. :)
Unfortunately, I don't know language F # and I can not understand your code. If it is not difficult, write it, please on a C #.

In the course of testing I have clarified that my code not always works correctly - in one situation at me the attribute receives an incorrect insertion point. I put a problem file.

In a dwg-file I have created two determinations of the unit: annotative ("www") and normal ("www2").

Has created entrances of these units. Then I have changed unit determination "www2" (yellow objects in the drawing). If to cause on this unit my command ""MySynch"the attribute"GGG"for already existing entrances of units is allocated in a point 0,0, instead of there where should.

If after a command "MySynch" I push CTRL keys + Z I will receive a fatal error:



kaefer:
Sorry for the F# example. The corresponding C# is little bit less sharp, for the want of partial application, but I think it's similar to what you have already, except for the cryptic join clauses.


--- Code: ---        public static IEnumerable<T> DifferenceBy<T, U>(this IEnumerable<T> t, Func<T, U, bool> predicate, IEnumerable<U> s)
        {
            return t.Where(n => !s.Any(o => predicate(n, o)));
        }
        public static IEnumerable<T> IntersectBy<T, U>(this IEnumerable<T> t, Func<T, U, bool> predicate, IEnumerable<U> s)
        {
            return t.Where(n => s.Any(o => predicate(n, o)));
        }

--- End code ---

BTW shouldn't line 162 of your current version be like this, attn. underline?

--- Code: ---                    IEnumerable<AttributeDefinition> attdefs2 = _btr.Cast<ObjectId>()

--- End code ---

Andrey:
I thank for the found out error!
I have made changes to the code and have published its new version.

Changes:

1. Superfluous AttributeReference I have moved removal so that this action was before editing and adding new AttributeReference. (code line 67).
2. Has eliminated from processed dial-up AttributeDefinition, at which property Const = true (code line 43).
3. Has rectified the error specified by you with underlining (code line 163).

Unfortunately, if after command MySynch to push Ctrl + Z автокад fails on the former.

Navigation

[0] Message Index

[#] Next page

Go to full version