Jump to content

Python with CMS IntelliCAD 14.1


Recommended Posts

Posted

Super cool to see the progress IntelliCAD has made with their C++ API. I’ve been working to port pyrx, still not released, there’s a couple small issues I need to work out

 

import traceback
from pyrx import Ap, Db, Ge

# -----------------------------
# Simple spline-based vector font
# -----------------------------
FONT = {
    "H": [[(0, 0), (0, 10)], [(5, 0), (5, 10)], [(0, 5), (5, 5)]],
    "A": [[(0, 0), (2.5, 10), (5, 0)], [(1.2, 5), (3.8, 5)]],
    "P": [[(0, 0), (0, 10)], [(0, 10), (5, 9), (5, 6), (0, 5)]],
    "Y": [[(0, 10), (2.5, 5)], [(5, 10), (2.5, 5)], [(2.5, 5), (2.5, 0)]],
    "N": [[(0, 0), (0, 10)], [(0, 10), (5, 0)], [(5, 0), (5, 10)]],
    "E": [[(5, 0), (0, 0), (0, 10), (5, 10)], [(0, 5), (4, 5)]],
    "W": [[(0, 10), (1.2, 0), (2.5, 6), (3.8, 0), (5, 10)]],
    "R": [[(0, 0), (0, 10)], [(0, 10), (5, 9), (5, 6), (0, 5)], [(0, 5), (5, 0)]],
    " ": [],
}

# -----------------------------
# Create a spline from points
# -----------------------------
def add_spline(ms, pts, base, scale):
    arr = []
    for p in pts:
        arr.append(Ge.Point3d(base.x + p[0] * scale, base.y + p[1] * scale, 0.0))

    spline = Db.Spline(arr, 3, 0.0)
    ms.appendAcDbEntity(spline)

# -----------------------------
# Write text as splines
# -----------------------------
def write_happy_new_year(start=Ge.Point3d(0, 0, 0), scale=5.0, spacing=8.0):
    db = Db.curDb()
    ms = Db.BlockTableRecord(db.modelSpaceId(), Db.OpenMode.kForWrite)
    cursor = Ge.Point3d(start.x, start.y, 0)
    text = "HAPPY NEW YEAR"

    for ch in text:
        strokes = FONT.get(ch.upper(), [])
        for stroke in strokes:
            add_spline(ms, stroke, cursor, scale)
        cursor.x += spacing * scale

# -----------------------------
# Entry point
# -----------------------------
def PyRxCmd_HAPPYNEWYEAR():
    try:
        write_happy_new_year(start=Ge.Point3d(0, 0, 0), scale=2.5, spacing=7.0)
    except Exception as err:
        traceback.print_exception(err)

 

cms.thumb.png.4fef6c432d77726f443a7f12b17ad59b.png

  • Like 1
Posted

Here’s a test extracting data from multiple drawings

 

import traceback
import pandas as pd
import os

from pyrx import Ap, Db, Ed, Ge

def proccessDrawing(db: Db.Database, data: dict):
    blk_dict = db.getBlocks()
    fname = os.path.basename(db.getFilename())
    data[fname] = []
    for name, id in blk_dict.items():
        if name != "RMNUM":
            continue
        btr = Db.BlockTableRecord(id)
        for refid in btr.getBlockReferenceIds():
            blkref = Db.BlockReference(refid)
            for attid in blkref.attributeIds():
                attref = Db.AttributeReference(attid)
                data[fname].append(attref.textString())


def openSideDatabase(dwg_path: str, data: dict):
    sdb = Db.Database(False, True)
    sdb.readDwgFile(dwg_path)
    sdb.closeInput(True)
    proccessDrawing(sdb, data)


@Ap.Command()
def doit():
    try:
        data = {}
        dwgs = Ap.Application.listFilesInPath("E:\\FloorPlans", ".dwg")
        for dwg in dwgs:
            openSideDatabase(dwg, data)

        df = pd.DataFrame(data)
        print(df)
    except Exception as err:
        traceback.print_exception(err)

 

output :

Success module _DOIT is loaded: 
Command: doit
   1st floor.dwg 2nd floor.dwg 3rd floor.dwg
0           1049          2049          3049
1           1045          2045          3045
2           1032          2032          3032
3           1048          2048          3048
4           1046          2046          3046
..           ...           ...           ...
94          1122          2122          3122
95          1106          2106          3106
96          1104          2104          3104
97          1093          2093          3093
98          1042          2042          3042
[99 rows x 3 columns]

 

  • Like 1
Posted

Some really cool stuff here

  • Like 1
  • Agree 1
Posted (edited)

Thanks!

 

I’m always rooting for the underdog, I guess to promote competition in the space. I’ve been goofing around with the clones since the early days.

I think before version 9. Every year, I download the trial and try out the IARX SDK. The trial is 14 days, this is the first time I was able to get past day 1 and run some real tests.

 

Here’s my little mini review of the API.

 

- I was able to compile my custom object https://github.com/CEXT-Dan/ArxTin

While I didn’t test all the protocols, the important ones work great!

dwgOutFields, dwgInFields, subWorldDraw, subTransformBy etc.

 

The most impressive thing besides it working, is the subWorldDraw performance. In this sample, I’m pushing 10s of thousands of edges to the graphics interface and transformby is as fast a moving a line. A $250 cad is out performing a $1200 cad by 10x

 

tin.png.67f3557feceb711a87d7b7791acbb367.png

Edited by Danielm103
Posted

But there’s stuff missing, from the automated tests in PyRx

 

"collecting ... collected 529 items / 210 deselected / 3 skipped / 319 selected"

 

There are 210 tests that I had to disable to get a clean run. I’m still working through them, I disabled the whole class on some tests

all the test_Ax**** tests are not accurate, I've not worked through them yet

 

Filename                    NextLine
--------                    --------
test_Ax3DFace.py            class TestAx3dFace:
test_Ax3DPolyline.py        class TestAx3DPolyline:
test_Ax3DSolid.py           class TestAx3DSolid:
test_AxAcadSortentsTable.py class TestAcadSortentsTable:
test_AxAcadSortentsTable.py
test_AxApplication.py       class TestAxApplication:
test_AxArc.py               class TestAxArc:
test_AxAttribute.py         class TestAxAttribute:
test_AxBlock.py             class TestAxBlock:
test_AxBlockReference.py    class TestAxBlockReference:
test_AxBlockReference.py    class TestAxDynBlockReference:
test_AxCircle.py            class TestAxCircle:
test_AxDatabase.py          class TestAxDatabase:
test_AxDocument.py          class TestAxDocument:
test_AxEllipse.py           class TestAxEllipse:
test_AxEntity.py            class TestAxEntity:
test_AxGroup.py             fail
test_AxLayout.py            class TestAxLayout:
test_AxLWPolyline.py        def test_getcoordinate(self):
test_AxLWPolyline.py       
test_AxMenu.py              class TestAxMenu:
test_AxModelSpace.py        class TestAxModelSpace:
test_AxObject.py            class TestAxObject:
test_AxPoint.py             class TestAxPoint:
test_AxPolygonMesh.py       class TestAxPolygonMesh :
test_AxPolyline.py          class TestAxPolyline:
test_AxPreferences.py       class TestAxPreferences:
test_AxPreferences.py       class TestSelection:
test_AxPreferences.py       class TestDrafting:
test_AxPreferences.py       class TestDisplay:
test_AxPreferences.py       class TestPrefFiles:
test_AxSummaryInfo.py       class TestAxSummaryInfo:
test_AxTable.py             class TestAxTable:
test_AxUtility.py           class TestAxUtility:
test_Brep.py                class TestBrep:
test_AssocPersSubentIdPE.py 
test_AttributeDefinition.py  (mtext attributes)
test_AttributeDefinition.py 
test_Database.py            def test_dbopbject_dxfname(self, db_06457: Db.Database):
test_Database.py            def test_getSummaryInfo(self):
test_Database.py            def test_blocktable(self, db_06457: Db.Database):
test_Database.py            def test_GeoPositionMarker(self, db_geo: Db.Database):
test_Database.py            def test_GeoData(self, db_geo: Db.Database) -> None:
test_Database.py            def test_GeoData_transformFromLonLatAlt(self, db_geo: Db.Database) -> None:
test_Database.py            def test_tdusrtimer(self) -> None:
test_DbObject.py            def test_property_ids2(self):
test_DbObject.py            def test_undo_recording(self):
test_DbObject.py            def test_BinaryData(self):
test_DbObject.py            def test_BinaryXdData(self):
test_entity.py              def test_dbtext(self):
test_entity.py              def test_dbleader(self):
test_entity.py              def test_table_cells1(self, db_06457: Db.Database): //missing iterator 
test_entity.py              def test_table_cells2(self, db_06457: Db.Database): //missing iterator
test_entity.py              def test_table_cellValues1(self, db_06457: Db.Database): //missing iterator
test_entity.py              def test_table_cellValues2(self, db_06457: Db.Database): //missing iterator
test_entity.py              def test_table_cellValues4(self, db_06457: Db.Database): //missing iterator
test_entity.py              def test_table_calcTextExtents(self):
test_entity.py              def test_create_wipout(self):
test_entity.py              def test_create_extruded_surface(self):
test_SortentsTable.py       def test_getinstance(self):
test_XrefGraph.py           def test_XrefGraph(self, db_xrefGraph: Db.Database):
test_Editor.py              def test_evaluateDiesel(self):
test_Curve2d.py             def test_ge2dcurve_length(self):
test_Curve3d.py             def test_Ge_lineseg3d_1(self):
test_Curve3d.py             def test_ge3dcurve_length(self):
test_GsCore.py              def test_gs_getBlockImage(self, db_dynblock: Db.Database):
test_RxObject.py            def test_name(self):
test_SheetSet.py            class TestSheetSet:
test_wx.py                  def test_wx_CallAfter(self):
test_block_reference.py     def test_get_attribute(self, db_06457: Db.Database):
test_prompt.py              def test_select_entity_without_type(self):
test_prompt.py              def test_select_entity_with_single_type(self):
test_prompt.py              def test_select_entity_with_multiple_types(self):
test_reload.py              class Test_Reload:
test_reload.py              class Test_reload_func:

 

Posted

I was able to connect with ITC Directly and report the items I felt are important from an API perspective.

AcRxClass::dxfName()    is null with AcDbObject
AcDbObject::close()     has an access violation if called twice.

 

I think the next release or so of IntelliCAD will be a real competitor in the space.  Assuming pricing is stable, there’s no reason to buy any ‘lite’ version of CAD

 

 

 

 

 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...