.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Create a user parameter for a dynamic block

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
rick_hgy
5855 Views, 8 Replies

Create a user parameter for a dynamic block

Hello,

 

We have some dnyamic block share set of parameters, if we change a parameter's value, all block that reference this parameter should be change. we can do it by program.

 

but create user parameters for a dynamic block must be by hand, can we create a user parameter by code?

 

another way is user global parameter. does AutoCAD Parametric function's user value can be share with dynamic block?

 

Thanks for any inputs

 

 

 

8 REPLIES 8
Message 2 of 9
philippe.leefsma
in reply to: rick_hgy

Hi,

 

Answer to both your question is not doable at the moment.

 

Sorry for the bad news.

 

Regards,

Philippe.

 

Philippe Leefsma
Developer Consultant
Developer Technical Services
Global Subscription & Support

 

Autodesk EMEA

 

www.autodesk.com/joinadn



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

Message 3 of 9
rick_hgy
in reply to: philippe.leefsma

Thanks, Phillippe.

 

we found a link that create user parameter for dynamic block can be done by code in AutoCAD 2012, a demo api can be fond at :

http://through-the-interface.typepad.com/through_the_interface/2011/08/a-simplified-net-api-for-acce...

 

but in AutoCAD 2010, Parametric's user variable and dynamic block's user parameter had different means.

 

so hope global parameter coming soon in next version.

 

 

Message 4 of 9
philippe.leefsma
in reply to: rick_hgy

Hi Rick,

 

If you look carefully, then you should see that I actually took part in writting most of this parametric high level API 🙂

 

There is no naming change between 2010 and 2012, just some more parametric functionalities, sorry I should have mentionned that, but I got confused by your question about dynamic parameters:

 

So a dynamic parameter is a property that controls something, length for example, inside a dynamic block. I don't think you can set those to share a commomn global value, they are basically independent double values.

 

A user parameter, or associative variable (AssocVariable in API naming) is different. That's a variable part of the associative network that can be set to a global value or an equation involving other AssocVariables.

 

I believe that the scope of those AssocVariable is limited to each block definition, that means you cannot use a variable from model space in a block or vice versa, or between blocks, however you may want to confirm that.

 

I hope it provides a little more context, feel free to send me your feedback on that or on the high level API (you can update the blog post, it might be the easiest way, it will reach me anyway).

 

Regards,

Philippe. 



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

Message 5 of 9
rick_hgy
in reply to: philippe.leefsma

thanks, Philippe.

 

I should be observed that from your signature, sorry.

 

Yes, your API is much useful for us, we used it to import the user parameter from a xls file for the dynamic blocks. and we can update theall dynamic block reference's parameter by DynamicBlockReferencePropertyCollection 

 

thanks again. 

 

Another two question about dynamic block.

 

  1. dimension update problem. if we change the property of dynamic block, the entity will be change but the dimension wouldn't update automatically. we should be use "dimregen" and "regen" command by code. but you know, in RealDWG, there is no interface command to do this. 
  2. Hatch update problem. sometime the hatch can be automatically update, but some time's failed. we can't find the rule for those upgrade action. in RealDWG, it's cant be update.

can we find solution about those two problem for AutoCAD & RealDWG?

 

the attachment is the testing project.

 

the testing process is:

 

1. start AutoCAD 2010, and open the blocktesting.dwg

2. netload the otis_testing.dll

3. use the command "gendraw" to insert the dynamic blocks

4. use the command "updatedraw" to update the blocks.

 

sorry that it's testing project so the interface is simply Chinese. you can change the number of the black box in the png highlight.

 

the zip file include the testing dwg file, interface and code.

 

Thanks for your great support!

 

Rick

 

 

Message 6 of 9
philippe.leefsma
in reply to: rick_hgy

Hi Rick,

 

There is a known issue with the .Net API concerning not updating the block automatically after modifying the dynamic properties.

 

Here is a workaround I was providing for a similar previous request, unfortunatly it involves invoking some ObjectARX code:

 

A possible solution would be to modify the property using the same .net code that you provided and rely on an external function imported from an ARX module that will “refresh” the dynamic block reference properties. You don’t need to actually load the arx module in order to get it working, you just have to reference the *.arx dll on your disk.

 

Here is the arx code I have to refresh the block properties:

 

void RefreshDynamicBlkProperty(AcDbObjectId blockRefId)

