Register
 
DesignCAD 2019 and DesignCAD 3D Max 2019 now available for sale!
https://www.turbocad.com/designcad/ OR
https://www.imsidesign.com/products/designcad

How to use Python with DesignCAD
Read 2409 times
* October 14, 2016, 11:21:44 AM
Dear Members,

how can I use Python with DesignCad? Has anybody experience writing python scripts to operate by remote control DesignCAD?

I'm trying it with comtypes but I only get rudimentary access to DC. Are there any small examples? I didn't find anything in Forum.

Many thanks for your Answers.

Greetings

Zarathustra

Logged


October 14, 2016, 01:35:08 PM
#1
Hi Zarathustra. Have you come down from the mountain yet? :)

Sorry, I don't have any experience with Python. Everyone seems to have their own pet scripting language, but Python isn't one that (as far as I know) anyone has yet tried to use with DesignCAD.

Logged
25 years with DesignCAD


* October 09, 2017, 09:06:29 AM
#2
Hello Members I'm down from the Mountain  ;)

Here is my first attempt with COM and Python. It think it should work. I tested with DC23.

import sys
import wx
from comtypes.client import GetActiveObject as gao
from ctypes import c_double, byref

def Mitteilung(Titel, Nachricht):
    app = wx.App()
    frame = wx.Frame(None)
    frame.Center()
    frame.Close()
    app.MainLoop()
    wx.MessageDialog(None, Nachricht, Titel, wx.OK | wx.ICON_INFORMATION).ShowModal()


def main():
    try:
        DcApp = gao("DesignCAD.Application.23")
        Mitteilung("Makro Einspurmodell","Einspurmodell gestartet!")
    except:
        Mitteilung("Kein DesignCAD", "Bitte zuerst DesignCAD starten, Abbruch!")
        sys.exit(0)

    DcApp.Visible = True
    DcApp.BringToTop()

    DcDoc = gao("DesignCAD.DCD-Document.23")

    DcPlane = DcDoc.Plane
    DcCurve = DcDoc.Curve
    DcPts = DcDoc.CmdPoints

    x = c_double()
    y = c_double()
    z = c_double()
    DcPts.GetUserPoint(byref(x), byref(y), byref(z))

    DcPts.SetCommandPoint(0. + x.value, 0. + y.value, 0. + z.value)
    DcPts.SetCommandPoint(10. + x.value, 0. + y.value, 0. + z.value)
    DcPts.SetCommandPoint(5. + x.value, 8.6667 + y.value, 0. + z.value)
    DcPlane.DrawType = 0
    DcPlane.Draw


if __name__ == '__main__':
    main()

There is only a Messagebox from wxPython, therefore "import wx". But in future, i try to use wxPython for  GUI-Programming because of wxFormbuilder for design GUI-Layout.

It was hard for myself to find out how to get values from GetUserPoint. It doesent work for me with win32com.client etc.
You should use oleview.exe to get the Names of the registred Class-Names.

Next Tests are with numpy array and SetCommandPoints

I hope it's not to hard for me...

Greetings from Düsseldorf, Germany

Logged


* September 15, 2018, 02:30:50 AM
#3
Dear Members,

now I'm able to use "SetCommandPonts" to create a Curve.

I'm testet with DC Version 24. I bought "a new one"  ;)

I changed back to win32com instead of comtypes, because "SetCommandPoints" works with VARIANTS, an I was able to get "GetUserPoint" to work by VARIANTS.

I' don't know why, but GetUserPoint needs (z, y, x) instead of (x, y, z) because the first Variable is in 2D-Mode set to zero.

Now, here ist my source code:

import sys
import wx
import numpy as np
from win32com.client import Dispatch as DP
from win32com.client import VARIANT
import pythoncom

