Getting shape data from DxfModel

1 2 3    next >
TorbenVanAssche
4/20/2022 8:16 AM

We are trying to extract data from a DxfModel and cannot find how to get the actual shape.

Preferably, we would like to be able to get a list of coordinates from the Entities but that's not something I can find out how to retrieve. I have populated an array with the different DxfBlocks in the file, and am hoping to now get entities from that list (preferably some [x, y] formatting but I cannot find how this can be done from the docs).

Code:
//Read the Dwg file into memory
DwgReader dwgReader = new(fileName);
DxfModel dxfModel = dwgReader.Read();

//Get the blocks in the file
DxfBlock[] blocks = GetBlocks(dxfModel);
var entities = blocks[0].Entities;

Wout
4/20/2022 9:53 AM

Hi,

If you're using CadLib 4.0/5.0 (for Windows), there's a GetCoordinates example in the Examples directory. I'll copy the code below:

C# Code:
#region (C) Wout Ware 2006-2011
//
// File: Program.cs
//
// (c) 2006-2011 Wout Ware All Rights Reserved.
//
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;

using WW.Cad.Drawing;
using WW.Cad.Model;
using WW.Cad.Model.Entities;
using WW.Drawing;
using WW.Math;
using WW.Math.Geometry;

namespace GetCoordinates {
    /// <summary>
    /// Entities are drawn onto the coordinates collector, which writes the coordinates
    /// of the line segments to the console.
    /// </summary>
    /// <remarks>
    /// Serves as an example <see cref="IWireframeGraphicsFactory"/> implementation.
    /// </remarks>
    /// <seealso cref="IWireframeGraphicsFactory"/>
    class CoordinatesCollector : BaseWireframeGraphicsFactory {
        public override void CreateDot(
            DxfEntity entity,
            DrawContext.Wireframe drawContext, 
            ArgbColor color, 
            bool forText, 
            Vector4D position
        ) {
            Point3D point = (Point3D)position;
            Console.WriteLine("Dot: {0}", point.ToString());
        }

        public override void CreateLine(
            DxfEntity entity,
            DrawContext.Wireframe drawContext,
            ArgbColor color, 
            bool forText, 
            Vector4D start, 
            Vector4D end
        ) {
            Point3D point1 = (Point3D)start;
            Point3D point2 = (Point3D)end;
            Console.WriteLine("Line, start: {0}, end: {1}", start.ToString(), end.ToString());
        }

        public override void CreatePath(
            DxfEntity entity,
            DrawContext.Wireframe drawContext,
            ArgbColor color, 
            bool forText, 
            IList<Polyline4D> polylines, 
            bool fill,
            bool correctForBackgroundColor
        ) {
            WritePolylines(polylines);
        }

        public override void CreatePathAsOne(
            DxfEntity entity,
            DrawContext.Wireframe drawContext,
            ArgbColor color, 
            bool forText, 
            IList<Polyline4D> polylines,
            bool fill,
            bool correctForBackgroundColor
        ) {
            WritePolylines(polylines);
        }

        public override void CreateShape(
            DxfEntity entity, 
            DrawContext.Wireframe drawContext,
            ArgbColor color, 
            bool forText, 
            IShape4D shape
        ) {
            WritePolylines(shape.ToPolylines4D(ShapeTool.DefaultEpsilon));
        }

        private static void WritePolylines(IList<Polyline4D> polylines) {
            foreach (Polyline4D polyline in polylines) {
                Console.WriteLine("Polyline: {");
                foreach (Vector4D vector in polyline) {
                    Point3D point = (Point3D)vector;
                    Console.WriteLine("   {0}", point.ToString());
                }
                Console.WriteLine("}");
            }
        }
    }

    /// <summary>
    /// Create an example <see cref="DxfModel"/> and show all involved coordinates.
    /// </summary>
    class Program {
        static void Main(string[] args) {
            DxfModel model = new DxfModel();
            model.Entities.Add(new DxfCircle(new Point3D(3, 0, 1), 1));
            model.Entities.Add(new DxfLine(new Point3D(3, 0, 1), new Point3D(5, 2, 1)));

            CoordinatesCollector coordinatesCollector = new CoordinatesCollector();
            DrawContext.Wireframe drawContext = 
                new DrawContext.Wireframe.ModelSpace(
                    model, 
                    GraphicsConfig.BlackBackground, 
                    Matrix4D.Identity
                );
            model.Draw(drawContext, coordinatesCollector);

            Console.WriteLine("Press enter...");
            Console.ReadLine();
        }
    }
}

- Wout

TorbenVanAssche
4/20/2022 10:07 AM

Thank you for the quick reply,

We are currently using the .NET Standard 2.0 version (our client's back-end is .NET Core as far as I can tell).
The other DLL for both 4.0 and 5.0 were throwing errors upon installation.

The 'CoordinatesCollector' does not appear to be available in this version as far as I can tell.
I assume this is limited to the 2 versions you mentioned?

- Torben

Wout
4/20/2022 10:21 AM

Hi,

I just haven't included the sample in the other 2 versions yet, but it should work for those too, perhaps with very minor modification.

What errors did you get for 4.0/5.0? 4.0 should be fine, 5.0 is fairly new so perhaps there are still some occasional hiccups with it.

- Wout

TorbenVanAssche
4/20/2022 11:48 AM

Hello,

This may be a me-problem but looking at the documentation I don't see the coordinates you mention there.

I just tried importing the 5.0 package, after generating a license for a trial I now have this error popping up,
likely to do with some file missing somewhere

Wout
4/20/2022 11:54 AM

Hi,

Since this is the Windows version, you need to set TargetFramework to net5.0-windows and set UseWindowsForms to true in your project file:

C# Code:
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0-windows</TargetFramework>
    <DisableWinExeOutputInference>true</DisableWinExeOutputInference>
    <UseWindowsForms>true</UseWindowsForms>

I don't really like how Microsoft changed the way of simply referencing the assemblies you need. It's just become messy in my opinion.

- Wout

TorbenVanAssche
4/20/2022 11:57 AM

Hello,

I cannot change this myself sadly. I will forward this forum post to the relevant parties and see what they can do to help...
The entire framework we have is built on the current framework version, I don't know if I can just change that.

TorbenVanAssche
4/20/2022 12:24 PM

Oh... I was looking for a "CoordinateCollector" class, not knowing you had included taht in your code snippet. That would explain why it isnt in the library documentation...

TorbenVanAssche
4/21/2022 2:07 PM

After carefully applying your suggestion, we are getting a lot of PolyLine data from a file that only includes a rectangle. How should we proceed to identify only this shape and its PolyLines so that we can work with the data extracted as PolyLines? We need to correctly identify the x and y minimum and maximum of the shape so that we can process the data for our database lookup

Wout
4/21/2022 2:21 PM

I only see 2 polylines in the output, which is correct, because the rectangle in the drawing is drawn by 2 polylines.

- Wout

1 2 3    next >