{

      AcDbEntity* pEnt = NULL;

      if (acdbOpenObject(pEnt, blockRefId , AcDb::kForRead) != Acad::eOk)

      {

            acutPrintf(L"\nError opening entity.");

            if(pEnt)  pEnt->close();

            return;

      }

 

      AcDbBlockReference *pBlkRef = AcDbBlockReference::cast(pEnt);

 

      // initialise a AcDbDynBlockReference from the object id of the blockreference

      AcDbDynBlockReference* pDynBlkRef = new AcDbDynBlockReference(pBlkRef->objectId());

 

      //Don't forget to close the blockreference here,

      //otherwise you wont be able to modify properties

      pEnt->close();

 

      if (pDynBlkRef)

      {

            AcDbDynBlockReferencePropertyArray blkPropAry;

            pDynBlkRef->getBlockProperties(blkPropAry);

           

            Acad::ErrorStatus err;

            AcDbDynBlockReferenceProperty blkProp;

 

            for(long lIndex1=0L ; lIndex1<blkPropAry.length() ; ++lIndex1)

            {

                  blkProp = blkPropAry[lIndex1];

     

                  AcDbEvalVariant value = blkProp.value();

 

                  if(!blkProp.readOnly())

                  {

                        if((err = blkProp.setValue(value)) != Acad::eOk)

                        {

                              acutPrintf(L"\nError setting property value...");

                        }

                  }

            }

 

            //Don't forget to delete this reference, otherwise you will have problems.

            delete pDynBlkRef;

      }

}

 

 

Last thing you need to do on the arx side is to export this method. To do that you have to declare in one of the header (StdAfx.h for example) the following export:

 

extern "C" void _declspec(dllexport) RefreshDynamicBlkProperty(AcDbObjectId blockRefId);

 

And add to your arx project a .def file that looks like this:

 

LIBRARY "asdkArxMain"

 

EXPORTS RefreshDynamicBlkProperty

 

 

 

You just need to import this method in your .net dll and call it at the end of your command as follow:

 

 

const string arxPath = "C:\\My Documents\\AutoCAD\\ARX\\asdkArxMain.arx";

 

[DllImport(arxPath,

    CharSet = CharSet.Unicode,

    CallingConvention = CallingConvention.Cdecl,

    EntryPoint = "RefreshDynamicBlkProperty")]

private static extern void RefreshDynamicBlkProperty(ObjectId blockRefId);

 

[CommandMethod("SetDynamicBlkProperty")]

static public void SetDynamicBlkProperty()

{

    Document doc = Application.DocumentManager.MdiActiveDocument;

    Editor ed = doc.Editor;

 

    PromptEntityOptions peo = new PromptEntityOptions("Select a dynamic block reference...");

    peo.SetRejectMessage("\nMust be a block reference...");

    peo.AddAllowedClass(typeof(BlockReference), true);

 

    PromptEntityResult per = ed.GetEntity(peo);

 

    if (per.Status != PromptStatus.OK)

        return;

 

    using (Transaction Tx = doc.TransactionManager.StartTransaction())

    {

        BlockReference oBlkRef = Tx.GetObject(per.ObjectId, OpenMode.ForWrite) as BlockReference;

 

        if (oBlkRef.IsDynamicBlock)

        {

            DynamicBlockReferencePropertyCollection oProperties = oBlkRef.DynamicBlockReferencePropertyCollection;

 

            BlockTableRecord oBtr = Tx.GetObject(oBlkRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;

            ed.WriteMessage("\nBlock Record: " + oBtr.Name + "\n");

 

            foreach (DynamicBlockReferenceProperty oProp in oProperties)

            {

                object[] values = oProp.GetAllowedValues();

 

                ed.WriteMessage("\n - PropertyName: " + oProp.PropertyName + "  UnitsType: " + oProp.UnitsType.ToString());

 

                for (int i = 0; i < values.Length; ++i)

                {

                    ed.WriteMessage("\n . Value[" + i.ToString() + "]: " + values[i].ToString());

                }

 

                if (oProp.PropertyName == "Origin")

                {

                    Point3d origin = (Point3d)oProp.Value;

                    ed.WriteMessage("\n . Origin: " + origin.ToString());

 

                    Point3d originWCS = origin.TransformBy(oBlkRef.BlockTransform);

                    ed.WriteMessage("\n . Origin WCS: " + originWCS.ToString());

                }

 

                //Switch Property

                if (oProp.PropertyName == "Visibility" && !oProp.ReadOnly)

                {

                    if (oProp.Value.ToString() == values[0].ToString()) oProp.Value = values[1];

                    else oProp.Value = values[0];

                }

 

                if (oProp.PropertyName == "Angle" && !oProp.ReadOnly)

                {

                    oProp.Value = 10.0 * 3.1416 / 180.0;

                }

            }

        }

 

        Tx.Commit();

        RefreshDynamicBlkProperty(oBlkRef.Id);

    }

}



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

Message 7 of 9
rick_hgy
in reply to: philippe.leefsma

Great thanks for your help, Philippe.

 

ARX is ok for us. 

 

Thanks again, 

 

Rick

Message 8 of 9
BellwetherBill
in reply to: rick_hgy

Is this an Autocad 2010 problem? I have done some similar things with hatching and dimensions in simple blocks and they seam to update fine while modifying the block properties as well as updating the AssocVariables associated with it. I am working in 2012

 

I am however have the same issue where dimensions and hatches nested in an AssocArray don't update properly. Has anyone seen this or know why?

 

Thanks, Bill

Message 9 of 9
rick_hgy
in reply to: BellwetherBill

We tested it in AutoCAD 2012, worked fine. we need more test.

 

in AutoCAD 2010, sometimes it's work fine, sometimes didn't. 

 

In RealDWG 2012, the same problem with AutoCAD 2010.

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost