Author Topic: My Overrule Sample  (Read 6038 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
My Overrule Sample
« on: April 10, 2009, 01:09:27 AM »
Seems to work  :-o

.h
Code: [Select]
#pragma once
class DrawableOverrule : public AcGiDrawableOverrule
{
public:
  DrawableOverrule(void);
  virtual ~DrawableOverrule(void);
  virtual Adesk::Boolean worldDraw(AcGiDrawable* pSubject, AcGiWorldDraw * wd);
  virtual Adesk::UInt32 setAttributes (AcGiDrawable* pSubject, AcGiDrawableTraits * traits);
  virtual bool isApplicable(const AcRxObject* pOverruledSubject) const;
};

.cpp
Code: [Select]
#include "StdAfx.h"
#include "DrawableOverrule.h"

DrawableOverrule::DrawableOverrule(void)
{
}

DrawableOverrule::~DrawableOverrule(void)
{
}

Adesk::Boolean DrawableOverrule::worldDraw(AcGiDrawable* pSubject, AcGiWorldDraw * wd )
{
  if(pSubject == NULL) {  return Adesk::kFalse; }
  if(wd == NULL) { return Adesk::kFalse; }

  if(pSubject->isKindOf(AcDbPolyline::desc()))
  {
    AcDbPolyline *pLine = AcDbPolyline::cast(pSubject);

    if(pLine == NULL) { return Adesk::kFalse; }
    if(!__super::worldDraw(pLine,wd)) { return Adesk::kFalse; }

    AcCmEntityColor oldc = wd->subEntityTraits().trueColor();
    AcCmEntityColor color;

    if(color.setColorIndex(1) != eOk) { return Adesk::kFalse; }
    wd->subEntityTraits().setTrueColor(color);
    wd->subEntityTraits().setLineWeight(AcDb::kLnWt000);

    AcDbVoidPtrArray ents;

    if(pLine->getOffsetCurves(2.0,ents) != eOk) { return Adesk::kFalse; }
    if(pLine->getOffsetCurves(-2.0,ents) != eOk) { return Adesk::kFalse; }

    for(int i =  0; i < ents.length() ; i++)
    {
      AcDbEntity *tmp = reinterpret_cast<AcDbEntity*>(ents[i]);
      if(tmp->worldDraw(wd) != eOk)
      {
        // sometimes this fails but I don't know why?? ok no crash;
        // acutPrintf(_T("\nFailed@tmp->worldDraw(wd)"));
      }
      delete tmp;
    }

    wd->subEntityTraits().setTrueColor(oldc);
    return Adesk::kTrue;
  }

  return Adesk::kFalse;
}

Adesk::UInt32 DrawableOverrule::setAttributes( AcGiDrawable* pSubject, AcGiDrawableTraits * traits )
{

  if(!__super::setAttributes(pSubject,traits)) { return Adesk::kFalse; }

  AcDbEntity *pLine = AcDbEntity::cast(pSubject);

  if(pLine == NULL) { return Adesk::kFalse; }

  if(!pLine->isWriteEnabled())
  {
    AcDbObjectId id;
    if(acdbOpenAcDbEntity(pLine,id,AcDb::kForWrite) == eOk)
    {
     AcCmColor color;
     color.setColorIndex(1);
     pLine->setColor(color);
     pLine->setLineWeight(AcDb::kLnWt000);
     pLine->downgradeOpen();
    }
  }
  return Adesk::kTrue;
}

// Note Autodesk should be consistent on using bool, Adesk::Boolean
bool DrawableOverrule::isApplicable( const AcRxObject* pOverruledSubject ) const
{
  if(pOverruledSubject->isKindOf(AcDbPolyline::desc()))
  {
    AcDbPolyline *pLine = AcDbPolyline::cast(pOverruledSubject);

    // conditions we don't like
    if(pLine == NULL)                         { return false; }
    if(pLine->objectId().isNull())            { return false; }
    if(!pLine->objectId().isValid())          { return false; }
    if(!pLine->objectId().isResident())       { return false; }
    if(!pLine->isReadEnabled())               { return false; }
    if(pLine->isErased())                     { return false; }

    // condtions we like
    if(_tcscmp(pLine->layer(), _T("0")) == 0) { return true;  }
  }
  return false;
}


edit bug
« Last Edit: April 10, 2009, 02:06:58 AM by Daniel »

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: My Overrule Sample
« Reply #1 on: April 10, 2009, 01:13:23 AM »
and the command

Code: [Select]
static int setLwDisplay(int flag)
 {
   resbuf rb;
   rb.restype = RTSHORT;
   rb.resval.rint = flag;
   return acedSetVar(_T("LWDISPLAY"),&rb);
 }

 static int getLwDisplay(int flag)
 {
   resbuf rb;
   acedGetVar(_T("LWDISPLAY"),&rb);
   return rb.resval.rint;
 }

 static void enableOverrule(Adesk::Boolean flag)
 {
   setLwDisplay(flag);
   DrawableOverrule::setIsOverruling(flag);
   acedCommand(RTSTR,_T("REGEN"),0);
 }
 
 static void ArxAcGiDrawable_doit(void)
 {
   DrawableOverrule::addOverrule(AcDbPolyline::desc(),drawableOverrule,Adesk::kTrue);
   enableOverrule(Adesk::kTrue);
 }

 static void ArxAcGiDrawable_undoit(void)
 {
   enableOverrule(Adesk::kFalse);
   DrawableOverrule::removeOverrule(AcDbPolyline::desc(),drawableOverrule);
 }


edit, added the solution and Arx
« Last Edit: April 10, 2009, 07:31:43 AM by Daniel »

pkohut

  • Guest
Re: My Overrule Sample
« Reply #2 on: April 10, 2009, 01:18:51 AM »
Is this a derived entity?  What version of AC is the screen shot from?

Send me a PM w/ email addy, I've got something you might like.

Paul

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: My Overrule Sample
« Reply #3 on: April 10, 2009, 01:22:11 AM »
Itís the new feature in Acad 2010, where you can overrule how an entity draws
See this link

pkohut

  • Guest
Re: My Overrule Sample
« Reply #4 on: April 10, 2009, 01:31:55 AM »
Cool I get it now (mostly, have to study code some more), thanks.

Paul

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: My Overrule Sample
« Reply #5 on: April 10, 2009, 02:10:35 AM »
DoH! had a bug.

if you use the ArxAcGiDrawable.arx

the command is doit to load

draw a few polylines

and undoit to unload

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: My Overrule Sample
« Reply #6 on: April 10, 2009, 02:30:05 AM »
hehe before and after 8-)

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: My Overrule Sample
« Reply #7 on: April 10, 2009, 08:53:36 AM »
add a circle at every vertex  :laugh:

Code: [Select]
Adesk::Boolean DrawableOverrule::worldDraw(AcGiDrawable* pSubject, AcGiWorldDraw * wd )
{
  if(pSubject == NULL) {  return Adesk::kFalse; }
  if(wd == NULL) { return Adesk::kFalse; }

  if(pSubject->isKindOf(AcDbPolyline::desc()))
  {
    AcDbPolyline *pLine = AcDbPolyline::cast(pSubject);

    if(pLine == NULL) { return Adesk::kFalse; }
    if(!__super::worldDraw(pLine,wd)) { return Adesk::kFalse; }

    AcCmEntityColor oldc = wd->subEntityTraits().trueColor();
    AcCmEntityColor color;

    if(color.setColorIndex(1) != eOk) { return Adesk::kFalse; }
    wd->subEntityTraits().setTrueColor(color);
    wd->subEntityTraits().setLineWeight(AcDb::kLnWt000);

    AcDbVoidPtrArray ents;

    if(pLine->getOffsetCurves(2.0,ents) != eOk) { return Adesk::kFalse; }
    if(pLine->getOffsetCurves(-2.0,ents) != eOk) { return Adesk::kFalse; }

    for(unsigned int j = 0 ; j < pLine->numVerts() ; j++)
    {
      AcGePoint3d cp;
      if(pLine->getPointAt(j,cp) == eOk)
      {
        AcDbCircle *pCircle = new AcDbCircle(cp, AcGeVector3d(0,0,1), 1.0);
        pCircle->worldDraw(wd);
        delete pCircle;
      }
    }

    for(int i =  0; i < ents.length() ; i++)
    {
      AcDbPolyline *tmp = reinterpret_cast<AcDbPolyline*>(ents[i]);
      tmp->worldDraw(wd);
      delete tmp;
    }

    wd->subEntityTraits().setTrueColor(oldc);
    return Adesk::kTrue;
  }

  return Adesk::kFalse;
}


It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: My Overrule Sample
« Reply #8 on: April 10, 2009, 09:47:32 AM »
last one for now  :lol:

Code: [Select]
Adesk::Boolean DrawableOverrule::worldDraw(AcGiDrawable* pSubject, AcGiWorldDraw * wd )
{
  if(pSubject == NULL) {  return Adesk::kFalse; }
  if(wd == NULL) { return Adesk::kFalse; }

  if(pSubject->isKindOf(AcDbPolyline::desc()))
  {
    AcDbPolyline *pLine = AcDbPolyline::cast(pSubject);

    if(pLine == NULL) { return Adesk::kFalse; }
    if(!__super::worldDraw(pLine,wd)) { return Adesk::kFalse; }

    AcCmEntityColor oldc = wd->subEntityTraits().trueColor();
    AcCmEntityColor color;

    if(color.setColorIndex(1) != eOk) { return Adesk::kFalse; }
    wd->subEntityTraits().setTrueColor(color);
    wd->subEntityTraits().setLineWeight(AcDb::kLnWt000);

    AcDbVoidPtrArray ents1;
    AcDbVoidPtrArray ents2;

    if(pLine->getOffsetCurves(2.0,ents1) != eOk) { return Adesk::kFalse; }
    if(pLine->getOffsetCurves(-2.0,ents2) != eOk) { return Adesk::kFalse; }

    for(int i =  0; i < ents1.length() ; i++)
    {
      AcDbPolyline *tmp = reinterpret_cast<AcDbPolyline*>(ents1[i]);
      for(unsigned int j = 0 ; j < tmp->numVerts() ; j++)
      {
        AcGePoint3d cp;
        tmp->setBulgeAt(j, 0.1);
      }
      tmp->worldDraw(wd);
      delete tmp;
    }

    for(int i =  0; i < ents2.length() ; i++)
    {
      AcDbPolyline *tmp = reinterpret_cast<AcDbPolyline*>(ents2[i]);
      for(unsigned int j = 0 ; j < tmp->numVerts() ; j++)
      {
        AcGePoint3d cp;
        tmp->setBulgeAt(j, -0.1);
      }
      tmp->worldDraw(wd);
      delete tmp;
    }

    wd->subEntityTraits().setTrueColor(oldc);
    return Adesk::kTrue;
  }

  return Adesk::kFalse;
}

Spike Wilbury

  • Guest
Re: My Overrule Sample
« Reply #9 on: April 11, 2009, 12:27:33 PM »
That looks pretty good, to bad I still don't have this version of AutoCAD to play.

ahlzl

  • Guest
Re: My Overrule Sample
« Reply #10 on: April 12, 2009, 12:02:04 AM »
I am Daniel's fans!

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: My Overrule Sample
« Reply #11 on: April 12, 2009, 12:54:50 AM »
I am Daniel's fans!

I understand what you're saying.
I have this thing for Elle Macpherson, but she can't  programme very well at all  ...
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: My Overrule Sample
« Reply #12 on: April 12, 2009, 10:03:11 AM »
I have this thing for Elle Macpherson

Me Too!  :laugh:

Spike Wilbury

  • Guest
Re: My Overrule Sample
« Reply #13 on: April 12, 2009, 11:29:03 AM »
Quote
Elle Macpherson
I can be a fan of her too. :)


BTW, Tony Tanzillo just posted a C# sample about this new feature here:

Quote
autodesk.autocad.customization.dotnet

The link below includes a simple example of using the Overrule Api
in a way that will not bog down AutoCAD performance (mainly during
object dragging).

    http://www.caddzone.com/OverruleSample.zip

See the included code comments for the theory/explanation about
performance issues that will occur when this API is used incorrectly.

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: My Overrule Sample
« Reply #14 on: April 12, 2009, 08:40:56 PM »
Yeah, I didnít follow Kean on Tonyís point either, I made mine for Polylines only, here.

Code: [Select]
DrawableOverrule::addOverrule(AcDbPolyline::desc(),drawableOverrule,Adesk::kTrue);

ARX also has far more control over the API than .NET does because you can override the isApplicable method.
One of the issues that I ran into was creating entities of the same type inside the worldDraw method,
which could cause end endless loop if not handled correctly.