Drawable Overrule not plotting through viewport.

Drawable Overrule not plotting through viewport.

Anonymous
Not applicable
927 Views
6 Replies
Message 1 of 7

Drawable Overrule not plotting through viewport.

Anonymous
Not applicable

I have created a DrawableOverrule which will draw a polyline as a table.  This draws and plots fine from model space.  When I view it through a paperspace viewport, it still looks good, but when I plot, it doesn't show up at all.  

 

I have tested this on both 2015 and 2016 versions of Civil 3d.  Can anybody help with what I am missing?  

 

I have even tried changing my overrule to as simple as drawing a circle and even that will not plot through a paperspace viewport.  Here is the simple example which will not plot but shows up fine on the screen and also plots fine from model space (it draws a circle instead of the polyline):

 

public override bool WorldDraw(Drawable drawable, WorldDraw wd)
        {
            var polyline = drawable as Autodesk.AutoCAD.DatabaseServices.Polyline;
            if (polyline != null && polyline.ObjectId.IsValid)
            {
                var labelTable = polyline.ReadClassFromEntity<LabelTable>();
                if (labelTable == null) return base.WorldDraw(drawable, wd);

                wd.Geometry.Circle(labelTable.TableInsertionPoint.ToPoint3d(), 5, Vector3d.ZAxis);
                return true;
            }
            return base.WorldDraw(drawable, wd);
        }

 

If it helps, here is my overrule code.  It may not make sense out of context, but at least you can see what I'm doing and how I'm drawing the entities.

 

public override bool WorldDraw(Drawable drawable, WorldDraw wd)
        {
            var polyline = drawable as Autodesk.AutoCAD.DatabaseServices.Polyline;
            if(polyline!=null && polyline.ObjectId.IsValid)
            {
                var labelTable = polyline.ReadClassFromEntity<LabelTable>();
                if (labelTable == null) return base.WorldDraw(drawable, wd);

               
                ILabelTableSettings settings =
                    LabelTableSettings.GetLabelTableSettings(polyline.Database, true);
                
                if (settings == null) return base.WorldDraw(drawable, wd);

                // get intersections that are inside of our polyline
                var pipesPlugin = PlugInManager.GetPlugIn<PipesPlugIn>();
                if(pipesPlugin!=null)
                {
                    string annotationLayer = "0";
                    ObjectId annotationLayerId = ObjectId.Null;
                    string tableLayer = "0";
                    // GetPipeCrossings will consider whether or not a Viewport is part of the labeltable.
                    // GetPipeCrossings will convert intersection points?

                    var crossings = labelTable.GetPipeCrossings(polyline);
                    crossings.Sort((crossing, pipeCrossing) => crossing.IntersectionPoint.X.CompareTo(pipeCrossing.IntersectionPoint.X));

                    // get xdata values, table insertion point, text height
                    using (var tr = polyline.Database.TransactionManager.StartTransaction())
                    {
                        var layers = polyline.Database.LayerTableId.GetObject(OpenMode.ForRead) as LayerTable;
                        if(layers!=null)
                            foreach (var layer in layers)
                            {
                                var layerObj = layer.GetObject(OpenMode.ForRead) as LayerTableRecord;
                                if (layerObj!=null && layerObj.Name.EndsWith(settings.AnnotationLayer))
                                {
                                    annotationLayer = layerObj.Name;
                                    annotationLayerId = layer;
                                }
                                if (layerObj != null && layerObj.Name.EndsWith(settings.TableLayer))
                                {
                                    tableLayer = layerObj.Name;
                                }
                            }
                    }
                    var acadTable = new Table();
                    acadTable.SetDatabaseDefaults();
                    acadTable.Layer = tableLayer;
                    acadTable.Position = labelTable.TableInsertionPoint.ToPoint3d();
                    var mtext = new MText();
                    mtext.SetDatabaseDefaults();
                    mtext.Height = labelTable.TextHeight;
                    var columns = settings.Columns.ToList();
                    if (crossings.Count > 0)
                    {
                        acadTable.InsertColumns(0, mtext.Height * 12, columns.Count);
                        Enumerable.Range(0, columns.Count )
                            .ForEach(
                                x =>
                                {
                                    // get the column from the label table, we read the width and that is all.
                                    var myColumn =
                                        labelTable.Columns.FirstOrDefault(y => y.GetType() == columns[x].GetType());
                                    // if it doesn't exist, we just put it in there...it's the same reference, but no
                                    // worries, once we serialize and then deserialize, i think it will be unique.
                                    if (myColumn == null)
                                    {
                                        myColumn = columns[x];
                                        labelTable.Columns.Add(myColumn);
                                    }
                                    acadTable.Columns[x].Width = myColumn.WidthFactor*mtext.Height;
                                });

                        acadTable.InsertRows(0, mtext.Height * settings.RowHeightMultiplier, crossings.Count);

                        // sets up the first row
                        Enumerable.Range(0, columns.Count).ForEach(x =>
                        {
                            acadTable.Cells[0, x].TextHeight = mtext.Height*1.2;
                            acadTable.Cells[0, x].TextString = columns[x].Header;
                            acadTable.Rows[0].Height = mtext.Height*1.2*settings.RowHeightMultiplier;
                        });

                        int row = 1;
                        int crossingLabel = labelTable.StartIndex;
                        var doc = CivilApplication.ActiveDocument;
                        foreach (var crossing in crossings)
                        {
                            // todo: find the crossing by number
                            // crossing index is always first since we set it to Canreorder = false
                            acadTable.Cells[row, 0].TextHeight = mtext.Height;
                            acadTable.Cells[row, 0].TextString = crossingLabel.ToString();
                            acadTable.Rows[row].Height = mtext.Height*settings.RowHeightMultiplier;

                            for (int i = 1; i < columns.Count; i++)
                            {
                                acadTable.Cells[row, i].TextHeight = mtext.Height;
                                acadTable.Cells[row, i].TextString = columns[i].GetText(crossing);
                            }

                            row++;

                            // do we have an annotation point for this crossing?  it will fetch the default if one doesn't exist.
                            var annoPoints = labelTable.GetIntersectionAndAnnotationPoint(crossing.CrossingId);

                            // draw the label on the crossing
                            var leader = new Leader();
                            leader.SetDatabaseDefaults();
                            leader.Layer = annotationLayer;
                            leader.AppendVertex(annoPoints.Item1.ToPoint3d());
                            leader.AppendVertex(annoPoints.Item2.ToPoint3d());
                            leader.Dimasz = labelTable.TextHeight;
                            leader.Dimscale = 1;
                            leader.WorldDraw(wd);

                            // draw Hex and Text
                            // need text size on LabelTable
                            var hatch = new Hatch();
                            hatch.SetDatabaseDefaults();
                            hatch.Layer = annotationLayer;
                            hatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");
                            //hatch.ColorIndex = 1;
                            var loop = new Polyline();
                            loop.SetDatabaseDefaults();
                            loop.Layer = annotationLayer;
                            var vector = new Vector2d(labelTable.TextHeight * 1.1, 0);
                            var annoPoint = annoPoints.Item2;
                            loop.AddVertexAt(0, annoPoint.ToPoint2d().Add(vector), 0, 0, 0);
                            vector = vector.RotateBy(2*Math.PI/6);
                            loop.AddVertexAt(1, annoPoint.ToPoint2d().Add(vector), 0, 0, 0);
                            vector = vector.RotateBy(2 * Math.PI / 6);
                            loop.AddVertexAt(2, annoPoint.ToPoint2d().Add(vector), 0, 0, 0);
                            vector = vector.RotateBy(2 * Math.PI / 6);
                            loop.AddVertexAt(3, annoPoint.ToPoint2d().Add(vector), 0, 0, 0);
                            vector = vector.RotateBy(2 * Math.PI / 6);
                            loop.AddVertexAt(4, annoPoint.ToPoint2d().Add(vector), 0, 0, 0);
                            vector = vector.RotateBy(2 * Math.PI / 6);
                            loop.AddVertexAt(5, annoPoint.ToPoint2d().Add(vector), 0, 0, 0);
                            vector = vector.RotateBy(2 * Math.PI / 6);
                            loop.AddVertexAt(6, annoPoint.ToPoint2d().Add(vector), 0, 0, 0);
                            loop.Closed = true;
                            var points = new Point2dCollection();
                            for (int i = 0; i < loop.NumberOfVertices; i++)
                            {
                                points.Add(loop.GetPoint2dAt(i));
                            }
                            hatch.AppendLoop(HatchLoopTypes.Default, points, new DoubleCollection());
                            hatch.EvaluateHatch(false);
                            var color = wd.SubEntityTraits.Color;
                            wd.SubEntityTraits.Color = 247;
                            hatch.WorldDraw(wd);
                            wd.SubEntityTraits.Color = color;
                            wd.Geometry.Polyline(loop, 0, loop.NumberOfVertices);
                            var text = new DBText();
                            text.SetDatabaseDefaults();
                            text.Layer = annotationLayer;
                            text.Height = labelTable.TextHeight;
                            text.TextString = crossingLabel.ToString();
                            text.Position = annoPoint.ToPoint3d();
                            text.HorizontalMode = TextHorizontalMode.TextAlign;
                            text.Justify = AttachmentPoint.MiddleCenter;
                            text.AlignmentPoint = annoPoint.ToPoint3d();
                            text.AdjustAlignment(polyline.Database);
                            text.WorldDraw(wd);

                            // increment the label last
                            crossingLabel++;

                        }
                        acadTable.DeleteColumns(acadTable.Columns.Count-1, 1);
                        acadTable.InsertRows(0, mtext.Height*1.5, 1);
                        acadTable.MergeCells(CellRange.Create(acadTable, 0, 0, 0, columns.Count - 1));
                        acadTable.Cells[0, 0].TextString = "UTILITY CROSSINGS";
                        acadTable.Cells[0, 0].TextHeight = mtext.Height*1.4;
                        acadTable.Rows[0].Height = mtext.Height*1.4*settings.RowHeightMultiplier;
                        CellRange.Create(acadTable,0,0,acadTable.Rows.Count-1, acadTable.Columns.Count-1).Alignment = CellAlignment.MiddleCenter;
                        acadTable.WorldDraw(wd);
                        return true;
                    }
                }
            }
            return base.WorldDraw(drawable, wd);
        }
0 Likes
928 Views
6 Replies
Replies (6)
Message 2 of 7

Virupaksha_aithal
Autodesk Support
Autodesk Support

Hi

 

Can you provide buildable sample? Below code for circle is working fine (printing fine from paper space)

public class MyTestCommands
{
    private static circleOverrule _overruleCirle = null;
    [CommandMethod("circleOverrule")]
    public void circleOverrule()
    {
        if (_overruleCirle == null)
        {
            _overruleCirle = new circleOverrule();
            Overrule.AddOverrule(RXClass.GetClass(typeof(Circle)), _overruleCirle, false);
        }
        else
        {
            Overrule.RemoveOverrule(RXClass.GetClass(typeof(Circle)), _overruleCirle);
            _overruleCirle = null;
        }

        Application.DocumentManager.MdiActiveDocument.Editor.Regen();
    }
}

public class circleOverrule : Autodesk.AutoCAD.GraphicsInterface.DrawableOverrule
{
    public override bool WorldDraw(AcGi.Drawable drawable, AcGi.WorldDraw wd)
    {
        var circle = drawable as Circle;

        wd.Geometry.Circle(circle.Center, circle.Radius * 0.5, Vector3d.ZAxis);

        return base.WorldDraw(drawable, wd);
    }
}


Virupaksha Aithal KM
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 3 of 7

jdowthwaite
Enthusiast
Enthusiast

I'm currently having the same problem (in AutoCAD Map 2013) with overruled entities not plotting correctly in viewports.

 

Were you able to resolve this issue?

0 Likes
Message 4 of 7

Virupaksha_aithal
Autodesk Support
Autodesk Support

Hi,

 

Are you plotting in background? if yes, please try with plotting in Foreground (set BACKGROUNDPLOT = 0)



Virupaksha Aithal KM
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 5 of 7

jdowthwaite
Enthusiast
Enthusiast
We currently have BACKGROUNDPLOT set to 0. I've tested it with 0 and 1, neither makes a difference. The overrule entity is still not showing in the plot preview window or plotted file.

Was there a solution found for the case I reference in my original post?
0 Likes
Message 6 of 7

Virupaksha_aithal
Autodesk Support
Autodesk Support

Hi,

 

Can you please test the attached sample project at your end? Refer the screen cast of the working in AutoCAD 2013 at my end http://autode.sk/29sR5oz .



Virupaksha Aithal KM
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 7 of 7

Anonymous
Not applicable

I was recently forced to revisit this issue and get it resolved.

 

With help from the simple Circle overrule and getting it to work, I started troubleshooting my code and realized that the problem was caused by an uncomitted transaction.

 

My overrule worked perfectly in model, plotted in model, showed up through a viewport and everything, so I never thought there was a problem. But in order to know how to draw my table, I have to read information from the object and even though it was a READOnly transaction, I needed to commit() it to fix my issue.

 

Now it works as designed. It was a one-liner.

 

So apparently it's a good idea to always close your transactions. Lesson learned.

 

Thanks for the help.

0 Likes