“Hello, New Year!” Or we program NanoCAD using Visual Basic .NET

  • Tutorial
While browsing the documentation for the NanoCAD API that came with the SDK the other day, I suddenly noticed that the description of class members for the .NET API and MultiCAD.NET API was given in both C # and Visual Basic . And I thought: “But it’s great that there is a description for VB as well!”

And although honestly I don’t know VB at all, the code on the good old BASIC was last seen 100 years ago, but it's one of the languages ​​in which people begin to learn the basics of programming, so I decided to make my small contribution to the popularization of the program.

I must say that there is already a good article on Habr on the use of VB for NanoCAD , it discusses the combination of NanoCAD with Excel and how it can ultimately facilitate building design.

We will solve another, simpler and more festive task, draw a Christmas tree and wish the user a happy new year. Despite the fact that the article is devoted to VB, the code in C # will also be.

And since “New Year” is a costly holiday, we will focus on the free version for commercial use of NanoCAD 5.1 (but in theory it should work without problems under NC 8.X).

Also, we will not bypass Linux users , since C # code using Mono and Wine can be compiled and run on it.

To be honest, I myself just recently started to master the NanoCAD API and therefore my last holiday article this year reminds me of the warm tube graphic artist "Kengurenok (ROO)" in code complexity , but if this doesn’t stop you, I’m kindly asking you to…



PS This is the first letter of the word "Habrahabr" - I wasn’t enough for more =)


Since my new hobby is already turning into a small series of articles, just in case, I’ll give links to all previous articles under the spoiler:


To begin with, as usual, I remind you that I'm not a programmer and therefore not all my thoughts in this article can be 100% correct, and also that I have nothing to do with the NanoCAD developers , just for ideological reasons I popularize Russian CAD.

At the end of the year, I don’t want to produce a mountain of text, so the article will be short, that’s what we will analyze.

Contents:
Part I: introduction
Part II: write code in C #
Part III: write code in VB
Part IV: Happy New Year!

Part II: writing C # code


How to create a new project in Visual Studio 2015 for NC 8.5 I have already said before .

This time, for the sake of curiosity, let's create a project in the more lightweight IDE Xamarin Studio ( MonoDevelop ).

I’ll hide the whole process under the spoiler.

How to create a C # project for NanoCAD 5.1 in the Xamarin Studio IDE
First, create a new project and select the C # class library.



Give it a name.



Then configure the project by clicking on it with the RMB and selecting the “Options” button.



Select the .Net 3.5 version.



Then, for debugging convenience, configure the launch of Nanocad by pressing the “F5” key
(each time making changes to the code, Nanocad will need to be restarted completely)



Then we will load the links to the libraries we need the ones that are displayed on the right of the picture



Do the mapimgd library do not forget to uncheck the option “copy locally”



Well, actually it remains to write the code click F5 and see that everything starts



To load your library, enter the Netload command in the NanoCAD console and select your dll (usually it is in the project folder, for example, C: \ Users \ b \ Dev \ habr \ XMTree \ XMTree \ bin \ Debug)

so that it doesn’t to do
Let's go to the address C: \ ProgramData \ Nanosoft \ nanoCAD 5.1 \ DataRW (it may differ from you) and find or create the file load.config with the following contents


After that, the libraries will be loaded automatically when the program starts.

Similar manipulations can be performed under Linux, where we need Wine to run NanoCAD 5.1, and MonoDevelop to program. I described in more detail in the last article .

Unfortunately, there I had some problems with Wine and the colors of NanoCAD were broken in some places, so our Linux tree will look like this:

Christmas tree under Linux



We will not disassemble the C # code in detail, we practically do nothing new.

In short, we create a team that draws polylines and strokes them.
Code under the spoiler and on GitHub (there is also a version for VB).