def Mitteilung(Nachricht, Titel):
    app = wx.App()
    frame = wx.Frame(None)
    frame.Center()
    frame.Close()
    app.MainLoop()
    wx.MessageDialog(None, Nachricht, Titel, wx.OK | wx.ICON_INFORMATION).ShowModal()

def main():
    try:
        DcApp = DP("DesignCAD.Application")
        Mitteilung("Sinus gestartet", "Makro einfacher Sinus")
    except:
        Mitteilung("Kein DesignCAD", "Bitte zuerst DesignCAD starten, Abbruch!")
        sys.exit(0)

    DcApp.BringToTop()
    DcApp.Visible = 1
    DcDoc = DcApp.ActiveDocument
    DcPts = DcDoc.CmdPoints
    DcCurve = DcDoc.Curve

    x_start = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)
    y_start = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)
    z_start = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)

    DcPts.GetUserPoint(z_start, y_start, x_start)

    x_start = x_start.value
    y_start = y_start.value
    z_start = z_start.value

    x_werte = np.linspace(0.,2*np.pi,300,True)
    y_werte = np.sin(x_werte)

    Punkte = np.zeros(3*np.alen(x_werte))

    for i in range(np.alen(x_werte)):
        j = 3 * i
        Punkte[j] = x_werte + x_start
        j = j + 1
        Punkte[j] = y_werte + y_start
        j = j + 1
        Punkte[j] = 0.0 + z_start

    vPkte = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_ARRAY | pythoncom.VT_R8, Punkte)

    Anz = np.alen(x_werte)
    vAnz = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, Anz)


    DcCurve.DrawType = 0
    DcPts.SetCommandPoints(vAnz, vPkte)
    DcCurve.Draw

if __name__ == '__main__':
    main()

Best regards

Volker
 

Logged


* July 21, 2019, 02:48:58 AM
#4
Hello Members,

i think i tried a more easy way to connect to DesignCAD via Python. Python 3.7.3 64 bit, DesignCAD 24 (24.1).

At first, build a Wrapper from Typelibrary. See below:

import win32com.client
import sys
from win32com.client import makepy

OutputFile = r"C:\path\to\your\pythonproject\DC24Automation.py"

DCTypbibliothek = r"C:\path\to\DesignCAD\Dcad24.tlb"

sys.argv = ["makepy", "-o", OutputFile, DCTypbibliothek]

makepy.main()

after that, import the wrapper in your project like the following example:

import win32com.client
import DC24Automation as DC24A #This is the import of the automation-wrapper
import numpy as np

DcApp: DC24A.IDcadApp = win32com.client.GetActiveObject(DC24A.Application.CLSID)
DcApp.BringToTop()

DcDoc: DC24A.IDcadDoc = win32com.client.GetActiveObject(DC24A.Document.CLSID)

DcPts = DcDoc.CmdPoints()
DcLine = DcDoc.Line()
DcPlane = DcDoc.Plane()
DcCurve = DcDoc.Curve()

MsPkt = DcPts.GetUserPoint() #Catch a point with mouse
x_start = MsPkt[1]
y_start = MsPkt[2]
z_start = MsPkt[3]

#print("Ausgabe x=",MsPkt[1],"y=",MsPkt[2],"z=",MsPkt[3])

x_werte = np.linspace(0.,2*np.pi,30,True)
y_werte = 1.5*np.sin(x_werte)

Anz = np.alen(x_werte)
Punkte = np.zeros(3*Anz)

for i in range(np.alen(x_werte)):      #SetCommandPoints needs the number of points (Anz) and a Array (Vector) like [x0,y0,z0, x1,y1,z1, x2,y2,z2, ... ]
    j = 3 * i
    Punkte[j] = x_werte + x_start
    j = j + 1
    Punkte[j] = y_werte + y_start
    j = j + 1
    Punkte[j] = 0.0 + z_start

DcCurve.DrawType = 0
DcPts.SetCommandPoints(Anz, Punkte)
DcCurve.Draw();

Best regards,

Zarathustra

Logged