subWorldDraw

Hi,
I try to learn BRX SDK custom entity. As example I use sample brxSample.

To sample I have added std::vector to store AcGePoint3d.
Created methods and commands to add points to vector and it works.
I have modified subWorldDraw() and added code to draw all points from vector.~~~~
But don't know how to call subWorldDraw(). So no points are draw, but if I use subMoveGripPointsAt() after it completes it calls subWorldDraw() and points from std::vector are draw.

How can I make to redraw custom entity after adding point to it?

Comments

  • You will need to have your own (custom) entity
    a) to be opened in kForWrite
    b) call assertWriteEnabled() - this ensures that undo data are written, and the display system also takes notice, that your entity had been modified, and in next idle state (or enforced by acedRedraw() and similar), the display system will call the subWorldDraw() on your object instance
    c) then add your extra points to your custom entity
    d) close your entity

    Then an automatic redraw should happen ...
    hope this explains ?

  • Thanks will try after I return home from work.

  • DonatasAzaravičius
    edited October 2018

    Did not worked. Something not right in my code. Grip point of my entity have changed to the point I have added, but entity was not redrawn.

    My method to add points to custom entity

    void MyEntity::addPoint(const AcGePoint3d& point)
    {
        assertWriteEnabled();
        m_points.push_back(point);
        m_point1 = point;
    }
    

    Found many examples to create custom entity, but can't find example to modify custom entity after creation. Or all modifications are about standard (move, rotate, grip and so on) modifications.

    https://youtube.com/watch?v=o_TJgJVDhVU

  • So my question would be : from what code part (in which context) do you call your MyEntity::addPoint() function ?

  • From the video, I see you have a dedicated ADDPOINT command ? That should indeed trigger a redraw of your entity ...
    when modifying the custom entity from within a virtual function callback (grip points handling), then it becomes more complicate.
    So adding points via ADDPOINT should indeed trigger a new worldDraw() operation ...

    If all does not help, please send us your sample project as support request, maybe that sample custom entity is not properly implemented ?

  • DonatasAzaravičius
    edited October 2018

    As base I used sample from BRX SDK brxSample. I am using not full example but only MyEntity code.
    To MyEntity class added

    std::vector<AcGePoint3d> m_points; // variable, 
    void addPoint(const AcGePoint3d&); // and
    Adesk::Boolean drawPoint(AcGiWorldDraw* pWd, const AcGePoint3d& point, AcGePoint3d* points) const; // methods
    

    Changed subWorldDraw method

    Adesk::Boolean MyEntity::subWorldDraw(AcGiWorldDraw* pWd)
    {
        assertReadEnabled();
        AcGePoint3d points[4] = { AcGePoint3d() }; // Place holder variable.
    
        pWd->subEntityTraits().setFillType(kAcGiFillAlways);
        pWd->geometry().polygon(3, &m_point1);
        pWd->subEntityTraits().setFillType(kAcGiFillNever);
        pWd->geometry().circle(m_point1, m_point2, m_point3);
    
        pWd->subEntityTraits().setColor(1);
        for (auto p : m_points)
            drawPoint(pWd, p, points); // draw all added points.
    
        acutPrintf(_T("\n   subWorldDraw")); // To check calls to subWorldDraw method.
        return Adesk::kTrue;
    }
    
    Adesk::Boolean MyEntity::drawPoint(AcGiWorldDraw* pWd, const AcGePoint3d& point, AcGePoint3d* points) const
    {
        double size = 0.2;
        points[0].x = point.x;
        points[0].y = point.y + size;
        points[1].x = point.x;
        points[1].y = point.y - size;
        points[2].x = point.x + size;
        points[2].y = point.y;
        points[3].x = point.x - size;
        points[3].y = point.y;
    
        pWd->geometry().circle(point, size * 0.5, AcGeVector3d(0, 0, 1));
        pWd->geometry().polyline(2, points);
        pWd->geometry().polyline(2, &points[2]);
        return Adesk::kTrue;
    }
    

    No change to dwgOutFields and other methods. I don't want to save points to dwg. I plan to use SQLite database to save all points externally. But it is only plan.

    To add points I created command function.

    void cmdAddPoint()
    {
        ads_point adsPoint;
        int nReturn;
        ads_name name;
        AcDbObjectId id;
        AcDbEntity* pEnt = NULL;
    
        nReturn = acedEntSel(_T("\nSelect entity: "), name, adsPoint);
        if (nReturn != RTNORM)
            return;
        if (acdbGetObjectId(id, name) != Acad::eOk)
            return;
        if (acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead) != Acad::eOk)
            return;
    
        while (true)
        {
            if (RTNORM != acedGetPoint(NULL, _T("\nPoint: "), adsPoint))
                return;
    
            TINSurface::cast(pEnt)->addPoint(asPnt3d(adsPoint));
        }
        pEnt->close();
    }
    
  • You should open with kForWrite ! :-)
    Because you modify your entity ...

    "if (acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead) != Acad::eOk) ...."

    otherwise, the required "assertWriteEnabled()" in your

    void MyEntity::addPoint(const AcGePoint3d& point)
    {
        assertWriteEnabled();
        m_points.push_back(point);
        m_point1 = point;
    }
    

    should trigger an exception ... or at least, a debug assertion :-)

    Undo data generation, and display updates are triggered from "assertWriteEnabled()", and that in turn requires that the object is open in kForWrite mode ...

  • Such a small mistake and so much headache :(
    Thanks.

    How do I mark discussion for Answered. I see two discussions in forum marked as Answered, but I can't find how to do it myself.

This discussion has been closed.