Full code for NC 5.1 in C #
//Use Microsoft .NET Framework 3.5 and old version of MultiCad.NET (for NC 5.1)
//Class for demonstrating the capabilities of MultiCad.NET
//Assembly for the Nanocad 5.1 
//Link mapimgd from Nanocad SDK
//Link System.Windows.Forms and System.Drawing
//The commands: draws a christmas three.
//This code in the part of non-infringing rights Nanosoft can be used and distributed in any accessible ways.
//For the consequences of the code application, the developer is not responsible.
//The code was not tested with NANOCAD 8.X.
// However, it should work, if you  update SDK libraries and include NC 8.X dll
using System.Collections.Generic;
using System.Linq;
using Multicad.Runtime;
using Multicad.DatabaseServices;
using Multicad.Geometry;
using Multicad.DatabaseServices.StandardObjects;
using System.Drawing;
using System.Windows.Forms;
namespace XmasThree
{
    class XmasThree
    {
        [CommandMethod("DXThree", CommandFlags.NoCheck | CommandFlags.NoPrefix)]
        public void DrawXThree()
        {
            Point3d _pntBase;
            Point3d _bufPnt;
            //prompts for installation point entry
            InputJig jig = new InputJig();
            // Get the first box point from the jig
            InputResult res = jig.GetPoint("Select first point:");
            //It works only if input was successful
            if (res.Result == InputResult.ResultCode.Normal)
            {
                // The base point is taken from the entry point (click with mouse)
                _pntBase = res.Point;
                //Draw the outline of the left half of the Christmas tree
                //Create base points for the polyline
                List leftPatrOfThreePoints = new List()
                {
                    new Point3d(_pntBase.X, _pntBase.Y, 0),
                    new Point3d(_pntBase.X-125, _pntBase.Y-154, 0),
                    new Point3d(_pntBase.X-31, _pntBase.Y-137, 0),
                    new Point3d(_pntBase.X-181, _pntBase.Y-287, 0),
                    new Point3d(_pntBase.X-31, _pntBase.Y-253, 0),
                    new Point3d(_pntBase.X-242, _pntBase.Y-400, 0),
                    new Point3d(_pntBase.X-37, _pntBase.Y-400, 0),
                    new Point3d(_pntBase.X-37, _pntBase.Y-454, 0),
                    new Point3d(_pntBase.X, _pntBase.Y-454, 0)
                };
                //Create a polyline (geometry)
                Polyline3d leftPatrOfThree = new Polyline3d(leftPatrOfThreePoints);
                //Create a polyline object and place it on the drawing
                DbPolyline XThreeLeft = new DbPolyline();
                XThreeLeft.Polyline = new Polyline3d(leftPatrOfThree);
                XThreeLeft.Polyline.SetClosed(false);
                XThreeLeft.DbEntity.Color = Color.Green;
                XThreeLeft.DbEntity.AddToCurrentDocument();
                //The right part of the tree is obtained by mirroring the left
                DbPolyline XThreeRight = new DbPolyline();
                XThreeRight.DbEntity.Color = Color.Green;
                XThreeRight.Polyline = (Polyline3d)XThreeLeft.Polyline.Mirror(new Plane3d(_pntBase, new Vector3d(10, 0, 0)));
                XThreeRight.DbEntity.AddToCurrentDocument();
                //From the right and left sides we make a single contour for hatching
                DbPolyline XThreeR = new DbPolyline();
                XThreeR.DbEntity.Color = Color.Green;
                //XThreeR.Polyline = XThreeRight.Polyline.Clone() as Polyline3d; for NC 8.5
                XThreeR.Polyline = XThreeRight.Polyline.GetCopy() as Polyline3d; //FOR NC 5.1
                XThreeR.DbEntity.AddToCurrentDocument();
                List hatchPoints = new List();
                hatchPoints.AddRange(leftPatrOfThreePoints);
                hatchPoints.AddRange(XThreeR.Polyline.Points.Reverse().ToList());
                Polyline3d hatchContur = new Polyline3d(hatchPoints);
                //We will create on the basis of a contour a hatch (geometry) with continuous filling 
                Hatch hatch = new Hatch(hatchContur, 0, 10, true);
                hatch.PattType = PatternType.PreDefined;
                hatch.PatternName = "SOLID";
                //Based on the geometry of the hatch, we create the document object, set its color properties - green
                DbGeometry dbhatch = new DbGeometry();
                dbhatch.Geometry = new EntityGeometry(hatch);
                dbhatch.DbEntity.Color = Color.Green;
                dbhatch.DbEntity.AddToCurrentDocument();
                // if you want you can try to draw balls with circles use
                // DrawThreeBalls(_pntBase);
                //Similarly, make a Christmas tree toy (octagon)
                //red
                _bufPnt = _pntBase.Subtract(new Vector3d(30, 95, 0));
                DbPolyline dbOctoRed = DrawThreeOctogonPl(_bufPnt);//implicit
                dbOctoRed.DbEntity.AddToCurrentDocument();
                Hatch hatchCirkRed = new Hatch(dbOctoRed.Polyline, 0, 1, false);
                hatchCirkRed.PattType = PatternType.PreDefined;
                hatchCirkRed.PatternName = "SOLID";
                DbGeometry dbhatchCirkRed = new DbGeometry();
                dbhatchCirkRed.Geometry = new EntityGeometry(hatchCirkRed);
                dbhatchCirkRed.DbEntity.Color = Color.Red;
                dbhatchCirkRed.DbEntity.AddToCurrentDocument();
                //green
                _bufPnt = _pntBase.Subtract(new Vector3d(-40, 200, 0));
                DbPolyline dbOctoGreen = DrawThreeOctogonPl(_bufPnt);//implicit
                dbOctoGreen.DbEntity.AddToCurrentDocument();
                Hatch hatchCirkGreen = new Hatch(dbOctoGreen.Polyline, 0, 1, false);
                hatchCirkGreen.PattType = PatternType.PreDefined;
                hatchCirkGreen.PatternName = "SOLID";
                DbGeometry dbhatchCirkGreen = new DbGeometry();
                dbhatchCirkGreen.Geometry = new EntityGeometry(hatchCirkGreen);
                dbhatchCirkGreen.DbEntity.Color = Color.LightSeaGreen;
                dbhatchCirkGreen.DbEntity.AddToCurrentDocument();
                //blue
                _bufPnt = _pntBase.Subtract(new Vector3d(-12, 350, 0));
                DbPolyline dbOctoBlue = DrawThreeOctogonPl(_bufPnt);//implicit
                dbOctoBlue.DbEntity.AddToCurrentDocument();
                Hatch hatchCirkBlue = new Hatch(dbOctoBlue.Polyline, 0, 1, false);
                hatchCirkBlue.PattType = PatternType.PreDefined;
                hatchCirkBlue.PatternName = "SOLID";
                DbGeometry dbhatchCirkBlue = new DbGeometry();
                dbhatchCirkBlue.Geometry = new EntityGeometry(hatchCirkBlue);
                dbhatchCirkBlue.DbEntity.Color = Color.Blue;
                dbhatchCirkBlue.DbEntity.AddToCurrentDocument();
                //display the text with congratulations
                MessageBox.Show("I Wish You A Merry Christmas And Happy New Year!");
            }
        }
        public Polyline3d DrawThreeOctogonPl(Point3d _pntB)
        {
            //Create points for an octagon
            List octoPoints = new List()
                {
                    new Point3d(_pntB.X, _pntB.Y, 0),
                    new Point3d(_pntB.X-15, _pntB.Y, 0),
                    new Point3d(_pntB.X-25, _pntB.Y-11.3, 0),
                    new Point3d(_pntB.X-25, _pntB.Y-26.3, 0),
                    new Point3d(_pntB.X-15, _pntB.Y-37.6, 0),
                    new Point3d(_pntB.X, _pntB.Y-37.6, 0),
                    new Point3d(_pntB.X+9.7, _pntB.Y-26.3, 0),
                    new Point3d(_pntB.X+9.7, _pntB.Y-11.3, 0),
                    new Point3d(_pntB.X, _pntB.Y, 0)
                };
            return new Polyline3d(octoPoints);
        }
        //Draws three balls instead of an octagon, can not earn in NanoCAD 8.X
        public void DrawThreeBalls(Point3d _pntB)
        {
            CircArc3d circarcRed = new CircArc3d(_pntB.Subtract(new Vector3d(30, 100, 0)), Vector3d.ZAxis, 15);
            DbCircArc dbCircarcRed = circarcRed;//implicit
            dbCircarcRed.DbEntity.AddToCurrentDocument();
            Hatch hatchCirkRed = new Hatch(circarcRed, 0, 1, false);
            hatchCirkRed.PattType = PatternType.PreDefined;
            hatchCirkRed.PatternName = "SOLID";
            DbGeometry dbhatchCirkRed = new DbGeometry();
            dbhatchCirkRed.Geometry = new EntityGeometry(hatchCirkRed);
            dbhatchCirkRed.DbEntity.Color = Color.Red;
            dbhatchCirkRed.DbEntity.AddToCurrentDocument();
            CircArc3d circarcGreen = new CircArc3d(_pntB.Subtract(new Vector3d(-40, 200, 0)), Vector3d.ZAxis, 15);
            DbCircArc dbCircarcGreen = circarcGreen;//implicit
            dbCircarcGreen.DbEntity.AddToCurrentDocument();
            Hatch hatchCirkGreen = new Hatch(circarcGreen, 0, 1, false);
            hatchCirkGreen.PattType = PatternType.PreDefined;
            hatchCirkGreen.PatternName = "SOLID";
            DbGeometry dbhatchCirkGreen = new DbGeometry();
            dbhatchCirkGreen.Geometry = new EntityGeometry(hatchCirkGreen);
            dbhatchCirkGreen.DbEntity.Color = Color.LightSeaGreen;
            dbhatchCirkGreen.DbEntity.AddToCurrentDocument();
            CircArc3d circarcBlue = new CircArc3d(_pntB.Subtract(new Vector3d(-12, 350, 0)), Vector3d.ZAxis, 15);
            DbCircArc dbCircarcBlue = circarcBlue;//implicit
            dbCircarcBlue.DbEntity.AddToCurrentDocument();
            Hatch hatchCirkBlue = new Hatch(circarcBlue, 0, 1, false);
            hatchCirkBlue.PattType = PatternType.PreDefined;
            hatchCirkBlue.PatternName = "SOLID";
            DbGeometry dbhatchCirkBlue = new DbGeometry();
            dbhatchCirkBlue.Geometry = new EntityGeometry(hatchCirkBlue);
            dbhatchCirkBlue.DbEntity.Color = Color.Blue;
            dbhatchCirkBlue.DbEntity.AddToCurrentDocument();
        }
    }
}

In theory, this code should work in NC 8.X too, it will only be necessary to choose the .NET Framework 4.0 to include mapibasetypes.dll and mapimgd.dll in the project from the include folder of the corresponding bit capacity (x64 or x86) and replace one line (where the corresponding comment is, and also comment out or delete the DrawThreeBalls method.

It turns out like this:

Full code for NC 8.X in C #
//Use Microsoft .NET Framework 4 and old version of MultiCad.NET (for NC 8.X)
//Class for demonstrating the capabilities of MultiCad.NET
//Assembly for the Nanocad 8.X 
//Link mapimgd and mapibasetypes from Nanocad SDK
//Link System.Windows.Forms and System.Drawing
//The commands: draws a christmas three.
//This code in the part of non-infringing rights Nanosoft can be used and distributed in any accessible ways.
//For the consequences of the code application, the developer is not responsible.
using System.Collections.Generic;
using System.Linq;
using Multicad.Runtime;
using Multicad.DatabaseServices;
using Multicad.Geometry;
using Multicad.DatabaseServices.StandardObjects;
using System.Drawing;
using System.Windows.Forms;
namespace XmasThree
{
    class XmasThree
    {
        [CommandMethod("DXThree", CommandFlags.NoCheck | CommandFlags.NoPrefix)]
        public void DrawXThree()
        {
            Point3d _pntBase;
            Point3d _bufPnt;
            //prompts for installation point entry
            InputJig jig = new InputJig();
            // Get the first box point from the jig
            InputResult res = jig.GetPoint("Select first point:");
            //It works only if input was successful
            if (res.Result == InputResult.ResultCode.Normal)
            {
                // The base point is taken from the entry point (click with mouse)
                _pntBase = res.Point;
                //Draw the outline of the left half of the Christmas tree
                //Create base points for the polyline
                List leftPatrOfThreePoints = new List()
                {
                    new Point3d(_pntBase.X, _pntBase.Y, 0),
                    new Point3d(_pntBase.X-125, _pntBase.Y-154, 0),
                    new Point3d(_pntBase.X-31, _pntBase.Y-137, 0),
                    new Point3d(_pntBase.X-181, _pntBase.Y-287, 0),
                    new Point3d(_pntBase.X-31, _pntBase.Y-253, 0),
                    new Point3d(_pntBase.X-242, _pntBase.Y-400, 0),
                    new Point3d(_pntBase.X-37, _pntBase.Y-400, 0),
                    new Point3d(_pntBase.X-37, _pntBase.Y-454, 0),
                    new Point3d(_pntBase.X, _pntBase.Y-454, 0)
                };
                //Create a polyline (geometry)
                Polyline3d leftPatrOfThree = new Polyline3d(leftPatrOfThreePoints);
                //Create a polyline object and place it on the drawing
                DbPolyline XThreeLeft = new DbPolyline();
                XThreeLeft.Polyline = new Polyline3d(leftPatrOfThree);
                XThreeLeft.Polyline.SetClosed(false);
                XThreeLeft.DbEntity.Color = Color.Green;
                XThreeLeft.DbEntity.AddToCurrentDocument();
                //The right part of the tree is obtained by mirroring the left
                DbPolyline XThreeRight = new DbPolyline();
                XThreeRight.DbEntity.Color = Color.Green;
                XThreeRight.Polyline = (Polyline3d)XThreeLeft.Polyline.Mirror(new Plane3d(_pntBase, new Vector3d(10, 0, 0)));
                XThreeRight.DbEntity.AddToCurrentDocument();
                //From the right and left sides we make a single contour for hatching
                DbPolyline XThreeR = new DbPolyline();
                XThreeR.DbEntity.Color = Color.Green;
                XThreeR.Polyline = XThreeRight.Polyline.Clone() as Polyline3d; // for NC 8.5
                //XThreeR.Polyline = XThreeRight.Polyline.GetCopy() as Polyline3d; //FOR NC 5.1
                XThreeR.DbEntity.AddToCurrentDocument();
                List hatchPoints = new List();
                hatchPoints.AddRange(leftPatrOfThreePoints);
                hatchPoints.AddRange(XThreeR.Polyline.Points.Reverse().ToList());
                Polyline3d hatchContur = new Polyline3d(hatchPoints);
                //We will create on the basis of a contour a hatch (geometry) with continuous filling 
                Hatch hatch = new Hatch(hatchContur, 0, 10, true);
                hatch.PattType = PatternType.PreDefined;
                hatch.PatternName = "SOLID";
                //Based on the geometry of the hatch, we create the document object, set its color properties - green
                DbGeometry dbhatch = new DbGeometry();
                dbhatch.Geometry = new EntityGeometry(hatch);
                dbhatch.DbEntity.Color = Color.Green;
                dbhatch.DbEntity.AddToCurrentDocument();
                // if you want you can try to draw balls with circles use
                // DrawThreeBalls(_pntBase);
                //Similarly, make a Christmas tree toy (octagon)
                //red
                _bufPnt = _pntBase.Subtract(new Vector3d(30, 95, 0));
                DbPolyline dbOctoRed = DrawThreeOctogonPl(_bufPnt);//implicit
                dbOctoRed.DbEntity.AddToCurrentDocument();
                Hatch hatchCirkRed = new Hatch(dbOctoRed.Polyline, 0, 1, false);
                hatchCirkRed.PattType = PatternType.PreDefined;
                hatchCirkRed.PatternName = "SOLID";
                DbGeometry dbhatchCirkRed = new DbGeometry();
                dbhatchCirkRed.Geometry = new EntityGeometry(hatchCirkRed);
                dbhatchCirkRed.DbEntity.Color = Color.Red;
                dbhatchCirkRed.DbEntity.AddToCurrentDocument();
                //green
                _bufPnt = _pntBase.Subtract(new Vector3d(-40, 200, 0));
                DbPolyline dbOctoGreen = DrawThreeOctogonPl(_bufPnt);//implicit
                dbOctoGreen.DbEntity.AddToCurrentDocument();
                Hatch hatchCirkGreen = new Hatch(dbOctoGreen.Polyline, 0, 1, false);
                hatchCirkGreen.PattType = PatternType.PreDefined;
                hatchCirkGreen.PatternName = "SOLID";
                DbGeometry dbhatchCirkGreen = new DbGeometry();
                dbhatchCirkGreen.Geometry = new EntityGeometry(hatchCirkGreen);
                dbhatchCirkGreen.DbEntity.Color = Color.LightSeaGreen;
                dbhatchCirkGreen.DbEntity.AddToCurrentDocument();
                //blue
                _bufPnt = _pntBase.Subtract(new Vector3d(-12, 350, 0));
                DbPolyline dbOctoBlue = DrawThreeOctogonPl(_bufPnt);//implicit
                dbOctoBlue.DbEntity.AddToCurrentDocument();
                Hatch hatchCirkBlue = new Hatch(dbOctoBlue.Polyline, 0, 1, false);
                hatchCirkBlue.PattType = PatternType.PreDefined;
                hatchCirkBlue.PatternName = "SOLID";
                DbGeometry dbhatchCirkBlue = new DbGeometry();
                dbhatchCirkBlue.Geometry = new EntityGeometry(hatchCirkBlue);
                dbhatchCirkBlue.DbEntity.Color = Color.Blue;
                dbhatchCirkBlue.DbEntity.AddToCurrentDocument();
                //display the text with congratulations
                MessageBox.Show("I Wish You A Merry Christmas And Happy New Year!");
            }
        }
        public Polyline3d DrawThreeOctogonPl(Point3d _pntB)
        {
            //Create points for an octagon
            List octoPoints = new List()
                {
                    new Point3d(_pntB.X, _pntB.Y, 0),
                    new Point3d(_pntB.X-15, _pntB.Y, 0),
                    new Point3d(_pntB.X-25, _pntB.Y-11.3, 0),
                    new Point3d(_pntB.X-25, _pntB.Y-26.3, 0),
                    new Point3d(_pntB.X-15, _pntB.Y-37.6, 0),
                    new Point3d(_pntB.X, _pntB.Y-37.6, 0),
                    new Point3d(_pntB.X+9.7, _pntB.Y-26.3, 0),
                    new Point3d(_pntB.X+9.7, _pntB.Y-11.3, 0),
                    new Point3d(_pntB.X, _pntB.Y, 0)
                };
            return new Polyline3d(octoPoints);
        }
    }
}


Part III: writing code on VB


Despite the fact that the process of creating a project in Visual Studio 2015 for VB.NET is almost completely identical to creating a project for C #, given that people who do not have the necessary skills can read the article, we’ll analyze this point in more detail.

First, create a new project, select the VB.NET class library and select the .NET Framework 3.5 (for NC 8.X version 4.0)



Then, right-click on the “links” button on the right and add links to the libraries that you installed with the SDK for any from versions of NanoCAD.

For this project, only mapimgd is enough for us (for NC 8.5 mapibasetypes will also be needed).
You will also need to load the standard System.Windows.Forms and System.Drawing.



Do not forget to uncheck the “copy locally” property



Then we configure the project by clicking on it with PCM and selecting the “properties” button.
And for debugging convenience, we will configure the launch of Nanocad by pressing the F5 key



(each time you make changes to the code, you will need to restart the Nanocad completely)

To load your library, enter the Netload command in the NanoCAD console and select the compiled dll (usually it lies in the project folder, for example, C: \ Users \ b \ Dev \ habr \ XMTree \ XMTree \ bin \ Debug)

In order not to do this every time, go to the address C: \ ProgramData \ Nanosoft \ nanoCAD 5.1 \ DataRW (it may differ for you) and find or create a file load.config with the following contents Ania:


After that, the libraries will be loaded automatically when the program starts.

As I already said, I don’t know VB.NET at all, but as it turned out, if you know C # a bit and let the code converter from C # to VB do all the rough work (for example, this one ), then there’s no special knowledge for our task required, it remains only to correct a little.

I will place the full command code under the spoiler, and then we will analyze it in parts.

Full code for NC 5.1 on VB.NET
Imports System.Collections.Generic
Imports Multicad.Runtime
Imports Multicad.DatabaseServices
Imports Multicad.Geometry
Imports Multicad.DatabaseServices.StandardObjects
Imports System.Drawing
Imports System.Windows.Forms
Namespace XmasThree
    Class XmasThree
        
        Public Sub DrawXThree()
            Dim _pntBase As Point3d
            Dim _bufPnt As Point3d
            Dim jig As New InputJig()
            'prompts for installation point entry
            Dim res As InputResult = jig.GetPoint("Select first point:")
            If res.Result = InputResult.ResultCode.Normal Then
                'The base point is taken from the entry point (click with mouse)
                _pntBase = res.Point
                'Draw the outline of the left half of the Christmas tree
                'Create base points for the polyline
                Dim leftPatrOfThreePoints As New List(Of Point3d)() From {
                    New Point3d(_pntBase.X, _pntBase.Y, 0),
                    New Point3d(_pntBase.X - 125, _pntBase.Y - 154, 0),
                    New Point3d(_pntBase.X - 31, _pntBase.Y - 137, 0),
                    New Point3d(_pntBase.X - 181, _pntBase.Y - 287, 0),
                    New Point3d(_pntBase.X - 31, _pntBase.Y - 253, 0),
                    New Point3d(_pntBase.X - 242, _pntBase.Y - 400, 0),
                    New Point3d(_pntBase.X - 37, _pntBase.Y - 400, 0),
                    New Point3d(_pntBase.X - 37, _pntBase.Y - 454, 0),
                    New Point3d(_pntBase.X, _pntBase.Y - 454, 0)
                }
                'Create a polyline (geometry)
                Dim leftPatrOfThree As New Polyline3d(leftPatrOfThreePoints)
                'Create a polyline object and place it on the drawing
                Dim XThreeLeft As New DbPolyline()
                XThreeLeft.Polyline = New Polyline3d(leftPatrOfThree)
                XThreeLeft.Polyline.SetClosed(False)
                XThreeLeft.DbEntity.Color = Color.Green
                XThreeLeft.DbEntity.AddToCurrentDocument()
                Dim XThreeRight As New DbPolyline()
                XThreeRight.DbEntity.Color = Color.Green
                XThreeRight.Polyline = DirectCast(XThreeLeft.Polyline.Mirror(New Plane3d(_pntBase, New Vector3d(10, 0, 0))), Polyline3d)
                XThreeRight.DbEntity.AddToCurrentDocument()
                'From the right and left sides we make a single contour for hatching
                Dim XThreeR As New DbPolyline()
                XThreeR.DbEntity.Color = Color.Green
                XThreeR.Polyline = TryCast(XThreeRight.Polyline.GetCopy(), Polyline3d)
                XThreeR.DbEntity.AddToCurrentDocument()
                Dim hatchPoints As New List(Of Point3d)()
                hatchPoints.AddRange(leftPatrOfThreePoints)
                hatchPoints.AddRange(XThreeR.Polyline.Points.Reverse().ToList())
                Dim hatchContur As New Polyline3d(hatchPoints)
                'We will create on the basis of a contour a hatch (geometry) with continuous filling 
                Dim hatch As New Hatch(hatchContur, 0, 10, True)
                hatch.PattType = PatternType.PreDefined
                hatch.PatternName = "SOLID"
                'Based on the geometry of the hatch, we create the document object, set its color properties - green
                Dim dbhatch As New DbGeometry()
                dbhatch.Geometry = New EntityGeometry(hatch)
                dbhatch.DbEntity.Color = Color.Green
                dbhatch.DbEntity.AddToCurrentDocument()
                'Similarly, make a Christmas tree toy (octagon)
                'red
                _bufPnt = _pntBase.Subtract(New Vector3d(30, 95, 0))
                Dim dbOctoRed As DbPolyline = DrawThreeOctogonPl(_bufPnt)
                dbOctoRed.DbEntity.AddToCurrentDocument()
                Dim hatchCirkRed As New Hatch(dbOctoRed.Polyline, 0, 1, False)
                hatchCirkRed.PattType = PatternType.PreDefined
                hatchCirkRed.PatternName = "SOLID"
                Dim dbhatchCirkRed As New DbGeometry()
                dbhatchCirkRed.Geometry = New EntityGeometry(hatchCirkRed)
                dbhatchCirkRed.DbEntity.Color = Color.Red
                dbhatchCirkRed.DbEntity.AddToCurrentDocument()
                'green
                _bufPnt = _pntBase.Subtract(New Vector3d(-40, 200, 0))
                Dim dbOctoGreen As DbPolyline = DrawThreeOctogonPl(_bufPnt)
                dbOctoGreen.DbEntity.AddToCurrentDocument()
                Dim hatchCirkGreen As New Hatch(dbOctoGreen.Polyline, 0, 1, False)
                hatchCirkGreen.PattType = PatternType.PreDefined
                hatchCirkGreen.PatternName = "SOLID"
                Dim dbhatchCirkGreen As New DbGeometry()
                dbhatchCirkGreen.Geometry = New EntityGeometry(hatchCirkGreen)
                dbhatchCirkGreen.DbEntity.Color = Color.LightSeaGreen
                dbhatchCirkGreen.DbEntity.AddToCurrentDocument()
                'blue
                _bufPnt = _pntBase.Subtract(New Vector3d(-12, 350, 0))
                Dim dbOctoBlue As DbPolyline = DrawThreeOctogonPl(_bufPnt)
                dbOctoBlue.DbEntity.AddToCurrentDocument()
                Dim hatchCirkBlue As New Hatch(dbOctoBlue.Polyline, 0, 1, False)
                hatchCirkBlue.PattType = PatternType.PreDefined
                hatchCirkBlue.PatternName = "SOLID"
                Dim dbhatchCirkBlue As New DbGeometry()
                dbhatchCirkBlue.Geometry = New EntityGeometry(hatchCirkBlue)
                dbhatchCirkBlue.DbEntity.Color = Color.Blue
                dbhatchCirkBlue.DbEntity.AddToCurrentDocument()
                MessageBox.Show("I Wish You A Merry Christmas And Happy New Year!!!")
            End If
        End Sub
        Public Function DrawThreeOctogonPl(_pntB As Point3d) As Polyline3d
            'Create points for an octagon
            Dim octoPoints As New List(Of Point3d)() From {
                    New Point3d(_pntB.X, _pntB.Y, 0),
                    New Point3d(_pntB.X - 15, _pntB.Y, 0),
                    New Point3d(_pntB.X - 25, _pntB.Y - 11.3, 0),
                    New Point3d(_pntB.X - 25, _pntB.Y - 26.3, 0),
                    New Point3d(_pntB.X - 15, _pntB.Y - 37.6, 0),
                    New Point3d(_pntB.X, _pntB.Y - 37.6, 0),
                    New Point3d(_pntB.X + 9.7, _pntB.Y - 26.3, 0),
                    New Point3d(_pntB.X + 9.7, _pntB.Y - 11.3, 0),
                    New Point3d(_pntB.X, _pntB.Y, 0)
        }
            Return New Polyline3d(octoPoints)
        End Function
    End Class
End Namespace

Despite the fact that the code is simple, just in case, we will analyze it in detail and in parts, because for VB we have not done this before.

Imports System.Collections.Generic
Imports Multicad.Runtime
Imports Multicad.DatabaseServices
Imports Multicad.Geometry
Imports Multicad.DatabaseServices.StandardObjects
Imports System.Drawing
Imports System.Windows.Forms

Import namespaces of the MultiCAD.NET API library for drawing, as well as Windows libraries for displaying a window and assigning colors to hatching.

Namespace XmasThree
    Class XmasThree

Defining a namespace and class name


        Public Sub DrawXThreeLeft()

We create a team that will then be entered into the command line of Nanocad and actually draw our tree.
- the name of the team, as we will call it from Nanocad, you can specify any, but better in short, I'm not sure about the purpose of the other flags.
Public Sub DrawXThreeLeft () - the name of the function (method) for the command is already the internal logic invisible to the CAD user.

Dim _pntBase As Point3d
Dim _bufPnt As Point3d

We create class fields (variables) in order to store the coordinates of the insertion point and the coordinates of the insertion buffer point for Christmas tree decorations.

Dim jig As New InputJig()
Dim res As InputResult = jig.GetPoint("Select first point:")

We create a new object for input into the console and give the user an invitation to click on the screen to determine the insertion point.

If res.Result = InputResult.ResultCode.Normal Then
_pntBase = res.Point

If the input is successful, then the Christmas tree is drawn further; if not, nothing is done.

                Dim leftPatrOfThreePoints As New List(Of Point3d)() From {
                    New Point3d(_pntBase.X, _pntBase.Y, 0),
                    New Point3d(_pntBase.X - 125, _pntBase.Y - 154, 0),
                    New Point3d(_pntBase.X - 31, _pntBase.Y - 137, 0),
                    New Point3d(_pntBase.X - 181, _pntBase.Y - 287, 0),
                    New Point3d(_pntBase.X - 31, _pntBase.Y - 253, 0),
                    New Point3d(_pntBase.X - 242, _pntBase.Y - 400, 0),
                    New Point3d(_pntBase.X - 37, _pntBase.Y - 400, 0),
                    New Point3d(_pntBase.X - 37, _pntBase.Y - 454, 0),
                    New Point3d(_pntBase.X, _pntBase.Y - 454, 0)
                }

Create a list with points that define the vertices of the polyline (left half of the tree)

                'Create a polyline (geometry)
                Dim leftPatrOfThree As New Polyline3d(leftPatrOfThreePoints)
                'Create a polyline object and place it on the drawing
                Dim XThreeLeft As New DbPolyline()
                XThreeLeft.Polyline = New Polyline3d(leftPatrOfThree)
                XThreeLeft.Polyline.SetClosed(False)
                XThreeLeft.DbEntity.Color = Color.Green
                XThreeLeft.DbEntity.AddToCurrentDocument()

First, create the geometry (not visible on the screen) for the left half of the tree, and then create a document object, which, as a result, with the XThreeLeft.DbEntity.AddToCurrentDocument () command we will place in the drawing model space.

                Dim XThreeRight As New DbPolyline()
                XThreeRight.DbEntity.Color = Color.Green
                XThreeRight.Polyline = DirectCast(XThreeLeft.Polyline.Mirror(New Plane3d(_pntBase, New Vector3d(10, 0, 0))), Polyline3d)
                XThreeRight.DbEntity.AddToCurrentDocument()

In order to make the right half of the tree, just mirror the left (analogue of the mirror command in NanoCAD itself). To do this, call the Mirror method at the polyline with the left half of the tree and do not forget to cast the type to Polyline3d, using the DirectCast command.

                Dim XThreeRight As New DbPolyline()
                XThreeRight.DbEntity.Color = Color.Green
                XThreeRight.Polyline = DirectCast(XThreeLeft.Polyline.Mirror(New Plane3d(_pntBase, New Vector3d(10, 0, 0))), Polyline3d)
                XThreeRight.DbEntity.AddToCurrentDocument()

Oddly enough, I did not find hatch references directly in the help for MultiCAD.NET API in the SDK for NC 5.1, although they are in the documentation for the regular .NET API, but nevertheless, the hatch seems to be implemented in the MultiCAD.NET API so the code below at least works fine for me.

                Dim XThreeR As New DbPolyline()
                XThreeR.DbEntity.Color = Color.Green
                XThreeR.Polyline = TryCast(XThreeRight.Polyline.GetCopy(), Polyline3d)
                XThreeR.DbEntity.AddToCurrentDocument()
                Dim hatchPoints As New List(Of Point3d)()
                hatchPoints.AddRange(leftPatrOfThreePoints)
                hatchPoints.AddRange(XThreeR.Polyline.Points.Reverse().ToList())
                Dim hatchContur As New Polyline3d(hatchPoints)

First, combine the points of the left and right half of the tree, and so that the line is closed in the correct order, the array of vertices for the right half must be “turned over” so that the vertices go in the reverse order.

Then, in the usual way, using the list of points, create the geometry of the poly line.
Here the code is a little redundant, you can rewrite it yourself more accurately

                'We will create on the basis of a contour a hatch (geometry) with continuous filling 
                Dim hatch As New Hatch(hatchContur, 0, 10, True)
                hatch.PattType = PatternType.PreDefined
                hatch.PatternName = "SOLID"

Create the geometry for hatching using our full spruce outline. As the type of hatching, choose a solid fill (the names of the hatchings can be seen in Nanocad itself by selecting the "hatching" command).

                Dim dbhatch As New DbGeometry()
                dbhatch.Geometry = New EntityGeometry(hatch)
                dbhatch.DbEntity.Color = Color.Green
                dbhatch.DbEntity.AddToCurrentDocument()

Now create a drawing object, which we will place in the model space, after setting it to green.

Hang our Christmas tree decorations. Initially, it was supposed to shade the balls, but the advice on hatching the circle from the developer forum works for me only for the C # version of the code and only in NC 5.1, so we will hatch the 8-gons.

                'Similarly, make a Christmas tree toy (octagon)
                'red
                _bufPnt = _pntBase.Subtract(New Vector3d(30, 95, 0))
                Dim dbOctoRed As DbPolyline = DrawThreeOctogonPl(_bufPnt)
                dbOctoRed.DbEntity.AddToCurrentDocument()
                Dim hatchCirkRed As New Hatch(dbOctoRed.Polyline, 0, 1, False)
                hatchCirkRed.PattType = PatternType.PreDefined
                hatchCirkRed.PatternName = "SOLID"
                Dim dbhatchCirkRed As New DbGeometry()
                dbhatchCirkRed.Geometry = New EntityGeometry(hatchCirkRed)
                dbhatchCirkRed.DbEntity.Color = Color.Red
                dbhatchCirkRed.DbEntity.AddToCurrentDocument()

The whole process is identical to what we did earlier, the only difference is that we made the creation of a polyline for the octagon a bit in the separate method DrawThreeOctogonPl to slightly reduce the amount of code .
There will be three such “balls” (red, green, blue), I think it’s not worthwhile to separate them separately.

The last thing left is to display a congratulatory window.

                MessageBox.Show("I Wish You a Merry Christmas and Happy New Year!!!")
            End If
        End Sub

As a result, we get the following picture.
For NC 5.1



For NC 8.1




Part IV: With the Coming!


Well, maybe someone will say that we have now made useless and useless "nonsense" to anyone ...

nonsense

And that this is again another article for beginners, which has no place on Habré.

But, I remember that at school when they tried to teach us all about programming, we started with the simplest tasks of drawing, something with the help of a Kangaroo, and then they gave the basics of Basic (although at that time I already liked the good old Pascal more) . Yes, and it’s a sin to still hide variations on the Basic theme are one of the available ways to teach people how to program, take at least the same SmallBasic.

Therefore, considering that NC 5.1 is absolutely free for any purpose, you can get a license for educational versions of NanoCAD institutions, then I think high school and educational institutions of secondary vocational education could well turn their eyes to Nanocad and explain with simple examples to children how to program CAD.

Although in fairness it should be noted that NC is not the only CAD system that is easy to use in educational institutions and which has open APIs, you can certainly turn to the same Compass.

In any case, I wish everyone happiness and success in the coming 2018!
And I hope that in 2018 developers will give us a normal update for the free version of NanoCAD, with new APIs and for the new NET Framework.

PS Important! In order not to fence a separate article, just in case, I will warn people who, just like me, are picking the API for Nanocad 8.X.

Personally, after installing the latest Windows 10 update in a 64-bit version of NanoCAD, polylines began to fail (the height is incorrectly set). And all the previously written C # commands go "down the drain."

In the 32-bit version, everything works fine, I have not yet found a solution to the problem, so be careful before updating Windows 10 if it is critical for you.

Also popular now: