.NET

.NET

Reply
Active Contributor
calvindale
Posts: 33
Registered: ‎03-11-2010
Message 1 of 13 (544 Views)

Block Created and Inserted Shows Text Entities at Origin Until Regen'd By User

544 Views, 12 Replies
08-30-2012 04:38 PM

I've written a method that creates a block definition and inserts one instance the newly created block definition.  The block is comprised exclusively of lines and text entities.  When the method is completed, all entities appear correctly on my machine.

 

However, when other users try to run the routine on their machines, the lines appear correctly but the text entities all appear positioned at the block insertion's origen.  And the other users must manually regen the drawing after the command is run to trigger the text entities to move (or appear to move) into their proper location.

 

Though it wasn't necessary on my machine, I tried adding the following line as the last instruction in my command-method:

 

   _drawing.Editor.Regen();

 

But even that last line's programmatically-triggered regen didn't solve the text location issue for my users.  They still have to manually regen.

 

I also ensured that all (or most) of a test user's system variables were set to the same values that I use (via Express Tools export & import).  But that didn't help either.

 

So I'm at a loss as to what could possibly be causing the discrepant behavior.  Any ideas?

 

THANKS!

*Expert Elite*
Alfred.NESWADBA
Posts: 9,583
Registered: ‎06-29-2007
Message 2 of 13 (525 Views)

Re: Block Created and Inserted Shows Text Entities at Origin Until Regen'd By Us

08-31-2012 08:47 AM in reply to: calvindale

Hi,

 

are you really speaking about TEXT-objects in the BlockReference or are these object AttributeReferences?

If you run your code that inserts the BlockReference and then start _AUDIT instead of any other command like _REGEN ...does AutoCAD bring up any database-errors?

 

The code-snippet would be great to see

The version of AutoCAD + ServicePack (pluse vertical information if it's a vertical product) may also help

To check the gc, maybe to toggle the hardware-acceleration is always a good idea. :smileywink:

 

- alfred -

 

-------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at
-------------------------------------------------------------------------
Active Contributor
calvindale
Posts: 33
Registered: ‎03-11-2010
Message 3 of 13 (515 Views)

Re: Block Created and Inserted Shows Text Entities at Origin Until Regen'd By Us

08-31-2012 01:25 PM in reply to: Alfred.NESWADBA

Thanks for the feedback.  I haven't had time to follow up on this fully yet.  And I probably won't get around to it until after the holiday weekend.

 

However, we did determine that if AutoCAD is launced to the VANILLA profile rather than the ACADMPP profile, it does indeed work correctly for my users.  I personally use the vanilla profile and haven't tested it in the mechanical profile on my machine.  And AutoCAD has to be launched to the vanilla profile rather than merely settting the vanilla profile current during the session.

 

I'll investigate further on Tuesday.

 

Active Contributor
calvindale
Posts: 33
Registered: ‎03-11-2010
Message 4 of 13 (466 Views)

Re: Block Created and Inserted Shows Text Entities at Origin Until Regen'd By Us

09-04-2012 01:18 PM in reply to: Alfred.NESWADBA

AUDIT didn't reveal any errors.  We're running AutoCAD Mechanical 2011 Version 3 (E.208.0.0).  The block only contains TEXT entities (i.e., there are no ATTDEFs).

Distinguished Mentor
gasty1001
Posts: 582
Registered: ‎04-11-2010
Message 5 of 13 (452 Views)

Re: Block Created and Inserted Shows Text Entities at Origin Until Regen'd By Us

09-04-2012 06:39 PM in reply to: calvindale

Hi,

 

Please post the code, in particular the block definition part of the code.

 

Gaston Nunez

Active Contributor
calvindale
Posts: 33
Registered: ‎03-11-2010
Message 6 of 13 (443 Views)

Re: Block Created and Inserted Shows Text Entities at Origin Until Regen'd By Us

09-05-2012 08:23 AM in reply to: gasty1001

There are about 1500 lines of code involved in the generation of these blocks.  And I really don't have time now to simplify this code simply to post it here.  I have however attached an image which shows the resulting blocks (highlighted in yellow).  But I suspect that my block-generation code is not source of the discrepant behavior between AutoCAD Vanilla and Mechanical; I'm not sure though.

 

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 7 of 13 (431 Views)

Re: Block Created and Inserted Shows Text Entities at Origin Until Regen'd By Us

09-05-2012 09:41 AM in reply to: calvindale

Show us just a code block where you do create the text within block

with all text settings, it's enough to see the problem

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Active Contributor
calvindale
Posts: 33
Registered: ‎03-11-2010
Message 8 of 13 (425 Views)

Re: Block Created and Inserted Shows Text Entities at Origin Until Regen'd By Us

09-05-2012 10:25 AM in reply to: Hallex

Ok,

 

Here's the main procedure.

        public void ConstructMatrix() {
            HubAssemblyMatrix.EraseHubAssemblyMatrix(_document);
            Application.UpdateScreen();
            _matrixData = _matrixBuilder.BuildMatrixData();
            GetInsertionPointAndScaleFactor();
            _metrics = new MatrixPositionMetrics(_matrixData);
            using (var transaction = _database.TransactionManager.StartTransaction()) {
                var blockTable = (BlockTable)transaction.GetObject(_database.BlockTableId, OpenMode.ForRead);
                var blockTableRecord = new BlockTableRecord() { Name = HubAssemblyMatrix.MatrixBlockName };
                blockTable.UpgradeOpen();
                var blockTableRecordId = blockTable.Add(blockTableRecord);
                transaction.AddNewlyCreatedDBObject(blockTableRecord, true);
                using (var entities = ConstructEntities()) {
                    foreach (var entity in entities.OfType<Entity>()) {
                        blockTableRecord.AppendEntity(entity);
                        transaction.AddNewlyCreatedDBObject(entity, true);
                    }
                }
                var modelSpace = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                var blockReference = new BlockReference(_insertionPoint, blockTableRecordId);
                blockReference.SetDatabaseDefaults();
                blockReference.ScaleFactors = new Scale3d(_scaleFactor);
                blockReference.LayerId = _layerObjectIdZero;
                modelSpace.AppendEntity(blockReference);
                transaction.AddNewlyCreatedDBObject(blockReference, true);
                transaction.Commit();
            }
            Application.UpdateScreen();
            _document.Editor.Regen(); //Added because Naomi's machine required a regen after completion
        }

Entity and text construction:

        private DBObjectCollection ConstructEntities() {
            _entities = new DBObjectCollection();
            AddVerticalLines();
            AddHorizontalLines();
            AddText();
            foreach (var entity in _entities.OfType<Entity>()) {
                entity.LayerId = _layerObjectIdBorder;
            }
            return _entities;
        }

        private void AddText() {
            _textStyleIdTahoma = TextStyle.StandardTextStyle.Tahoma.EnsureExists(_document);
            _textStyleIdTahomaBold = TextStyle.StandardTextStyle.TahomaBold.EnsureExists(_document);
            AddRowLabels();
            AddPartRevisionWeightAndStandout();
            if (_matrixData.Type == MatrixData.MatrixType.WithDrum)
                AddBrakeDrumDimensions();
            if (_matrixData.HasChildHubAssemblies)
                AddComponentHubAssemblyNumbers();
            AddXs();
            AddItemQuantityUnitPartNumberDescriptionAndMaterial();
        }

 Text style creator:

        public static ObjectId EnsureExists(this StandardTextStyle textStyle, Document document) {
            var database = document.Database;
            using (document.LockDocument()) {
                using (Transaction transaction = database.TransactionManager.StartTransaction()) {
                    var textStyleTable = (TextStyleTable)transaction.GetObject(database.TextStyleTableId, OpenMode.ForRead);
                    var styleName = textStyle.ToStyleName();
                    if (textStyleTable.Has(styleName))
                        return textStyleTable[styleName];
                    textStyleTable.UpgradeOpen();
                    var textStyleTableRecord = new TextStyleTableRecord() {
                        Font = new FontDescriptor(textStyle.ToTypeface(), textStyle.IsBold(), false, textStyle.ToCharacterSet(), textStyle.ToPitchAndFamily()),
                        Name = styleName,
                        FileName = textStyle.ToPathFileNameValidated()
                    };
                    var textStyleObjectId = textStyleTable.Add(textStyleTableRecord);
                    transaction.AddNewlyCreatedDBObject(textStyleTableRecord, true);
                    transaction.Commit();
                    return textStyleObjectId;
                }
            }
        }

 And finally some text creation

        private void AddPartRevisionWeightAndStandout() {
            double positionX = -(_metrics.PartNumberColumnWidth / 2D);
            foreach (var item in _matrixData.RevisionWeightStandouts) {
                AddTextItemCenteredBold(positionX, _rowCenters.Revision, item.Revision);
                AddTextItemCenteredBold(positionX, _rowCenters.HubAssemblyNumber, item.HubAssemblyNumber);
                AddTextItemCenteredLight(positionX, _rowCenters.Weight, item.Weight);
                if (_matrixData.HasWheelStuds)
                    AddTextItemCenteredLight(positionX, _rowCenters.WheelStudStandout, item.WheelStudStandout);
                positionX -= _metrics.PartNumberColumnWidth;
            }
        }


        private void AddTextItemCenteredBold(double positionX, double positionY, string text) {
            AddTextItemCentered(positionX, positionY, text, _textStyleIdTahomaBold);
        }

        private void AddTextItemCentered(double positionX, double positionY, string text, ObjectId textStyleId) {
            AddTextItem(positionX, positionY, text, textStyleId, AttachmentPoint.MiddleCenter);
        }


        private void AddTextItem(double positionX, double positionY, string text, ObjectId textStyleId, AttachmentPoint attachmentPoint) {
            var textEntity = new DBText();
            textEntity.SetDatabaseDefaults();
            textEntity.ColorIndex = Colors.ColorIndex.White.ToInt();
            textEntity.Height = _metrics.TextHeight;
            textEntity.Justify = attachmentPoint;
            textEntity.TextString = text;
            textEntity.AlignmentPoint = new Point3d(positionX, positionY, 0);
            textEntity.TextStyleId = textStyleId;
            _entities.Add(textEntity);

        }

 Hopefully the foregoing code blocks shed some light on my doings.  However, I still question why the regen behavior (or lack thereof) would be different between the Vanilla and Mechanical profiles.

 

thanks for the help

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 9 of 13 (418 Views)

Re: Block Created and Inserted Shows Text Entities at Origin Until Regen'd By Us

09-05-2012 11:18 AM in reply to: calvindale

I tested your command to create text,

guess the problem is on you do justify text

before of specifying the text position

so try this instead

 

       private void AddTextItem(double positionX, double positionY, string text, ObjectId textStyleId, AttachmentPoint attachmentPoint)
        {
            var textEntity = new DBText();
            textEntity.SetDatabaseDefaults();
            textEntity.ColorIndex = Colors.ColorIndex.White.ToInt();
            textEntity.Height = _metrics.TextHeight;
            
            textEntity.TextString = text;
            textEntity.Position = new Point3d(positionX, positionY, 0);
            textEntity.Justify = attachmentPoint;
            textEntity.AlignmentPoint = new Point3d(positionX, positionY, 0);
            textEntity.TextStyleId = textStyleId;
            _entities.Add(textEntity);
        }

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Active Contributor
calvindale
Posts: 33
Registered: ‎03-11-2010
Message 10 of 13 (412 Views)

Re: Block Created and Inserted Shows Text Entities at Origin Until Regen'd By Us

09-05-2012 01:47 PM in reply to: Hallex

Hmmm, your suggestion does indeed affect behavior in the Mechanical profile.  However, it doesn't completely fully correct it.  In Mechanical, text position is now initially correct; but text alignment is not initially correct (until subsequently manually regenerated).  See the attached image.

 

I also have another routine that exhibits similarly discrepant behavior between the Mechanical and Vanilla profiles.  In this case, my code draws BOM-item/balloon highlighter entites (a faded-yellow polyline and a hatch).  And it draws them iteratively with a pause to enable the user to manually verify the correspondence of the item numbers.  In AutoCAD Vanilla these highlighter entities are drawn at full scale and positioned properly; but in Mechanical profile, they are not visible unless the routine is exited.

 

I assume the two problems are related.

 

Here's the code:

 

namespace ConMetAutoCadLibrary {
    public static class HubAssemblyMatrixChecker {

        /// <summary>
        /// Highlights each bom-item row and corresponding callout bubble pausing for user verification
        /// </summary>
        public static void CheckBomItemBalloonNumbersViaSuccessiveHighlight() {
            var document = Drawing.ActiveDocument();
            var drawingRevision = Border.DetermineDrawingNumberAndRevision(Drawing.ActiveDocument());
            if (drawingRevision.DrawingNumber == default(string))
                throw new ApplicationException("A part number (i.e., the matrix drawing number) cannot be extracted from either the drawing name or the border attributes\nTherefore a hub assembly matrix BOM-items cannot be successively highlighted");
            if (drawingRevision.Revision == default(string))
                throw new ApplicationException("A revision cannot be extracted from either the drawing name or the border attribute\nTherefore a hub assembly matrix BOM-items cannot be successively highlighted");
            var cultureInfo = CultureInfo.CreateSpecificCulture("en-US");
            var matrixBuilder = new MatrixDataBuilder(drawingRevision.DrawingNumber, drawingRevision.Revision, MatrixData.TargetApplication.AutoCAD, MatrixData.DisplayUnits.English, cultureInfo);
            var matrixData = matrixBuilder.BuildMatrixData();
            //CursorExtensions.SetWaitCursor(() => { matrixData = matrixBuilder.BuildMatrixData(); });
            var metrics = new HubAssemblyMatrixGenerator.MatrixPositionMetrics(matrixData);
            var insertionPointAndScaleFactor = HubAssemblyMatrix.GetHubAssemblyMatrixInsertionPointAndScaleFactor(document);
            var xOffset = insertionPointAndScaleFactor.InsertionPoint.X;
            var yOffset = insertionPointAndScaleFactor.InsertionPoint.Y;
            double yPosition = yOffset;
            var groups = matrixData.BomItems.GroupBy(_ => _.BalloonNumber);
            var transparency = new Transparency(75);
            Layer.EnsureLayerConstructionSilent(false);
            //var objectIdCollection = new ObjectIdCollection();
            var dbObjectCollection = new DBObjectCollection();
            foreach (var group in groups) {
                var rowHeight = (metrics.MatrixBOMRowHeight * group.Count()) * insertionPointAndScaleFactor.ScaleFactor;
                yPosition += (rowHeight / 2D);
                //objectIdCollection.Clear();
                dbObjectCollection.Clear();
                var layerId = Layer.StandardLayer.Construction.GetObjectId(document);
                using (var transaction = document.TransactionManager.StartTransaction()) {
                    var blockTable = transaction.GetObject(document.Database.BlockTableId, OpenMode.ForRead) as BlockTable;
                    var blockTableRecord = transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                    var polyline = new Polyline();
                    polyline.SetDatabaseDefaults();
                    polyline.AddVertexAt(0, new Point2d(xOffset, yPosition), 0, 0, 0);
                    polyline.AddVertexAt(1, new Point2d(xOffset + metrics.RightLineOffsetMaterial * insertionPointAndScaleFactor.ScaleFactor, yPosition), 0, 0, 0);
                    polyline.Transparency = transparency;
                    polyline.LayerId = layerId;
                    polyline.ColorIndex = Colors.ColorIndex.Yellow.ToInt();
                    polyline.ConstantWidth = rowHeight;
                    dbObjectCollection.Add(polyline); blockTableRecord.AppendEntity(polyline);
                    //objectIdCollection.Add(blockTableRecord.AppendEntity(polyline));
                    transaction.AddNewlyCreatedDBObject(polyline, true);

                    //all 1 and 2 character numeric single-line text entities
                    var numberTextEntities = Texts.GetAllTextEntitiesSingleLine(document.Editor, true).ToDbObjects<DBText>(transaction).Where(_ => _.TextString.Length < 3 && _.TextString.All(c => Char.IsNumber(c)));
                    var hatches = HighlightRevisionBubble(document, group.First().BalloonNumber, transparency, insertionPointAndScaleFactor.ScaleFactor, numberTextEntities, layerId);
                    hatches.Apply(hatch => {
                        //var hatchId = blockTableRecord.AppendEntity(hatch);
                        //objectIdCollection.Add(hatchId);
                        dbObjectCollection.Add(hatch); blockTableRecord.AppendEntity(hatch);
                        transaction.AddNewlyCreatedDBObject(hatch, true);
                    });

                    transaction.Commit();
                    //document.Editor.UpdateScreen();
                    document.Editor.Regen(); //Added because Mechanical profile behaves differently than the Vanilla profile
                }

                var promptResult = document.Editor.GetString("Press ENTER to continue or ESCAPE to quit or any letter to retain");
                if (promptResult.Status != PromptStatus.OK) {
                    return;
                }

                using (var transaction = document.StartTransaction()) {
                    //Both .Reverse() and .Highlight() needed or .Erase() line will crash with => INTERNAL ERROR: !dbobji.cpp@7316: eNotOpenForWrite
                    foreach (var dbObject in dbObjectCollection.OfType<DBObject>().Reverse()) {
                        var entity = transaction.GetEntity(dbObject.ObjectId, OpenMode.ForWrite);
                        entity.Highlight(); //Needed (with .Reverse() above) or next line will crash with => INTERNAL ERROR: !dbobji.cpp@7316: eNotOpenForWrite
                        if (string.IsNullOrWhiteSpace(promptResult.StringResult)) {
                            entity.Erase();
                        }
                        else {
                            entity.ColorIndex = Colors.ColorIndex.Magenta.ToInt();
                        }
                    }
                    transaction.Commit();
                }
                document.Editor.UpdateScreen();
                //document.Editor.Regen(); //Added because Mechanical profile behaves differently than the Vanilla profile

                yPosition += (rowHeight / 2D);
            }
        }

        private static IEnumerable<Hatch> HighlightRevisionBubble(Document document, int balloonNumber, Transparency transparency, double scaleFactor, IEnumerable<DBText> numberTextEntities, ObjectId layerId) {
            var listOfHatches = new List<Hatch>();
            using (var transaction = document.StartTransaction()) {
                var possibleBalloonTexts = numberTextEntities.Where(_ => _.TextString == balloonNumber.ToString()).ToArray();
                if (possibleBalloonTexts.Any()) {
                    var possibleBalloonCircles = GetAllPotentialBalloonCircles(document, transaction, scaleFactor);
                    foreach (var possibleBalloonText in possibleBalloonTexts) {
                        var surroundingCircle = GetSurroundingCircle(possibleBalloonCircles, possibleBalloonText, scaleFactor);
                        if (surroundingCircle != default(Circle))
                            listOfHatches.Add(HighlightBalloon(surroundingCircle, transparency, layerId));
                    }
                }
            }
            return listOfHatches;
        }

        private static List<Circle> GetAllPotentialBalloonCircles(Document document, Transaction transaction, double scaleFactor) {
            var listOfCircles = new List<Circle>();
            var blockTable = transaction.GetObject(document.Database.BlockTableId, OpenMode.ForRead) as BlockTable;
            var modelSpace = transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
            var minRadius = scaleFactor * .14;
            var maxRadius = scaleFactor * .3;
            foreach (var objectId in modelSpace) {
                var circle = transaction.GetEntity(objectId, OpenMode.ForRead) as Circle;
                if (circle == null)
                    continue;
                if (circle.Radius > minRadius && circle.Radius < maxRadius) {
                    listOfCircles.Add(circle);
                }
            }
            return listOfCircles;
        }

        private static Circle GetSurroundingCircle(List<Circle> possibleBalloonCircles, DBText possibleBalloonText, double scaleFactor) {
            if (possibleBalloonText.Bounds.HasValue) {
                var tolerance = 0.04 * scaleFactor;
                var x = (possibleBalloonText.Bounds.Value.MinPoint.X + possibleBalloonText.Bounds.Value.MaxPoint.X) / 2D;
                var y = (possibleBalloonText.Bounds.Value.MinPoint.Y + possibleBalloonText.Bounds.Value.MaxPoint.Y) / 2D;
                return possibleBalloonCircles.Where(_ => (Math.Abs(x - _.Center.X) < tolerance) && Math.Abs(y - _.Center.Y) < tolerance).OrderBy(_ => _.Radius).FirstOrDefault();
            }
            else
                return default(Circle);
        }

        private static Hatch HighlightBalloon(Circle surroundingCircle, Transparency transparency, ObjectId layerId) {
            var hatch = new Hatch();
            hatch.SetDatabaseDefaults();
            hatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");
            hatch.Associative = false;
            hatch.LayerId = layerId;
            hatch.ColorIndex = Colors.ColorIndex.Yellow.ToInt();
            hatch.Transparency = transparency;
            var objectIdCollection = new ObjectIdCollection();
            objectIdCollection.Add(surroundingCircle.ObjectId);
            hatch.AppendLoop(HatchLoopTypes.Outermost, objectIdCollection);
            hatch.EvaluateHatch(true);
            return hatch;
        }


    }
}

 

 

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.