.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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

12 REPLIES 12
Reply
Message 1 of 13
calvindale
815 Views, 12 Replies

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

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!

12 REPLIES 12
Message 2 of 13

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. 😉

 

- alfred -

 

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 3 of 13

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.

 

Message 4 of 13

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).

Message 5 of 13
hgasty1001
in reply to: calvindale

Hi,

 

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

 

Gaston Nunez

Message 6 of 13
calvindale
in reply to: hgasty1001

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.

 

Message 7 of 13
Hallex
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
Message 8 of 13
calvindale
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

Message 9 of 13
Hallex
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
Message 10 of 13
calvindale
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;
        }


    }
}

 

 

Message 11 of 13
Hallex
in reply to: calvindale

Sorry I can't help with it,

just an idea > try ed.UpdateScreen(); at the end of code

currently I just have a AutoCAD 2010 on my machine installed

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 12 of 13
calvindale
in reply to: Hallex

Yeah thanks...I have tried that and also with Editor.Regen()'s interspersed before and after.   So far to no avail.

 

Message 13 of 13
Balaji_Ram
in reply to: calvindale

Hi,

 

It is quite hard to say what might be causing it with only the code snippet.

 

You may try using the DBText.adjustAlignment method.

This is the explanation for this method from the documentation :

 

"....if the text entity is embedded in another entity, it will never be closed in
which case it won't automatically be adjusted....."

 

Also if you have side database, then ensure that it is the working database before calling the adjustAlignment method.

 

 

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost