tag:blogger.com,1999:blog-104259452009-07-09T08:37:32.390-03:00ObjectARX & DummiesThis site was built to allow users to learn about ObjectARX® and AutoCAD® programming.
ObjectARX® and AutoCAD® are trademarks of Autodesk Inc.Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.comBlogger73125tag:blogger.com,1999:blog-10425945.post-63241327992167188872009-05-16T13:53:00.005-03:002009-05-16T14:09:08.119-03:00AU2008 ClassHello,<br /><br />Several people have asked me about some advice on creating custom classes inside ObjectARX.<br />I have made a detailed tutorial and presented it as a Class last year at Autodesk University.<br /><br />There is an online video recording, PPT and PDF of this class at AU2008 website:<br /><a href="http://au.autodesk.com/@script?nd=class&session_id=3019">AU2008</a><br /><br />For your convinience, I have also posted a direct link to the PDF:<br /><a href="http://files.ofcdesk.com/ThirdParty/files/ObjectARX/AU2008/CP311_5_ThePowerofObjectARX.pdf">Download</a><br /><br />This is the link for related source files:<br /><a href="http://files.ofcdesk.com/ThirdParty/files/ObjectARX/AU2008/Projects_Exercise2.zip">Projects_Exercise2.zip</a><br /><br />Best regards,<br />Fernando Malard.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-6324132799216718887?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-21981018033463234882009-02-11T09:56:00.004-02:002009-02-11T10:15:53.413-02:00AutoCAD 2010 announced!Hello,<br /><br />AutoCAD 2010 was announced:<br /><a href="http://finance.yahoo.com/news/Autodesk-Takes-3D-Design-and-prnews-14269988.html">http://finance.yahoo.com/news/Autodesk-Takes-3D-Design-and-prnews-14269988.html</a><br /><br />Very exciting new features and better support for .NET programming for customizing entities (I plan to discuss this further soon).<br /><br />Meanwhile, you may check these new features through a great collection of videos on the following page:<br /><br /><a href="http://heidihewett.blogs.com/files/autocad2010videos.htm">http://heidihewett.blogs.com/files/autocad2010videos.htm</a><br /><br />Regards,<br />Fernando.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-2198101803346323488?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com1tag:blogger.com,1999:blog-10425945.post-18961566255897869722008-04-29T16:39:00.001-03:002008-04-29T16:49:06.975-03:00AU2008 VotingHello,<br /><br />This year, AU (Autodesk University) classes will be rated by vote.<br />I have sent 3 classes under the <strong>Customization & Programming</strong> Power Track.<br />If you plan to attend AU2008 and would like to see one of my classes please take some time to vote through the following link:<br /><br /><a href="https://www.surveymonkey.com/s.aspx?sm=Yy_2fqK2TzVXoIf7d0TuRulw_3d_3d">AU2008 Voting</a><br /><br />My classes are:<br /><br /><strong><em>1) The Power of ObjectARX® - The Lab – AutoCAD – Level: Advanced<br /><br />2) The Power of ObjectARX® - The Class – AutoCAD – Level: Intermediate<br /><br />3) Creating Your Own Vertical Application Through AutoCAD® OEM – AutoCAD – Level: Intermediate</em></strong><br /><br />Hope these classes are approved and I hope you are able to attend this year!<br />Regards,<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-1896156625589786972?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com1tag:blogger.com,1999:blog-10425945.post-89337714768851842752008-03-27T09:43:00.000-03:002008-03-27T10:40:26.314-03:00Version ControlHello,<br /><br />Probably you will need or already need some version controlling on your software or on its modules.<br />This is made through the <span style="color:#ff0000;"><strong>VS_VERSION_INFO</strong></span><span style="color:#000000;"> resource inside <strong>C++</strong> projects and through <strong><span style="color:#ff0000;">AssemblyInfo.cs</span></strong> file inside <strong>C#</strong> projects.</span><br /><br />I have found an old but up to date tool (<strong>runs from VS2002 to VS2008</strong>) which allows you to easily manage these version informations. This tool, from <a href="http://www.codeproject.com/script/Membership/Profiles.aspx?mid=820347">Julijan Sribar</a>, is an AddIn which tracks all opened projects and allow you to manage each version information. This tool is provided for free and its source code is also available for download: <a href="http://www.codeproject.com/KB/macros/versioningcontrolledbuild.aspx">Versioning Controlled Build</a><br /><br />Another issue is how to get this information at runtime to display, for instance, this version at an "<strong><em>About</em></strong>" like dialog inside your product. To do that in VC++ we need to read the VS_VERSION_INFO resource and get what we want. There is also another great article <a href="http://www.codeproject.com/KB/cpp/GetLocalVersionInfos.aspx">Retrieving version information from your local application's resource</a>, from <a href="http://www.codeproject.com/script/Membership/Profiles.aspx?mid=553157">luetz</a>,explaining how to do that.<br /><br />Through C# there is no big deal, you can read the version information from AssemblyInfo as follows:<br /><br /><span style="font-family:courier new;color:#3333ff;">System.Reflection.Assembly oAssembly = System.Reflection.Assembly.GetExecutingAssembly(); </span><br /><span style="font-family:courier new;color:#3333ff;">System.Diagnostics.FileVersionInfo oFileVersionInfo = FileVersionInfo.GetVersionInfo(oAssembly.Location) ;</span><br /><span style="font-family:courier new;color:#3333ff;">MessageBox.Show("Version Info", oFileVersionInfo.ProductVersion);</span><br /><br />Hope this help you to keep your file versions organized and updated!<br />Cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-8933771476885184275?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com8tag:blogger.com,1999:blog-10425945.post-87225332489555657892008-03-25T00:06:00.000-03:002008-03-25T00:16:42.444-03:00Blog Classes content updateHello,<br /><br />I have updated and fixed some classes sample code that are not UNICODE aware that will not compile inside VS2005 (ObjectARX 2007, 2008 and 2009).<br /><br />Basically, I have changed:<br /><br />- Add <strong><span style="color:#3333ff;">_T()</span></strong> macro to all strings;<br />- Changed strcpy() to <strong><span style="color:#3333ff;">_tcscpy()</span></strong> which is UNICODE aware;<br />- Changed char* to <strong><span style="color:#3333ff;">TCHAR*</span></strong> or to <strong><span style="color:#3333ff;">ACHAR*</span></strong> pointers;<br /><br /><strong><span style="color:#ff0000;">Important</span></strong>: <em>ACHAR is a typedef present inside "AdAChar.h" ObjectARX header. If you are trying to compile for non-UNICODE ObjectARX versions replace ACHAR* by TCHAR* (or char*) and you should get out of compilation errors.</em><br /><br />Cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-8722533248955565789?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com1tag:blogger.com,1999:blog-10425945.post-14591080584771149922008-03-19T00:39:00.000-03:002008-03-19T00:43:09.935-03:00VS2005 SamplesHello,<br /><br />I have updated some VS2002 samples to VS2005.<br />There are two new files, ending with "VC8" which are the VS2005 converted solution/projects.<br /><br />You can download these projects from here:<br /><br /><a href="http://files.ofcdesk.com/ThirdParty/files/ObjectARX/VS2005/">VS2005 Samples</a><br /><br />These should compile fine with ObjectARX 2007, 2008 and 2009.<br />Note that if you plan to be 100% compatible with these 3 releases you will need to use the 2007 version of ObjectARX SDK.<br /><br />Cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-1459108058477114992?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com7tag:blogger.com,1999:blog-10425945.post-51234786612938737602008-02-13T08:10:00.000-02:002008-02-13T08:22:01.483-02:00AutoCAD 2009Hello,<br /><br />Yesterday, February 12th, <strong>Autodesk</strong> has officially announced its <strong>2009 product line</strong>.<br />Read more about here:<br /><br /><a href="http://www.worldpressdays08.com/pages/page.cfm?action=products&sub1=1">http://www.worldpressdays08.com/pages/page.cfm?action=products&sub1=1</a><br /><br /><strong>AutoCAD 2009</strong> (codename <strong>Raptor</strong>) will implement several new features like these major ones:<br /><br />- View Cube (easy 3D view);<br />- Steering Wheel (easy 3D navigation);<br />- Office like Ribbon interface;<br />- Menu Browser;<br />- Action recorder;<br />- Geographic location;<br />- Modeless Layer manager (works now like a toolpallete);<br /><br />There are much more and you may find these detailed features soon at Autodesk website.<br /><br />My friend, Shaan Hurley, have a more detailed list at his Blog:<br /><a href="http://autodesk.blogs.com/between_the_lines/2008/02/the-2009-produc.html">http://autodesk.blogs.com/between_the_lines/2008/02/the-2009-produc.html</a><br /><br />Regarding to programming aspects, <strong>AutoCAD 2009</strong> is backward compatible with 2007 and 2008. This way an application compiled with <strong>ObjectARX 2007</strong> will be able to run inside all these 3 versions.<br /><br />Actually, AutoCAD 2009 was built using <strong>VS2005 Service Pack 1</strong> but if you plan to keep your project backward compatible it is recommended to <strong>use VS2005 without Service Pack</strong>.<br /><br />Probably the next version of AutoCAD will break the binary compatibility with 2007,2008 and 2009 and will use <strong>VS2008</strong>. Autodesk seems to be aligned with Microsoft Visual Studio evolution and will try to make only binary compatibility break on every 3 releases.<br /><br />Cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-5123478661293873760?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-5178082910388274422008-01-14T23:34:00.000-02:002008-01-14T23:37:04.365-02:00AutoCAD GUI testsHello,<br /><br />I would like to introduce a new Blog this year. It will be about AutoCAD Applications GUI tests. The idea behind this Blog is to discuss methods and tools that could be used to test all types of AutoCAD applications against AutoCAD interface to reach a better test experience approaching the real user environment.<br /><br />If you are interested on discuss this I would like to invite you to visit my new Blog at:<br /><br /><a href="http://acadguitest.blogspot.com/">http://acadguitest.blogspot.com/</a><br /><br />Best regards,<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-517808291038827442?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-51113543395249910782007-12-04T08:51:00.000-02:002007-12-04T08:59:56.235-02:00AU2007 was huge!Hello,<br /><br />AU2007 was really huge. The initial estimations are around 10.000 attendees.<br />What can we expect for AU2008 ? 15.000 ???<br /><br />I will post on the next days my two courses materials but as one of my classes was recorded here is the link for the presentation (you will need to register to AU Online to be able to see the video):<br /><br /><a href="http://autodesk.mediasite.com/autodesk/autologinform/?peid=7a7838a8-1bc6-4d68-8b03-3158b14c023f">http://autodesk.mediasite.com/autodesk/autologinform/?peid=7a7838a8-1bc6-4d68-8b03-3158b14c023f</a><br /><br />Best Regards.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-5111354339524991078?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com3tag:blogger.com,1999:blog-10425945.post-36654799363629883722007-10-22T23:52:00.000-02:002007-10-22T23:53:41.710-02:00AutoCAD next version ?Hello,<br /><br />We are approaching the end of 2007 and if Autodesk keep its policy with annual releases of AutoCAD we will probably have soon the next release which would be 2009.<br /><br />I would like to ask you what do you expect as new features of this upcoming release. Please add your comments to this post and soon we will see what's new from the next AutoCAD.<br /><br />Meanwhile, cross your fingers and wait for the official announcement.<br /><br />Best regards,<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-3665479936362988372?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-73679721452133962872007-08-28T18:03:00.000-03:002007-08-28T18:12:06.909-03:00AU2007Hello,<br /><br />For those who will have the opportunity to participate on this year's Autodesk University at Las Vegas I would like to suggest my two classes:<br /><br /><a><strong><span style="color:#000099;">CP401-2</span></strong></a><br /><span style="color:#000099;">The Power of ObjectARX®</span><br /><br /><a><strong><span style="color:#000099;">CP405-1</span></strong></a><br /><span style="color:#000099;">Creating Your Own Vertical Application Through AutoCAD® OEM<br /></span><br />Registration:<br /><a href="http://au.autodesk.com/2007/register/">http://au.autodesk.com/2007/register/</a><br /><br />Hope to meet you in Vegas this year!<br />Regards,<br />Fernando.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-7367972145213396287?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-89899156173272761602007-05-30T10:42:00.000-03:002007-05-30T10:45:24.809-03:00AUGI BrazilHello,<br /><br />I would like to invite all Portuguese speaking world to visit the brand new <strong>AUGI Brasil</strong> website.<br /><br /><strong>AUGI Br</strong> was officially launched today (<strong>30/05/2007</strong>) which is the same day <strong>AutoCAD 2008</strong> is being officially announced here in Brazil.<br /><br /><a href="http://www.augibr.com">http://www.augibr.com</a><br /><br />Congratulations!<br /><br />Fernando.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-8989915617327276160?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-42547262037361622582007-03-06T10:57:00.000-03:002007-03-06T11:01:26.575-03:00Debug AutoCAD 2007 from VS2005 on Windows VistaHello,<br /><br />After some research I have tried to <strong>Debug AutoCAD 2007</strong> again but this time starting the Visual Studio 2005 with "<strong>Run as Administrator</strong>" feature. Now I'm able to Debug AutoCAD 2007 from <strong>VS2005</strong>.<br /><br />More tips to come as soon as I figure out them... :)<br /><br />If you have discovered something else, please share with this Blog!<br /><br />Cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-4254726203736162258?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com8tag:blogger.com,1999:blog-10425945.post-39713934219058811912007-03-06T08:25:00.000-03:002007-03-06T10:43:43.010-03:00ObjectARX & Windows VistaHello,<br /><br />I have migrated to <strong>Windows Vista Ultimate</strong> and would like to share some problems / workaround I have made so far.<br /><br />The first issue you will face is related to <strong>Visual Studio</strong>. Windows Vista supports partially (<a href="http://go.microsoft.com/?linkid=5728666">VS2005</a>) and do not natively support previous versions. As I have several projects running on <strong>AutoCAD 2005 and 2006</strong> (they require <strong>VS2002</strong> to compile) I need a way to run then from inside Windows Vista. I have then remembered the good old <strong>Microsoft Virtual PC</strong> which is now free and has a new release 2007.<br /><br />I have downloaded and installed (<a href="http://www.microsoft.com/windows/products/winfamily/virtualpc/default.mspx">Virtual PC 2007</a>). After that I have then created a new virtual machine with <strong>Windows XP PRO SP2</strong> and then installed <strong>AutoCAD 2005</strong>, <strong>2006</strong> and <strong>VS2002</strong>. Of course my machine helps a lot because it runs an <strong>Intel Core 2 Duo</strong> processor and has <strong>2Gb RAM</strong>. The <strong>Virtual PC 2007</strong> runs well but it causes some erratic mouse moves and some small locks. Unsatisfied with that I then go to the Google and find out a great tip about how to improve <strong>Virtual PC 2007</strong> performance adding a new parameter to its (<a href="http://codebetter.com/blogs/jeff.lynch/archive/2006/11/28/VPC-2007-Beta_3A00_-Centrino-915-Chipset-Issues.aspx">XML configuration file</a>). After changed this it runs fast and without any erractic mouse moves. (Thanks to <strong><em>Jeff Lynch</em></strong>)<br /><br />Regarding to <strong>AutoCAD 2007</strong> and Windows Vista at the beginning I was unable to run it. As I'm new to Vista I have found a command when you right click on the application "<strong>Run as Administrator</strong>". This did the trick and now I'm able to open AutoCAD but I'm still unable to <strong>Debug</strong> or <strong>Attach to Process</strong> on Vista. This is not the proper solution once Autodesk already told us about some issues related with Vista and will release soon a Service Pack to <strong>AutoCAD 2007</strong> and <strong>LT 2007</strong>:<br /><br /><a href="http://autodesk.blogs.com/between_the_lines/2007/02/autocad_and_aut.html">AutoCAD 2007 and LT 2007</a><br /><br /><strong>AutoCAD 2008</strong>: It will be released soon and some good information about its integration with Windows Vista can be found here:<br /><br /><a href="http://autodesk.blogs.com/between_the_lines/2007/03/autocad_2008_wi.html">AutoCAD 2008</a><br /><br />(Thanks to <strong><em>Shaan Hurley</em></strong>)<br /><br />That's it for now.<br />Cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-3971393421905881191?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-77226235385054716842007-02-13T23:56:00.000-02:002007-02-14T00:00:50.596-02:00AutoCAD 2008 is coming...Hello,<br /><br />Autodesk has announced the upcoming AutoCAD 2008 version. It will be released on both 32-bit and 64-bit versions. There is no change on dwg file format. Further it will officially support Windows Vista.<br /><br />More information will be announced soon from Autodesk. Stay tuned at:<br /><br /><a href="http://www.autodesk.com">http://www.autodesk.com</a><br /><a href="http://through-the-interface.typepad.com/">http://through-the-interface.typepad.com/</a><br /><a href="http://autodesk.blogs.com/between_the_lines/">http://autodesk.blogs.com/between_the_lines/</a><br /><br />Cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-7722623538505471684?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-1168648402197229432007-01-12T22:33:00.001-02:002007-01-13T00:49:21.238-02:00Exercise2 - Step6<strong><span style="font-family:Verdana;font-size:85%;">Creating a Custom Entity – Exercise 2 – Step 6</span></strong><br /><strong><span style="font-family:Verdana;font-size:85%;"></span></strong><br /><span style="font-family:Verdana;font-size:85%;">On this step we will implement a pretty nice feature. Imagine you would like to add a </span><strong><span style="font-family:Verdana;font-size:85%;">hatch filling </span></strong><span style="font-family:Verdana;font-size:85%;">to your custom entity. We can take advantage of ObjectARX </span><strong><span style="font-family:Verdana;font-size:85%;">embedded object </span></strong><span style="font-family:Verdana;font-size:85%;">feature to implement this. There is a class called </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbHatch </span></strong><span style="font-family:Verdana;font-size:85%;">which represents the AutoCAD hatch entity. This class can be used as an embedded object and we can use its </span><strong><span style="font-family:Verdana;font-size:85%;">worldDraw() </span></strong><span style="font-family:Verdana;font-size:85%;">method to draw our own hatch pattern. The first thing you need to do is to add an </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbHatch </span></strong><span style="font-family:Verdana;font-size:85%;">member to our custom entity’s class. We will also declare the </span><strong><span style="font-family:Verdana;font-size:85%;">SetupHatch() </span></strong><span style="font-family:Verdana;font-size:85%;">method to setup the hatch properties. To do that, open the </span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline.h </span></strong><span style="font-family:Verdana;font-size:85%;">file, and place the following lines at the end of class declaration:</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="color:#3333ff;"><span style="font-family:Lucida Console;font-size:85%;">protected:</span><br /><span style="font-family:Lucida Console;font-size:85%;">AcDbHatch m_Hatch;</span><br /><span style="font-family:Lucida Console;font-size:85%;"></span><br /><span style="font-family:Lucida Console;font-size:85%;">public:</span><br /><span style="font-family:Lucida Console;font-size:85%;">void SetupHatch();</span><br /><span style="font-family:Verdana;font-size:85%;"></span></span><br /><span style="font-family:Verdana;font-size:85%;">Further, we will need to add 3 more methods to our entity to handle modifications. The first method will handle all </span><strong><span style="font-family:Verdana;font-size:85%;">graphic transformations</span></strong><span style="font-family:Verdana;font-size:85%;">. The 2 remaining methods will handle the </span><strong><span style="font-family:Verdana;font-size:85%;">STRETCH </span></strong><span style="font-family:Verdana;font-size:85%;">command:</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="color:#3333ff;"><span style="font-family:Lucida Console;font-size:85%;">public:</span><br /><span style="font-family:Lucida Console;font-size:85%;">virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d & xform);</span><br /><span style="font-family:Lucida Console;font-size:85%;">virtual Acad::ErrorStatus getStretchPoints(</span><br /><span style="font-family:Lucida Console;font-size:85%;">AcGePoint3dArray & stretchPoints) const;</span><br /><span style="font-family:Lucida Console;font-size:85%;">virtual Acad::ErrorStatus moveStretchPointsAt(</span><br /><span style="font-family:Lucida Console;font-size:85%;">const AcDbIntArray & indices, const AcGeVector3d & offset);</span></span><br /><span style="font-family:Lucida Console;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">Our hatch object needs to be configured. To do this we will place, </span><u><span style="font-family:Verdana;font-size:85%;">inside the custom entity’s constructor </span></u><span style="font-family:Verdana;font-size:85%;">located at </span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline.cpp </span></strong><span style="font-family:Verdana;font-size:85%;">file, the following code (note that this configuration needs to be done only once so the constructor is the better place to put it):</span><br /><br /><p><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AuPolyline::AuPolyline () : AcDbPolyline ()<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.setNormal(AcGeVector3d::kZAxis);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.setElevation(this->elevation());<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.setAssociative(true);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.setPatternScale(1.0);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.setPatternAngle(45.0);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.setHatchStyle(AcDbHatch::kNormal);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.setPattern(AcDbHatch::kPreDefined,_T("LINE"));<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}</span></p><span style="font-family:Verdana;font-size:85%;">This configuration will set the hatch </span><strong><span style="font-family:Verdana;font-size:85%;">pattern</span></strong><span style="font-family:Verdana;font-size:85%;">, </span><strong><span style="font-family:Verdana;font-size:85%;">normal </span></strong><span style="font-family:Verdana;font-size:85%;">vector, </span><strong><span style="font-family:Verdana;font-size:85%;">elevation</span></strong><span style="font-family:Verdana;font-size:85%;">, </span><strong><span style="font-family:Verdana;font-size:85%;">scale</span></strong><span style="font-family:Verdana;font-size:85%;">, </span><strong><span style="font-family:Verdana;font-size:85%;">angle </span></strong><span style="font-family:Verdana;font-size:85%;">and </span><strong><span style="font-family:Verdana;font-size:85%;">style</span></strong><span style="font-family:Verdana;font-size:85%;">. In this example they are fixed but you may want to create one property for each of these parameters allowing the user to change them at runtime.</span><br /><span style="font-family:Verdana;font-size:85%;">Now we need to add the </span><strong><span style="font-family:Verdana;font-size:85%;">SetupHatch() </span></strong><span style="font-family:Verdana;font-size:85%;">method implementation to build the hatch loop according to our polyline boundary. The code will be as follows:</span><br /><br /><p><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">void AuPolyline::SetupHatch()<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">assertWriteEnabled();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Remove previous loop<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">for (int l=0; l<m_Hatch.numLoops(); l++)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.removeLoopAt(l);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Insert the updated loop<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint2dArray vertexPts;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGeDoubleArray vertexBulges;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Collect points and bulges<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">for(int i=0; i<numVerts(); i++) {<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint2d pt2d;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">double bulge = 0.0;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">this->getPointAt(i,pt2d);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">this->getBulgeAt(i,bulge);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">vertexPts.append(pt2d);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">vertexBulges.append(bulge);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Close the loop<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">vertexPts.append(vertexPts.first());<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">vertexBulges.append(vertexBulges.first());<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.appendLoop(AcDbHatch::kDefault, vertexPts, vertexBulges);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Refresh hatch<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.evaluateHatch();<br /></span><span style="font-family:Lucida Console;font-size:85%;"><span style="color:#3333ff;">}</span> </span></p><span style="font-family:Verdana;font-size:85%;"></span><span style="font-family:Verdana;font-size:85%;">On lines </span><strong><span style="font-family:Verdana;font-size:85%;">05-06 </span></strong><span style="font-family:Verdana;font-size:85%;">we make sure there is no previous loop inside hatch. At the line range </span><strong><span style="font-family:Verdana;font-size:85%;">11-18 </span></strong><span style="font-family:Verdana;font-size:85%;">we walk through the polyline vertexes and collect its points and bulges (</span><em><span style="font-family:Verdana;font-size:85%;">the bulge is the tangent of 1/4 of the included angle for the arc between the selected vertex and the next vertex</span></em><span style="font-family:Verdana;font-size:85%;">). The collected information will be stored at two dynamic vectors: </span><strong><span style="font-family:Verdana;font-size:85%;">AcGePoint3dArray </span></strong><span style="font-family:Verdana;font-size:85%;">and </span><strong><span style="font-family:Verdana;font-size:85%;">AcGeDoubleArray</span></strong><span style="font-family:Verdana;font-size:85%;">. On lines </span><strong><span style="font-family:Verdana;font-size:85%;">20-21 </span></strong><span style="font-family:Verdana;font-size:85%;">we close the polyline loop to </span><u><span style="font-family:Verdana;font-size:85%;">ensure our hatch boundary is closed</span></u><span style="font-family:Verdana;font-size:85%;">.</span><br /><span style="font-family:Verdana;font-size:85%;">On line </span><strong><span style="font-family:Verdana;font-size:85%;">22 </span></strong><span style="font-family:Verdana;font-size:85%;">we append the arrays to the hatch entity as one loop. The loop can be also a hole into the hatch surface but in this example our loop is </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbHatch::kDefault</span></strong><span style="font-family:Verdana;font-size:85%;">. On line </span><strong><span style="font-family:Verdana;font-size:85%;">24 </span></strong><span style="font-family:Verdana;font-size:85%;">we finish the hatch configuration process by calling the </span><strong><span style="font-family:Verdana;font-size:85%;">evaluateHatch() </span></strong><span style="font-family:Verdana;font-size:85%;">method which will generate the hatch itself.</span><br /><span style="font-family:Verdana;font-size:85%;">We need to call the </span><strong><span style="font-family:Verdana;font-size:85%;">SetupHatch() </span></strong><span style="font-family:Verdana;font-size:85%;">method inside some of our methods. The first place is inside the </span><strong><span style="font-family:Verdana;font-size:85%;">dwgInFields()</span></strong><span style="font-family:Verdana;font-size:85%;">. Place a call to this method at the end of this method as follows:</span><br /><br /><p><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Acad::ErrorStatus AuPolyline::dwgInFields (AcDbDwgFiler *pFiler)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;"><span style="color:#ff0000;"><em><strong>[ some lines were not displayed for code brevity ]</strong></em></span><br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Setup hatch<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">SetupHatch();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">return (pFiler->filerStatus ()) ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}</span></p><span style="font-family:Verdana;font-size:85%;">Next, we need to place another call inside </span><strong><span style="font-family:Verdana;font-size:85%;">moveGripPointsAt() </span></strong><span style="font-family:Verdana;font-size:85%;">method. When user moves some of the GRIP points we need to </span><u><span style="font-family:Verdana;font-size:85%;">recalculate the hatch boundary</span></u><span style="font-family:Verdana;font-size:85%;">. We need to do this only in cases the selected GRIP is not our center point. The change is made on lines </span><strong><span style="font-family:Verdana;font-size:85%;">15-18 </span></strong><span style="font-family:Verdana;font-size:85%;">as follows:</span><br /><br /><p><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Acad::ErrorStatus AuPolyline::moveGripPointsAt (<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const AcDbVoidPtrArray &gripAppData,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const AcGeVector3d &offset, const int bitflags)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">assertWriteEnabled () ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">for (int g=0; g<gripAppData.length(); g++)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Get grip data back and see if it is our 0 Grip<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">int i = (int)gripAppData.at(g);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// If it is our grip, move the entire entity. If not, forward the call<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">if (i == 9999)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">this->transformBy(offset);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">else<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcDbCurve::moveGripPointsAt (gripAppData, offset, bitflags);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">SetupHatch();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">return (Acad::eOk);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}</span></p><span style="font-family:Verdana;font-size:85%;">To make the hatch entity appear as part of our custom entity’s graphics we need to call its </span><strong><span style="font-family:Verdana;font-size:85%;">worldDraw() </span></strong><span style="font-family:Verdana;font-size:85%;">method from inside our entity’s </span><strong><span style="font-family:Verdana;font-size:85%;">worldDraw()</span></strong><span style="font-family:Verdana;font-size:85%;">: </span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><br /><p><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Adesk::Boolean AuPolyline::worldDraw (AcGiWorldDraw *mode)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;"><span style="color:#ff0000;"><strong><em>[ some lines were not displayed for code brevity ]</em></strong></span><br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// =======================================================<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// HATCH<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.worldDraw(mode);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">//------ Returning Adesk::kFalse here will force viewportDraw() call<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">return (Adesk::kTrue) ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}</span></p><span style="font-family:Verdana;font-size:85%;"></span><span style="font-family:Verdana;font-size:85%;">Finally, we need to implement the code for the </span><u><span style="font-family:Verdana;font-size:85%;">3 new methods </span></u><span style="font-family:Verdana;font-size:85%;">we have added to our custom entity’s class. Open the </span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline.cpp </span></strong><span style="font-family:Verdana;font-size:85%;">file and add the following methods:</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><br /><p><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// -------------------------------------------------------------------------<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Acad::ErrorStatus AuPolyline::transformBy(const AcGeMatrix3d & xform)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Acad::ErrorStatus retCode = AcDbPolyline::transformBy (xform) ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">m_Hatch.transformBy(xform);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">return (retCode) ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// -------------------------------------------------------------------------<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Acad::ErrorStatus AuPolyline::getStretchPoints(AcGePoint3dArray & stretchPoints) const<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcDbIntArray osnapModes,geomIds;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">return this->getGripPoints(stretchPoints,osnapModes,geomIds) ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// -------------------------------------------------------------------------<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Acad::ErrorStatus AuPolyline::moveStretchPointsAt(<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const AcDbIntArray & indices,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const AcGeVector3d & offset)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Acad::ErrorStatus ret = AcDbPolyline::moveGripPointsAt (indices, offset);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">SetupHatch();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">return ret;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">} </span></p><span style="font-family:Verdana;font-size:85%;">The first method on lines </span><strong><span style="font-family:Verdana;font-size:85%;">02-07</span></strong><span style="font-family:Verdana;font-size:85%;">, </span><strong><span style="font-family:Verdana;font-size:85%;">transformBy()</span></strong><span style="font-family:Verdana;font-size:85%;">, is responsible for all entity’s graphic transformations such as </span><strong><span style="font-family:Verdana;font-size:85%;">MOVE</span></strong><span style="font-family:Verdana;font-size:85%;">, </span><strong><span style="font-family:Verdana;font-size:85%;">ROTATE</span></strong><span style="font-family:Verdana;font-size:85%;">, </span><strong><span style="font-family:Verdana;font-size:85%;">SCALE</span></strong><span style="font-family:Verdana;font-size:85%;">, etc. First we forward the call to our base class and then apply the same transformation to the hatch. This way it will follow all transformations applied to our AuPolyline. </span><br /><span style="font-family:Verdana;font-size:85%;">The second method on lines </span><strong><span style="font-family:Verdana;font-size:85%;">09-13</span></strong><span style="font-family:Verdana;font-size:85%;">, </span><strong><span style="font-family:Verdana;font-size:85%;">getStretchPoints()</span></strong><span style="font-family:Verdana;font-size:85%;">, is responsible to return the points that are enabled to </span><u><span style="font-family:Verdana;font-size:85%;">stretch the entity</span></u><span style="font-family:Verdana;font-size:85%;">. In this case we would like to add all of our polyline vertexes. This method can reuse the </span><strong><span style="font-family:Verdana;font-size:85%;">getGripPoints() </span></strong><span style="font-family:Verdana;font-size:85%;">method which returns the same points we want.</span><br /><span style="font-family:Verdana;font-size:85%;">The last method on lines </span><strong><span style="font-family:Verdana;font-size:85%;">15-22</span></strong><span style="font-family:Verdana;font-size:85%;">, </span><strong><span style="font-family:Verdana;font-size:85%;">moveStretchPointsAt()</span></strong><span style="font-family:Verdana;font-size:85%;">, is responsible to apply the stretch transformation over the entity. We will also reuse the existing method </span><strong><span style="font-family:Verdana;font-size:85%;">moveGripPointsAt() </span></strong><span style="font-family:Verdana;font-size:85%;">because it does exactly what we need. Next we just need to call </span><strong><span style="font-family:Verdana;font-size:85%;">SetupHatch() </span></strong><span style="font-family:Verdana;font-size:85%;">again to ensure our hatch is updated with the new boundary resulting from the STRETCH command.</span><br /><span style="font-family:Verdana;font-size:85%;">Before test our custom entity, we need to place a call to </span><strong><span style="font-family:Verdana;font-size:85%;">SetupHatch() </span></strong><span style="font-family:Verdana;font-size:85%;">just before to close the entity on its creation stage. Open the </span><strong><span style="font-family:Verdana;font-size:85%;">acrxEntryPoint.cpp </span></strong><span style="font-family:Verdana;font-size:85%;">file, of </span><strong><span style="font-family:Verdana;font-size:85%;">AuUserInterface </span></strong><span style="font-family:Verdana;font-size:85%;">project, and locate the </span><strong><span style="font-family:Verdana;font-size:85%;">AuUserInterface_MyCommand1() </span></strong><span style="font-family:Verdana;font-size:85%;">method. See the code below:</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><br /><p><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">static void AuUserInterface_MyCommand1(void)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;"><span style="color:#ff0000;"><em><strong>[ some lines were not displayed for code brevity ]</strong></em></span><br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">pL->SetupHatch();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">pL->close();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}</span></p><span style="font-family:Verdana;font-size:85%;"></span><span style="font-family:Verdana;font-size:85%;">Now </span><strong><span style="font-family:Verdana;font-size:85%;">Build you Solution </span></strong><span style="font-family:Verdana;font-size:85%;">again. You should get no errors. Open AutoCAD, load your modules (remember, first </span><strong><span style="font-family:Verdana;font-size:85%;">BDX </span></strong><span style="font-family:Verdana;font-size:85%;">and then </span><strong><span style="font-family:Verdana;font-size:85%;">ARX</span></strong><span style="font-family:Verdana;font-size:85%;">). Fire </span><strong><span style="font-family:Verdana;font-size:85%;">MYCOMMAND1 </span></strong><span style="font-family:Verdana;font-size:85%;">command and create one AuPolyline entity. Next test the several features we have implemented. Try to </span><strong><span style="font-family:Verdana;font-size:85%;">COPY </span></strong><span style="font-family:Verdana;font-size:85%;">you entity, </span><strong><span style="font-family:Verdana;font-size:85%;">MOVE </span></strong><span style="font-family:Verdana;font-size:85%;">it, </span><strong><span style="font-family:Verdana;font-size:85%;">ROTATE </span></strong><span style="font-family:Verdana;font-size:85%;">it, </span><strong><span style="font-family:Verdana;font-size:85%;">SCALE </span></strong><span style="font-family:Verdana;font-size:85%;">it and apply a </span><strong><span style="font-family:Verdana;font-size:85%;">MIRROR</span></strong><span style="font-family:Verdana;font-size:85%;">. You can also use the </span><strong><span style="font-family:Verdana;font-size:85%;">STRETCH </span></strong><span style="font-family:Verdana;font-size:85%;">command and move the </span><strong><span style="font-family:Verdana;font-size:85%;">GRIP </span></strong><span style="font-family:Verdana;font-size:85%;">points to change the entity’s shape. </span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">Our </span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline </span></strong><span style="font-family:Verdana;font-size:85%;">entity is derived from </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbPolyline</span></strong><span style="font-family:Verdana;font-size:85%;">, right? So do you expect that a specific polyline commands like </span><strong><span style="font-family:Verdana;font-size:85%;">PEDIT </span></strong><span style="font-family:Verdana;font-size:85%;">work with our entity? </span><strong><span style="font-family:Verdana;font-size:85%;">Yes, it works! </span></strong><span style="font-family:Verdana;font-size:85%;">Try to fire the </span><strong><span style="font-family:Verdana;font-size:85%;">PEDIT </span></strong><span style="font-family:Verdana;font-size:85%;">command and select our polyline. It will accept it and will allow you to change the AuPolyline as if it is a native AutoCAD Polyline. You can add new vertexes, remove existing, join new segments and even open the polyline (Figure 19). Great!</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><a href="http://photos1.blogger.com/x/blogger/6284/765/640/947370/Figure19.jpg"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/147119/Figure19.jpg" border="0" /></a><br /><span style="font-family:Verdana;font-size:85%;">Figure 19 – AuPolyline modifications.</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><strong><span style="font-family:Verdana;font-size:85%;">Conclusion</span></strong><br /><span style="font-family:Verdana;font-size:85%;">In this session you have learned how to create a custom entity and add some of the possible features </span><strong><span style="font-family:Verdana;font-size:85%;">ObjectARX </span></strong><span style="font-family:Verdana;font-size:85%;">allows. </span><strong><em><span style="font-family:Verdana;font-size:85%;">This is really only the tip of the iceberg</span></em></strong><span style="font-family:Verdana;font-size:85%;">. There are much more you can do using </span><strong><span style="font-family:Verdana;font-size:85%;">ObjectARX </span></strong><span style="font-family:Verdana;font-size:85%;">classes and implementing more sophisticated features. I really hope you have enjoyed this session and hope it may help you to make the startup into the </span><strong><span style="font-family:Verdana;font-size:85%;">ObjectARX </span></strong><span style="font-family:Verdana;font-size:85%;">world.</span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-116864840219722943?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-1168648377036127252007-01-12T22:33:00.000-02:002007-01-13T00:48:58.675-02:00Exercise2 - Step5<strong><span style="font-family:Verdana;font-size:85%;">Creating a Custom Entity – Exercise 2 – Step 5</span></strong><br /><strong><span style="font-family:Verdana;font-size:85%;"></span></strong><br /><span style="font-family:Verdana;font-size:85%;">Sometimes you need to distribute an AutoCAD drawing with custom entities inside. By default, when AutoCAD opens a drawing and find some entity it does not recognize, it protects this entity and </span><strong><span style="font-family:Verdana;font-size:85%;">packs its binary data into a Proxy entity</span></strong><span style="font-family:Verdana;font-size:85%;">. The proxy entity </span><strong><span style="font-family:Verdana;font-size:85%;">protects your object data </span></strong><span style="font-family:Verdana;font-size:85%;">avoiding unwanted users to manipulate your custom entities.</span><br /><span style="font-family:Verdana;font-size:85%;">The proxy entity is merely a dummy entity with a </span><strong><span style="font-family:Verdana;font-size:85%;">fixed graphical representation</span></strong><span style="font-family:Verdana;font-size:85%;">. Several features of your custom entity will not be available once your code is not there to provide these methods. If your drawing is opened by an unadvised user that would be nice if you inform this user about the missing application.</span><br /><span style="font-family:Verdana;font-size:85%;">The proxy can contain specific graphics which will be generated with a call to your </span><strong><span style="font-family:Verdana;font-size:85%;">worldDraw() </span></strong><span style="font-family:Verdana;font-size:85%;">method just before AutoCAD close the drawing. The worldDraw() method has a parameter, an </span><strong><span style="font-family:Verdana;font-size:85%;">AcGiWorldDraw </span></strong><span style="font-family:Verdana;font-size:85%;">pointer, that allows you to call a </span><strong><span style="font-family:Verdana;font-size:85%;">regenType() </span></strong><span style="font-family:Verdana;font-size:85%;">method to find out if the caller is requesting proxy graphics to your entity. At this time, you can draw a different graphic to make and advertisement of your missing custom entity. The following code shows how to handle the proxy graphics:</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><br /><br /><p><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// ==================================================================<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// PROXY<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">if (mode->regenType() == kAcGiSaveWorldDrawForProxy)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Draw dummy text<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">CString strTxt = _T("AU Polyline");<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint3d ptTxt = GetPolylineCenter();<br /></span><span style="color:#3333ff;"><span style="font-family:Lucida Console;font-size:85%;">mode->geometry().text(ptTxt, AcGeVector3d::kZAxis, AcGeVector3d::kXAxis, szRef, 1.0, 0.0, strTxt);<br /></span><span style="font-family:Lucida Console;font-size:85%;">}</span></span></p><span style="font-family:Verdana;font-size:85%;">On this example the proxy graphics will be the standard entity graphic plus a text indicating our class name. You may also add an URL address of your product or company. We will use the center point as this text’s start point.</span><br /><span style="font-family:Verdana;font-size:85%;">Unfortunately this solution is not complete for AcDbPolyline derived entities. There is a problem when a polyline needs to generate its proxy graphics and the worldDraw() method </span><u><span style="font-family:Verdana;font-size:85%;">is not called</span></u><span style="font-family:Verdana;font-size:85%;">. To solve this problem we need to add another method, called </span><strong><span style="font-family:Verdana;font-size:85%;">saveAs()</span></strong><span style="font-family:Verdana;font-size:85%;">, to our class. This method has the following declaration:</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><strong><span style="font-family:Lucida Console;font-size:85%;">virtual void saveAs(AcGiWorldDraw * mode, AcDb::SaveType st);</span></strong><br /><span style="font-family:Verdana;font-size:85%;">The implementation of this method is as follows:</span><br /><p><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">void AuPolyline::saveAs(AcGiWorldDraw * mode, AcDb::SaveType st)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcDbPolyline::saveAs (mode, st) ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">if ((mode->regenType() == kAcGiSaveWorldDrawForProxy) &&<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">(st == AcDb::kR13Save))<br /></span><span style="color:#3333ff;"><span style="font-family:Lucida Console;font-size:85%;">this->worldDraw(mode);<br /></span><span style="font-family:Lucida Console;font-size:85%;">}</span></span></p><span style="font-family:Verdana;font-size:85%;">This method first forward the call to our base class and then test if the </span><strong><span style="font-family:Verdana;font-size:85%;">regenType() </span></strong><span style="font-family:Verdana;font-size:85%;">and the save type is </span><strong><span style="font-family:Verdana;font-size:85%;">AcDb::kR13Save</span></strong><span style="font-family:Verdana;font-size:85%;">. If they are, we forward the call to our own </span><strong><span style="font-family:Verdana;font-size:85%;">worldDraw() </span></strong><span style="font-family:Verdana;font-size:85%;">method which will draw the custom entity graphic plus the proxy text message.</span><br /><span style="font-family:Verdana;font-size:85%;">To test this behavior create some </span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline </span></strong><span style="font-family:Verdana;font-size:85%;">entities, save the drawing, close AutoCAD and then open this DWG without loading the application modules. Once the DWG file is opened you will see a proxy warning dialog with some information about the </span><u><span style="font-family:Verdana;font-size:85%;">missing application </span></u><span style="font-family:Verdana;font-size:85%;">(Figure 18). </span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;"><a href="http://photos1.blogger.com/x/blogger/6284/765/640/22770/Figure18.jpg"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/26964/Figure18.jpg" border="0" /></a><br />Figure 18 – Proxy Information dialog.</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">Note on the Figure 18 that our proxy text is displayed and also, at the proxy information dialog, you may find information about the </span><u><span style="font-family:Verdana;font-size:85%;">missing application</span></u><span style="font-family:Verdana;font-size:85%;">. This dialog allows users to choose one of the </span><u><span style="font-family:Verdana;font-size:85%;">3 options </span></u><span style="font-family:Verdana;font-size:85%;">about how AutoCAD will handle its proxy entities. You can also setup the standard proxy behavior accessing </span><strong><span style="font-family:Verdana;font-size:85%;">Tools </span></strong><span style="font-family:Verdana;font-size:85%;">> </span><strong><span style="font-family:Verdana;font-size:85%;">Options </span></strong><span style="font-family:Verdana;font-size:85%;">> </span><strong><span style="font-family:Verdana;font-size:85%;">Open and Save</span></strong><span style="font-family:Verdana;font-size:85%;">.</span><br /><span style="font-family:Verdana;font-size:85%;">Remember that the </span><strong><span style="font-family:Verdana;font-size:85%;">DBX </span></strong><span style="font-family:Verdana;font-size:85%;">module can be loaded to re-enable the custom entity or you can also send your DBX module along with the </span><strong><span style="font-family:Verdana;font-size:85%;">DWG </span></strong><span style="font-family:Verdana;font-size:85%;">file to enable third-party users to see your custom entity with complete information. This way you can provide a full graphical representation without the application interfaces (</span><strong><span style="font-family:Verdana;font-size:85%;">ARX </span></strong><span style="font-family:Verdana;font-size:85%;">module). The third-party users will be able to see it but can’t modify the custom entity.</span><br /><span style="font-family:Verdana;font-size:85%;">AutoCAD allows some basic operations over the proxy entity like erase, change layer, change color and transformations. These operations will act basically over its dummy graphical representation (</span><u><span style="font-family:Verdana;font-size:85%;">they will not affect your custom entity’s data except when it is erased</span></u><span style="font-family:Verdana;font-size:85%;">). It is up to the developer to determine the most adequate flags for each custom entity. This is a compiler-time option and it is defined on the custom entity’s class implementation macro (</span><strong><span style="font-family:Verdana;font-size:85%;">ACRX_DXF_DEFINE_MEMBERS</span></strong><span style="font-family:Verdana;font-size:85%;">). This flags can be combined to build a complete configuration. </span><u><span style="font-family:Verdana;font-size:85%;">Please refer to ObjectARX SDK documentation for further information about proxy flags</span></u><span style="font-family:Verdana;font-size:85%;">.</span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-116864837703612725?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-1168648354099497922007-01-12T22:32:00.000-02:002007-01-13T00:48:34.475-02:00Exercise2 - Step4<strong><span style="font-family:Verdana;font-size:85%;">Creating a Custom Entity – Exercise 2 – Step 4</span></strong><br /><br /><span style="font-family:Verdana;font-size:85%;">Now you will learn how to add </span><strong><span style="font-family:Verdana;font-size:85%;">OSNAP </span></strong><span style="font-family:Verdana;font-size:85%;">points to your custom entity. If you run the application before this step you will see that our custom entity already shows some Object Snap points by default (</span><strong><span style="font-family:Verdana;font-size:85%;">ENDPOINT </span></strong><span style="font-family:Verdana;font-size:85%;">and </span><strong><span style="font-family:Verdana;font-size:85%;">MIDPOINT</span></strong><span style="font-family:Verdana;font-size:85%;">). In this example we want to add a </span><strong><span style="font-family:Verdana;font-size:85%;">CENTER </span></strong><span style="font-family:Verdana;font-size:85%;">object snap to our polyline that will allow users to select the exact </span><strong><span style="font-family:Verdana;font-size:85%;">center point</span></strong><span style="font-family:Verdana;font-size:85%;">. To provide this, we need to change the standard behavior of </span><strong><span style="font-family:Verdana;font-size:85%;">getOsnapPoints() </span></strong><span style="font-family:Verdana;font-size:85%;">method. This method has </span><strong><span style="font-family:Verdana;font-size:85%;">4 signatures </span></strong><span style="font-family:Verdana;font-size:85%;">and 2 of them, containing the </span><strong><span style="font-family:Verdana;font-size:85%;">AcGeFastTransform </span></strong><span style="font-family:Verdana;font-size:85%;">parameter, are for future use. We will use the first signature and will handle the </span><strong><span style="font-family:Verdana;font-size:85%;">CENTER </span></strong><span style="font-family:Verdana;font-size:85%;">object snap responding with our center point:</span><br /><br /><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;"></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Acad::ErrorStatus AuPolyline::getOsnapPoints (<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcDb::OsnapMode osnapMode,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">int gsSelectionMark,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const AcGePoint3d &pickPoint,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const AcGePoint3d &lastPoint,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const AcGeMatrix3d &viewXform,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint3dArray &snapPoints,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcDbIntArray &geomIds) const<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">assertReadEnabled () ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">switch(osnapMode)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">case AcDb::kOsModeCen:<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">snapPoints.append(GetPolylineCenter());<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">break;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">return (AcDbPolyline::getOsnapPoints (osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform, snapPoints, geomIds)) ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}</span><br /><span style="font-family:Verdana;font-size:85%;"></span><span style="font-family:Verdana;font-size:85%;">This method receives an Array of points where we need to add the center point whenever the </span><strong><span style="font-family:Verdana;font-size:85%;">OSNAP CENTER </span></strong><span style="font-family:Verdana;font-size:85%;">is requested. On line </span><strong><span style="font-family:Verdana;font-size:85%;">13 </span></strong><span style="font-family:Verdana;font-size:85%;">we handle the </span><strong><span style="font-family:Verdana;font-size:85%;">CENTER </span></strong><span style="font-family:Verdana;font-size:85%;">object snap by adding our </span><strong><span style="font-family:Verdana;font-size:85%;">center point </span></strong><span style="font-family:Verdana;font-size:85%;">to the </span><strong><span style="font-family:Verdana;font-size:85%;">snapPoints </span></strong><span style="font-family:Verdana;font-size:85%;">array (Figure 17). Even handling this particular object snap this method needs to call the polyline class level. The polyline will handle all other possible object snaps for us.</span><br /><br /><a href="http://photos1.blogger.com/x/blogger/6284/765/640/169140/Figure17.jpg"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/854398/Figure17.jpg" border="0" /></a><br /><span style="font-family:Verdana;font-size:85%;">Figure 17 – CENTER object snap.</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><strong><u><span style="font-family:Verdana;font-size:85%;">Note</span></u></strong><span style="font-family:Verdana;font-size:85%;">: </span><em><span style="font-family:Verdana;font-size:85%;">This OSNAP solution handles only simple OSNAP types like CENTER, MIDPOINT and ENDPOINT. Complex OSNAP modes like INTERSECTION require other methods implementations and some additional procedures.</span></em><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-116864835409949792?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-1168648289374721142007-01-12T22:31:00.001-02:002007-01-13T00:48:11.982-02:00Exercise2 - Step3<strong><span style="font-family:Verdana;font-size:85%;">Creating a Custom Entity – Exercise 2 – Step 3</span></strong><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">Now you will learn how to add </span><strong><span style="font-family:Verdana;font-size:85%;">GRIP </span></strong><span style="font-family:Verdana;font-size:85%;">points to your entity. In fact, as the default implementation of </span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline </span></strong><span style="font-family:Verdana;font-size:85%;">forward the call to its base class you may already noted that its GRIP points are </span><u><span style="font-family:Verdana;font-size:85%;">visible and working</span></u><span style="font-family:Verdana;font-size:85%;">. The GRIP point behavior is handled by </span><u><span style="font-family:Verdana;font-size:85%;">two methods</span></u><span style="font-family:Verdana;font-size:85%;">. The first method, called </span><strong><span style="font-family:Verdana;font-size:85%;">getGripPoints() </span></strong><span style="font-family:Verdana;font-size:85%;">is responsible for </span><u><span style="font-family:Verdana;font-size:85%;">acquiring </span></u><span style="font-family:Verdana;font-size:85%;">all GRIP points from your entity. The second, called </span><strong><span style="font-family:Verdana;font-size:85%;">moveGripPointsAt()</span></strong><span style="font-family:Verdana;font-size:85%;">, is responsible for the </span><u><span style="font-family:Verdana;font-size:85%;">action </span></u><span style="font-family:Verdana;font-size:85%;">fired by each grip.</span><br /><span style="font-family:Verdana;font-size:85%;">Each default polyline GRIP action is to move the related vertex. In this example we want to add </span><strong><span style="font-family:Verdana;font-size:85%;">one extra grip </span></strong><span style="font-family:Verdana;font-size:85%;">positioned at our </span><strong><span style="font-family:Verdana;font-size:85%;">polygon’s center</span></strong><span style="font-family:Verdana;font-size:85%;">. To do that we first need to create a helper method to calculate this point. We will walk through all polygon points and will sum the coordinates dividing the result by </span><strong><span style="font-family:Verdana;font-size:85%;">numVerts()</span></strong><span style="font-family:Verdana;font-size:85%;">. This method will not change our entity data so it is recommended to be </span><strong><span style="font-family:Verdana;font-size:85%;">CONST </span></strong><span style="font-family:Verdana;font-size:85%;">and will require only the </span><strong><span style="font-family:Verdana;font-size:85%;">assertReadEnabled() </span></strong><span style="font-family:Verdana;font-size:85%;">call:</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint3d AuPolyline::GetPolylineCenter() const<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">assertReadEnabled();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint3d ptC,pti;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">double cx = 0.0, cy = 0.0, cz = 0.0;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">for (int i=0; i<numVerts(); i++)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">this->getPointAt(i,pti);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">cx += pti[X];<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">cy += pti[Y];<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">cz += pti[Z];<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">cx = cx / numVerts();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">cy = cy / numVerts();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">cz = cz / numVerts();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">ptC.set(cx, cy, cz);<br /></span><span style="color:#3333ff;"><span style="font-family:Lucida Console;font-size:85%;">return ptC;<br /></span><span style="font-family:Lucida Console;font-size:85%;">}</span></span><br /><span style="font-family:Lucida Console;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">Lines </span><strong><span style="font-family:Verdana;font-size:85%;">04-15 </span></strong><span style="font-family:Verdana;font-size:85%;">apply the </span><strong><span style="font-family:Verdana;font-size:85%;">center formula </span></strong><span style="font-family:Verdana;font-size:85%;">and at line </span><strong><span style="font-family:Verdana;font-size:85%;">16 </span></strong><span style="font-family:Verdana;font-size:85%;">we build the point using cx, cy and cz as the point’s X, Y and Z coordinates respectively.</span><br /><span style="font-family:Verdana;font-size:85%;">Next we need to change the default implementation of the both GRIP point methods. First we will redefine the </span><strong><span style="font-family:Verdana;font-size:85%;">getGripPoints() </span></strong><span style="font-family:Verdana;font-size:85%;">method. This method has </span><u><span style="font-family:Verdana;font-size:85%;">2 signatures </span></u><span style="font-family:Verdana;font-size:85%;">and we will use the new </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbGripData </span></strong><span style="font-family:Verdana;font-size:85%;">method instead of the “old style” method.</span><br /><span style="font-family:Verdana;font-size:85%;">This method receives an array of </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbGripData </span></strong><span style="font-family:Verdana;font-size:85%;">pointers. These objects represent the </span><strong><span style="font-family:Verdana;font-size:85%;">GRIP </span></strong><span style="font-family:Verdana;font-size:85%;">point information. We need to inform at least the point and an arbitrary data (</span><strong><span style="font-family:Verdana;font-size:85%;">void*</span></strong><span style="font-family:Verdana;font-size:85%;">). This arbitrary data can be used later to get back information from each </span><strong><span style="font-family:Verdana;font-size:85%;">GRIP </span></strong><span style="font-family:Verdana;font-size:85%;">point allowing the </span><strong><span style="font-family:Verdana;font-size:85%;">moveGripPointsAt() </span></strong><span style="font-family:Verdana;font-size:85%;">method to perform the custom actions:</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Acad::ErrorStatus AuPolyline::getGripPoints (<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcDbGripDataPtrArray &grips,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const double curViewUnitSize,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const int gripSize,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const AcGeVector3d &curViewDir,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const int bitflags) const<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">assertReadEnabled () ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcDbGripData* gpd = new AcDbGripData();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">gpd->setAppData((void*)9999); // Center Grip code<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">gpd->setGripPoint(GetPolylineCenter());<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">grips.append(gpd);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcDbPolyline::getGripPoints (grips, curViewUnitSize, gripSize, curViewDir, bitflags);<br /></span><span style="color:#3333ff;"><span style="font-family:Lucida Console;font-size:85%;">return (Acad::eOk);<br /></span><span style="font-family:Lucida Console;font-size:85%;">}</span></span><br /><span style="font-family:Lucida Console;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">This method will not change our entity’s data so it is also a </span><strong><span style="font-family:Verdana;font-size:85%;">CONST </span></strong><span style="font-family:Verdana;font-size:85%;">method and calls </span><strong><span style="font-family:Verdana;font-size:85%;">assertReadEnabled() </span></strong><span style="font-family:Verdana;font-size:85%;">method. On lines </span><strong><span style="font-family:Verdana;font-size:85%;">09-12 </span></strong><span style="font-family:Verdana;font-size:85%;">we instantiate an </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbGripData </span></strong><span style="font-family:Verdana;font-size:85%;">pointer and set its application data (</span><strong><span style="font-family:Verdana;font-size:85%;">9999 </span></strong><span style="font-family:Verdana;font-size:85%;">in this case) and the grip point which is calculated by the </span><strong><span style="font-family:Verdana;font-size:85%;">GetPolylineCenter() </span></strong><span style="font-family:Verdana;font-size:85%;">method. Next, on line </span><strong><span style="font-family:Verdana;font-size:85%;">13 </span></strong><span style="font-family:Verdana;font-size:85%;">we forward the call to AcDbPolyline’s grip point method so it is able to add </span><u><span style="font-family:Verdana;font-size:85%;">its own GRIP points </span></u><span style="font-family:Verdana;font-size:85%;">at last. These GRIP points are those vertexes points we have mentioned before. The next step is to change the </span><strong><span style="font-family:Verdana;font-size:85%;">moveGripPointsAt() </span></strong><span style="font-family:Verdana;font-size:85%;">method so when the user clicks on this center GRIP it will </span><u><span style="font-family:Verdana;font-size:85%;">reflect a custom action</span></u><span style="font-family:Verdana;font-size:85%;">. In this example, our custom action will </span><strong><span style="font-family:Verdana;font-size:85%;">move the entire polyline</span></strong><span style="font-family:Verdana;font-size:85%;">. The following code shows how to do that:</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Acad::ErrorStatus AuPolyline::moveGripPointsAt (<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const AcDbVoidPtrArray &gripAppData,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const AcGeVector3d &offset,<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">const int bitflags)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">assertWriteEnabled () ;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">for (int g=0; g<gripAppData.length(); g++)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Get grip data back and see if it is our 0 Grip<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">int i = (int)gripAppData.at(g);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// If it is our grip, move the entire entity. If not, forward the call<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">if (i == 9999)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">this->transformBy(offset);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">else<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcDbCurve::moveGripPointsAt (gripAppData, offset, bitflags);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}<br /></span><span style="color:#3333ff;"><span style="font-family:Lucida Console;font-size:85%;">return (Acad::eOk);<br /></span><span style="font-family:Lucida Console;font-size:85%;">}</span></span><br /><span style="font-family:Lucida Console;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">This time, our method cannot be </span><strong><span style="font-family:Verdana;font-size:85%;">CONST </span></strong><span style="font-family:Verdana;font-size:85%;">once we will change our entity’s data. Due that, we need to call </span><strong><span style="font-family:Verdana;font-size:85%;">assertWriteEnabled() </span></strong><span style="font-family:Verdana;font-size:85%;">at it’s beginning. On line </span><strong><span style="font-family:Verdana;font-size:85%;">07 </span></strong><span style="font-family:Verdana;font-size:85%;">we start to inspect the </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbVoidPtrArray </span></strong><span style="font-family:Verdana;font-size:85%;">(an array of </span><strong><span style="font-family:Verdana;font-size:85%;">void*</span></strong><span style="font-family:Verdana;font-size:85%;">) looking for our application data (</span><strong><span style="font-family:Verdana;font-size:85%;">9999</span></strong><span style="font-family:Verdana;font-size:85%;">). This method also receives a </span><strong><span style="font-family:Verdana;font-size:85%;">3D vector </span></strong><span style="font-family:Verdana;font-size:85%;">which represents the transformation being applied to the GRIP. If the GRIP being modified is our </span><strong><span style="font-family:Verdana;font-size:85%;">9999 </span></strong><span style="font-family:Verdana;font-size:85%;">we will apply this vector transformation to the </span><u><span style="font-family:Verdana;font-size:85%;">entire polyline</span></u><span style="font-family:Verdana;font-size:85%;">. This can be done through the </span><strong><span style="font-family:Verdana;font-size:85%;">transformBy() </span></strong><span style="font-family:Verdana;font-size:85%;">method passing the same vector (Figure 16).</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;"><a href="http://photos1.blogger.com/x/blogger/6284/765/640/79041/Figure16.jpg"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/379296/Figure16.jpg" border="0" /></a><br />Figure 16 – Center GRIP in action.</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">If the fired </span><strong><span style="font-family:Verdana;font-size:85%;">GRIP </span></strong><span style="font-family:Verdana;font-size:85%;">is not our </span><strong><span style="font-family:Verdana;font-size:85%;">9999 </span></strong><span style="font-family:Verdana;font-size:85%;">code we will forward the call to </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbCurve </span></strong><span style="font-family:Verdana;font-size:85%;">class (AcDbPolylin’s base class) which will handle it for us. The resulting behavior is when you select a GRIP over the polyline boundary the entity </span><u><span style="font-family:Verdana;font-size:85%;">stretches </span></u><span style="font-family:Verdana;font-size:85%;">and when you select the center GRIP the entity </span><u><span style="font-family:Verdana;font-size:85%;">moves</span></u><span style="font-family:Verdana;font-size:85%;">.</span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-116864828937472114?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com4tag:blogger.com,1999:blog-10425945.post-1168648265636487252007-01-12T22:31:00.000-02:002007-01-13T00:47:45.447-02:00Exercise2 - Step2<span style="color:#000000;"><strong><span style="font-family:Verdana;font-size:85%;">Creating a Custom Entity – Exercise 2 – Step 2</span></strong> </span><br /><span style="color:#000000;"><br /><span style="font-family:Verdana;font-size:85%;">Now after you have created a basic custom entity you will learn how to add custom graphics to it. The custom entity’s graphics is generated primarily by the </span><strong><span style="font-family:Verdana;font-size:85%;">worldDraw() </span></strong><span style="font-family:Verdana;font-size:85%;">method and optionally by the </span><strong><span style="font-family:Verdana;font-size:85%;">viewportDraw() </span></strong><span style="font-family:Verdana;font-size:85%;">method.</span><br /><span style="font-family:Verdana;font-size:85%;">As this entity’s base class already generates a </span><u><span style="font-family:Verdana;font-size:85%;">polyline graphic </span></u><span style="font-family:Verdana;font-size:85%;">we will add some nice extra graphics to it. Each vertex will receive an </span><strong><span style="font-family:Verdana;font-size:85%;">index number and an arrow </span></strong><span style="font-family:Verdana;font-size:85%;">indicating the polyline construction direction (Figure 14). </span><br /><span style="font-family:Verdana;font-size:85%;">We will use different colors for each graphic type. The index number will use the </span><strong><span style="font-family:Verdana;font-size:85%;">256 </span></strong><span style="font-family:Verdana;font-size:85%;">color code which is the </span><strong><span style="font-family:Verdana;font-size:85%;">ByLayer </span></strong><span style="font-family:Verdana;font-size:85%;">color and the arrows will use a fixed </span><strong><span style="font-family:Verdana;font-size:85%;">1 </span></strong><span style="font-family:Verdana;font-size:85%;">color code which is </span><strong><span style="font-family:Verdana;font-size:85%;">red</span></strong><span style="font-family:Verdana;font-size:85%;">. If you change the color of this entity’s layer it will change except on the arrows that will stay red. Further, all arrows will be filled. </span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;"><a href="http://photos1.blogger.com/x/blogger/6284/765/640/744992/Figure14.jpg"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/418219/Figure14.jpg" border="0" /></a><br />Figure 14 – Custom Entity with vertex numbers and arrows</span></span><br /><span style="color:#000000;"><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">To create these graphics you will need to use some trigonometric methods. The following code demonstrates what you can reach this:</span><br /><br /><br /></span><span style="color:#000000;"></span><span style="color:#000000;"></span><p><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">Adesk::Boolean AuPolyline::worldDraw (AcGiWorldDraw *mode)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">assertReadEnabled();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Call base class first<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcDbPolyline::worldDraw(mode);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">double szRef = 5.0;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// ================================================================<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// DIRECTION AND VERTEX NUMBERING<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">int signal = 1;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">double ht2 = szRef/4.0;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">for(int i=0; i<numVerts(); i++)<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint3d pti;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">this->getPointAt(i,pti);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Draw vertex text<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">CString strNum;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">strNum.Format(_T("%d"),i);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint3d ptTxt = pti + (AcGeVector3d::kXAxis*ht2) + (AcGeVector3d::kYAxis*ht2);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">mode->subEntityTraits().setColor(256); // ByLayer<br /></span><span style="color:#3333ff;"><span style="font-family:Lucida Console;font-size:85%;">mode->geometry().text(ptTxt, AcGeVector3d::kZAxis, AcGeVector3d::kXAxis, ht2, 1.0, 0.0, strNum);<br /></span><span style="font-family:Lucida Console;font-size:85%;">/</span></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">/ Arrow direction<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint3d ptj;<br /></span><span style="color:#3333ff;"><span style="font-family:Lucida Console;font-size:85%;">this->getPointAt(i<(numVerts()-1) ? (i+1) : 0, ptj);<br /></span><span style="font-family:Lucida Console;font-size:85%;">A</span></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">cGeVector3d dir = (ptj - pti).normalize();<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Side perpendicular vectors<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGeVector3d perp = dir;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">perp.rotateBy(3.141592/2.0,AcGeVector3d::kZAxis);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint3d pt1 = ptj - (dir*ht2) + (perp*(ht2/4.0));<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint3d pt2 = ptj - (dir*ht2) - (perp*(ht2/4.0));<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">AcGePoint3d pts[3];<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">pts[0] = ptj;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">pts[1] = pt1;<br />p</span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">ts[2] = pt2;<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">// Draw arrow polygon<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">mode->subEntityTraits().setFillType(kAcGiFillAlways);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">mode->subEntityTraits().setColor(1); // red<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">mode->geometry().polygon(3,pts);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">mode->subEntityTraits().setFillType(kAcGiFillNever);<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">}<br /></span><span style="font-family:Lucida Console;font-size:85%;color:#3333ff;">//------ Returning Adesk::kFalse here will force viewportDraw() call<br /></span><span style="color:#3333ff;"><span style="font-family:Lucida Console;font-size:85%;">return (Adesk::kTrue) ;<br /></span><span style="font-family:Lucida Console;font-size:85%;">}</span></span></p><span style="color:#000000;"><span style="font-family:Verdana;font-size:85%;">On line </span><strong><span style="font-family:Verdana;font-size:85%;">03 </span></strong><span style="font-family:Verdana;font-size:85%;">we call the proper assert method which inform what type of access we are executing on this method. As we are not changing any data we need only to </span><strong><span style="font-family:Verdana;font-size:85%;">READ </span></strong><span style="font-family:Verdana;font-size:85%;">the entity so we call </span><strong><span style="font-family:Verdana;font-size:85%;">assertReadEnabled() </span></strong><span style="font-family:Verdana;font-size:85%;">method. On line </span><strong><span style="font-family:Verdana;font-size:85%;">05 </span></strong><span style="font-family:Verdana;font-size:85%;">we forward up the call to its base class method which will draw the polyline curves. On lines </span><strong><span style="font-family:Verdana;font-size:85%;">06-10 </span></strong><span style="font-family:Verdana;font-size:85%;">we initialize some local variables. </span><br /><span style="font-family:Verdana;font-size:85%;">Next, from line </span><strong><span style="font-family:Verdana;font-size:85%;">11-39 </span></strong><span style="font-family:Verdana;font-size:85%;">we perform a loop on each polyline vertex to draw our custom graphics. On lines </span><strong><span style="font-family:Verdana;font-size:85%;">13-14 </span></strong><span style="font-family:Verdana;font-size:85%;">we get the current vertex point. On line range </span><strong><span style="font-family:Verdana;font-size:85%;">16-20 </span></strong><span style="font-family:Verdana;font-size:85%;">we draw the vertex text using the </span><strong><span style="font-family:Verdana;font-size:85%;">text() </span></strong><span style="font-family:Verdana;font-size:85%;">geometry primitive at a point with a small displacement related to the vertex point. On lines </span><strong><span style="font-family:Verdana;font-size:85%;">22-24 </span></strong><span style="font-family:Verdana;font-size:85%;">we calculate the end point (</span><strong><span style="font-family:Verdana;font-size:85%;">ptj</span></strong><span style="font-family:Verdana;font-size:85%;">) of each polyline segment and its unitary direction vector (</span><strong><span style="font-family:Verdana;font-size:85%;">dir</span></strong><span style="font-family:Verdana;font-size:85%;">). Next, on lines </span><strong><span style="font-family:Verdana;font-size:85%;">26-33 </span></strong><span style="font-family:Verdana;font-size:85%;">we calculate the </span><u><span style="font-family:Verdana;font-size:85%;">3 points </span></u><span style="font-family:Verdana;font-size:85%;">which will build an arrow head graphic. The </span><strong><span style="font-family:Verdana;font-size:85%;">perp </span></strong><span style="font-family:Verdana;font-size:85%;">vector will allow us to draw each side of the arrow head according to the Figure 15. On lines </span><strong><span style="font-family:Verdana;font-size:85%;">35-38 </span></strong><span style="font-family:Verdana;font-size:85%;">we draw the filled arrow head using the </span><strong><span style="font-family:Verdana;font-size:85%;">polygon() </span></strong><span style="font-family:Verdana;font-size:85%;">primitive with </span><strong><span style="font-family:Verdana;font-size:85%;">color red </span></strong><span style="font-family:Verdana;font-size:85%;">and with the fill type always.</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">Finally, on line </span><strong><span style="font-family:Verdana;font-size:85%;">41</span></strong><span style="font-family:Verdana;font-size:85%;">, we return </span><strong><span style="font-family:Verdana;font-size:85%;">Adesk::kTrue </span></strong><span style="font-family:Verdana;font-size:85%;">to avoid the graphics to be made by the </span><strong><span style="font-family:Verdana;font-size:85%;">viewportDraw() </span></strong><span style="font-family:Verdana;font-size:85%;">method.</span><br /><span style="font-family:Verdana;font-size:85%;">These classes we have used, with </span><strong><span style="font-family:Verdana;font-size:85%;">AcGe </span></strong><span style="font-family:Verdana;font-size:85%;">prefix, are part of the AcGe library which contains several </span><u><span style="font-family:Verdana;font-size:85%;">utility classes and methods </span></u><span style="font-family:Verdana;font-size:85%;">to help us to deal with </span><strong><span style="font-family:Verdana;font-size:85%;">geometric calculations</span></strong><span style="font-family:Verdana;font-size:85%;">. This really helps a lot once most of these calculations are a little bit complex.</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;"></span><a href="http://photos1.blogger.com/x/blogger/6284/765/640/233570/Figure15.jpg"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/236941/Figure15.jpg" border="0" /></a><br /><span style="font-family:Verdana;font-size:85%;">Figure 15 – AuPolyline side graphics.</span></span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-116864826563648725?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com2tag:blogger.com,1999:blog-10425945.post-1168648229869560762007-01-12T22:30:00.000-02:002007-01-13T00:45:06.456-02:00Exercise2 - Step1<strong><span style="font-family:Verdana;font-size:85%;color:#000099;">Hello,</span></strong><br /><strong><span style="font-family:Verdana;font-size:85%;color:#000099;"></span></strong><br /><strong><span style="font-family:Verdana;font-size:85%;color:#000099;">I will post a sequence of 6 steps of my Exercise 2 provided at last year's AU. It will show you how to create a custom entity inside AutoCAD 2007 using ObjectARX 2007 and Visual Studio 2005.</span></strong><br /><strong><span style="font-family:Verdana;font-size:85%;color:#000099;"></span></strong><br /><strong><span style="font-family:Verdana;font-size:85%;color:#000099;">Hope you enjoy these posts!</span></strong><br /><span style="color:#000000;"><strong><span style="font-family:Verdana;font-size:85%;"></span></strong></span><br /><span style="color:#000000;"><strong><span style="font-family:Verdana;font-size:85%;">Creating a Custom Entity – Exercise 2 – Step 1</span></strong> </span><br /><span style="color:#000000;"><br /><span style="font-family:Verdana;font-size:85%;">You will learn in this exercise how to create a </span><strong><span style="font-family:Verdana;font-size:85%;">simple custom entity</span></strong><span style="font-family:Verdana;font-size:85%;">. I will keep it simple as much as I can to reinforce the basic concepts involved. On the next steps we will improve this custom entity by adding great features step by step.</span><br /><span style="font-family:Verdana;font-size:85%;">The first step is to name our entity and choose from which base class it will derive. Remember we have to split our application into two modules, an </span><strong><span style="font-family:Verdana;font-size:85%;">ARX </span></strong><span style="font-family:Verdana;font-size:85%;">(user interfaces) and a </span><strong><span style="font-family:Verdana;font-size:85%;">DBX </span></strong><span style="font-family:Verdana;font-size:85%;">(the custom entity class itself). These two projects will be placed into the same Visual Studio Solution and the </span><u><span style="font-family:Verdana;font-size:85%;">ARX module will depend on DBX module</span></u><span style="font-family:Verdana;font-size:85%;">. The names will be:</span><br /><br /><br /><br /><br /><br /></span><span style="color:#000000;"></span><span style="color:#000000;"></span><span style="color:#000000;"></span><span style="color:#000000;"></span><ul><li><span style="color:#000000;"><strong><u><span style="font-family:Verdana;font-size:85%;">Solution</span></u></strong><span style="font-family:Verdana;font-size:85%;">: </span><strong><span style="font-family:Verdana;font-size:85%;">Exercise2 </span></strong><span style="font-family:Verdana;font-size:85%;">(Visual Studio will create a </span><strong><em><span style="font-family:Verdana;font-size:85%;">Exercise2.sln </span></em></strong><span style="font-family:Verdana;font-size:85%;">file);</span></span></li><br /><li><span style="color:#000000;"><strong><u><span style="font-family:Verdana;font-size:85%;">DBX Project</span></u></strong><span style="font-family:Verdana;font-size:85%;">: </span><strong><span style="font-family:Verdana;font-size:85%;">AuCustomObjects </span></strong><span style="font-family:Verdana;font-size:85%;">(Visual Studio will create a </span><strong><em><span style="font-family:Verdana;font-size:85%;">AuCustomObjects.vcproj </span></em></strong><span style="font-family:Verdana;font-size:85%;">file);</span></span></li><br /><li><span style="color:#000000;"><strong><u><span style="font-family:Verdana;font-size:85%;">ARX Project</span></u></strong><span style="font-family:Verdana;font-size:85%;">: </span><strong><span style="font-family:Verdana;font-size:85%;">AuUserInterface </span></strong><span style="font-family:Verdana;font-size:85%;">(Visual Studio will create a </span><strong><em><span style="font-family:Verdana;font-size:85%;">AuUserInterface.vcproj </span></em></strong><span style="font-family:Verdana;font-size:85%;">file);</span></span></li></ul><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="color:#000000;"><span style="font-family:Verdana;font-size:85%;">Open Visual Studio, go to the menu </span><strong><span style="font-family:Verdana;font-size:85%;">File </span></strong><span style="font-family:Verdana;font-size:85%;">> </span><strong><span style="font-family:Verdana;font-size:85%;">New Project… </span></strong><span style="font-family:Verdana;font-size:85%;">Open “</span><strong><span style="font-family:Verdana;font-size:85%;">Other Project Types</span></strong><span style="font-family:Verdana;font-size:85%;">” node, click on “</span><strong><span style="font-family:Verdana;font-size:85%;">Visual Studio Solutions</span></strong><span style="font-family:Verdana;font-size:85%;">” item. It will show a template called “</span><strong><span style="font-family:Verdana;font-size:85%;">Blank Solution</span></strong><span style="font-family:Verdana;font-size:85%;">”. Choose this template and name it as </span><strong><span style="font-family:Verdana;font-size:85%;">Exercise2 </span></strong><span style="font-family:Verdana;font-size:85%;">(the location can be any folder you want). Click </span><strong><span style="font-family:Verdana;font-size:85%;">OK </span></strong><span style="font-family:Verdana;font-size:85%;">to proceed (Figure 8).</span><br /><span style="font-family:Verdana;font-size:85%;">Next, right click the solution icon; select </span><strong><span style="font-family:Verdana;font-size:85%;">Add </span></strong><span style="font-family:Verdana;font-size:85%;">and then </span><strong><span style="font-family:Verdana;font-size:85%;">New Project…</span></strong><span style="font-family:Verdana;font-size:85%;">, (Figure 9). The dialog, presented on </span><strong><span style="font-family:Verdana;font-size:85%;">Exercise1 </span></strong><span style="font-family:Verdana;font-size:85%;">will appear. Select on the list the </span><strong><span style="font-family:Verdana;font-size:85%;">ObjectARX </span></strong><span style="font-family:Verdana;font-size:85%;">template and create both </span><strong><span style="font-family:Verdana;font-size:85%;">AuUserInterface </span></strong><span style="font-family:Verdana;font-size:85%;">and </span><strong><span style="font-family:Verdana;font-size:85%;">AuCustomObjects </span></strong><span style="font-family:Verdana;font-size:85%;">modules. </span><u><span style="font-family:Verdana;font-size:85%;">Remember to choose ARX or DBX project type accordingly</span></u><span style="font-family:Verdana;font-size:85%;">.</span><br /><br /><br /><br /><br /></span><span style="color:#000000;"></span><span style="color:#000000;"></span><span style="color:#000000;"></span><span style="color:#000000;"></span><p></p><p><span style="color:#000000;"></span></p><p><span style="color:#000000;"></span></p><p><span style="color:#000000;"></span></p><a href="http://photos1.blogger.com/x/blogger/6284/765/640/457511/Figure8.jpg"></a><p><a href="http://photos1.blogger.com/x/blogger/6284/765/640/457511/Figure8.jpg"><span style="color:#000000;"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/251837/Figure8.jpg" border="0" /></span></a><span style="color:#000000;"><br /><span style="font-family:Verdana;font-size:85%;">Figure 8 – Blank Solution project</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">Each project location will be created inside the existing solution by default. </span><u><span style="font-family:Verdana;font-size:85%;">Don’t change this location</span></u><span style="font-family:Verdana;font-size:85%;">.</span><br /><span style="font-family:Verdana;font-size:85%;">Enable </span><strong><span style="font-family:Verdana;font-size:85%;">MFC </span></strong><span style="font-family:Verdana;font-size:85%;">option on both projects (don’t need to enable AutoCAD MFC extensions) Enable </span><strong><span style="font-family:Verdana;font-size:85%;">_DEBUG </span></strong><span style="font-family:Verdana;font-size:85%;">symbol too. Don’t enable any </span><strong><span style="font-family:Verdana;font-size:85%;">COM </span></strong><span style="font-family:Verdana;font-size:85%;">or </span><strong><span style="font-family:Verdana;font-size:85%;">.NET </span></strong><span style="font-family:Verdana;font-size:85%;">feature in both projects.</span><br /><span style="font-family:Verdana;font-size:85%;">Make </span><strong><span style="font-family:Verdana;font-size:85%;">AuUserInterface </span></strong><span style="font-family:Verdana;font-size:85%;">project depend on </span><strong><span style="font-family:Verdana;font-size:85%;">AuCustomObjects</span></strong><span style="font-family:Verdana;font-size:85%;">. To do that, </span><strong><span style="font-family:Verdana;font-size:85%;">right click </span></strong><span style="font-family:Verdana;font-size:85%;">project AuUserInterface and select </span><strong><span style="font-family:Verdana;font-size:85%;">Dependencies… </span></strong><span style="font-family:Verdana;font-size:85%;">Then mark AuCustomObjects project on the list. Click </span><strong><span style="font-family:Verdana;font-size:85%;">OK</span></strong><span style="font-family:Verdana;font-size:85%;">. </span></span></p><p><a href="http://photos1.blogger.com/x/blogger/6284/765/640/316528/Figure9.jpg"><span style="color:#000000;"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/816891/Figure9.jpg" border="0" /></span></a><span style="color:#000000;"><br /><span style="font-family:Verdana;font-size:85%;">Figure 9 – Creating solution’s projects</span> </span></p><p><span style="color:#000000;"><strong><span style="font-family:Verdana;font-size:85%;">Right click </span></strong><span style="font-family:Verdana;font-size:85%;">project </span><strong><span style="font-family:Verdana;font-size:85%;">AuUserInterface </span></strong><span style="font-family:Verdana;font-size:85%;">again and select “</span><strong><span style="font-family:Verdana;font-size:85%;">Set as Startup Project</span></strong><span style="font-family:Verdana;font-size:85%;">” (it will turn to </span><strong><span style="font-family:Verdana;font-size:85%;">bold</span></strong><span style="font-family:Verdana;font-size:85%;">). Now test your solution building it: go to menu </span><strong><span style="font-family:Verdana;font-size:85%;">Build </span></strong><span style="font-family:Verdana;font-size:85%;">> </span><strong><span style="font-family:Verdana;font-size:85%;">Build Solution</span></strong><span style="font-family:Verdana;font-size:85%;">. You should get 2 Builds with 0 errors and (1+3) warnings that are safe to ignore.</span><br /><span style="font-family:Verdana;font-size:85%;">The final test at this stage is to load the application inside AutoCAD. Remember our project AuUserInterface </span><u><span style="font-family:Verdana;font-size:85%;">depends on </span></u><span style="font-family:Verdana;font-size:85%;">AuCustomObjects so the </span><u><span style="font-family:Verdana;font-size:85%;">DBX module needs to be loaded first </span></u><span style="font-family:Verdana;font-size:85%;">than the ARX module. The </span><u><span style="font-family:Verdana;font-size:85%;">unload process must be done in reverse order</span></u><span style="font-family:Verdana;font-size:85%;">, AuUserInterface first and then AuCustomObjects. You should get everything working this way.</span><br /><strong><u><span style="font-family:Verdana;font-size:85%;">Note</span></u></strong><span style="font-family:Verdana;font-size:85%;">: </span><em><span style="font-family:Verdana;font-size:85%;">Depending on which type of build you made (</span></em><strong><em><span style="font-family:Verdana;font-size:85%;">Debug </span></em></strong><em><span style="font-family:Verdana;font-size:85%;">or </span></em><strong><em><span style="font-family:Verdana;font-size:85%;">Release</span></em></strong><em><span style="font-family:Verdana;font-size:85%;">) it is recommended to load both projects with the same compilation type.</span></em><br /><span style="font-family:Verdana;font-size:85%;">Now we have our </span><strong><span style="font-family:Verdana;font-size:85%;">DBX </span></strong><span style="font-family:Verdana;font-size:85%;">and </span><strong><span style="font-family:Verdana;font-size:85%;">ARX </span></strong><span style="font-family:Verdana;font-size:85%;">module it is time to add our custom entity’s class. In this example, our entity will be derived from </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbPolyline </span></strong><span style="font-family:Verdana;font-size:85%;">which represents the AutoCAD </span><strong><span style="font-family:Verdana;font-size:85%;">POLYLINE </span></strong><span style="font-family:Verdana;font-size:85%;">entity. The reason for this option is that our custom entity will behave almost exactly like a polyline but it will add some </span><u><span style="font-family:Verdana;font-size:85%;">extra features </span></u><span style="font-family:Verdana;font-size:85%;">like vertex numbers, direction symbols, hatch, etc. To add this custom class we will use the </span><strong><span style="font-family:Verdana;font-size:85%;">Autodesk Class Explorer </span></strong><span style="font-family:Verdana;font-size:85%;">tool which is located at ARXWizard’s toolbar. It is the second button like the Firgure 10 shows.</span><br /><span style="font-family:Verdana;font-size:85%;"></span></span></p><p><span style="font-family:Verdana;font-size:85%;color:#000000;"><a href="http://photos1.blogger.com/x/blogger/6284/765/640/797512/Figura10.jpg"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/256278/Figura10.jpg" border="0" /></a></span><span style="color:#000000;"><span style="font-family:Verdana;font-size:85%;"><br />Figure 10 – ARXWizard toolbar</span><br /><span style="font-family:Verdana;font-size:85%;"></span></span></p><p><span style="color:#000000;"><span style="font-family:Verdana;font-size:85%;">Once you click on this button a dialog bar will appear allowing you to explore all existing classes into your projects. At this time, there are no custom entity classes available. Select our </span><strong><span style="font-family:Verdana;font-size:85%;">DBX </span></strong><span style="font-family:Verdana;font-size:85%;">module and then </span><strong><span style="font-family:Verdana;font-size:85%;">right click </span></strong><span style="font-family:Verdana;font-size:85%;">on it. A pop-up menu will be displayed. Select the “</span><strong><span style="font-family:Verdana;font-size:85%;">Add an ObjectDBX Custom Object</span></strong><span style="font-family:Verdana;font-size:85%;">” option (Figure 11).</span> </span></p><p><a href="http://photos1.blogger.com/x/blogger/6284/765/640/431536/Figure11.jpg"><span style="color:#000000;"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/699753/Figure11.jpg" border="0" /></span></a><span style="color:#000000;"><br /><span style="font-family:Verdana;font-size:85%;">Figure 11 – Autodesk Class Explorer</span><br /><span style="font-family:Verdana;font-size:85%;"></span></span></p><p><span style="color:#000000;"><span style="font-family:Verdana;font-size:85%;">This wizard has </span><strong><span style="font-family:Verdana;font-size:85%;">3 steps</span></strong><span style="font-family:Verdana;font-size:85%;">. The first step, called </span><strong><span style="font-family:Verdana;font-size:85%;">Names </span></strong><span style="font-family:Verdana;font-size:85%;">(Figure 12), allows you to specify all basic custom entity’s features. First, name it as “</span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline</span></strong><span style="font-family:Verdana;font-size:85%;">”. Choose as base class the </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbPolyline </span></strong><span style="font-family:Verdana;font-size:85%;">class (note you have several other classes available to derive from). Remaining fields will be filled automatically. Press </span><strong><span style="font-family:Verdana;font-size:85%;">Next</span></strong><span style="font-family:Verdana;font-size:85%;">.</span><br /><span style="font-family:Verdana;font-size:85%;">Once you select the polyline as your base class you are saying that your custom entity will behave like a polyline except where you redefine it. This is done through the virtual methods I have mentioned before.</span><br /><span style="font-family:Verdana;font-size:85%;"></span></span></p><p><a href="http://photos1.blogger.com/x/blogger/6284/765/640/193624/Figure12.jpg"><span style="color:#000000;"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/488471/Figure12.jpg" border="0" /></span></a><span style="color:#000000;"><br /><span style="font-family:Verdana;font-size:85%;">Figure 12 – Custom Object Wizard - Names</span> </span></p><p><span style="color:#000000;"><span style="font-family:Verdana;font-size:85%;">The </span><strong><span style="font-family:Verdana;font-size:85%;">Custom Object Wizard </span></strong><span style="font-family:Verdana;font-size:85%;">also will help you to implement </span><u><span style="font-family:Verdana;font-size:85%;">basic class features</span></u><span style="font-family:Verdana;font-size:85%;">. This is done on the second step of this Wizard, called </span><strong><span style="font-family:Verdana;font-size:85%;">Protocols</span></strong><span style="font-family:Verdana;font-size:85%;">. Enabling these options will instruct the wizard to add the related virtual methods simplifying the class creation process for you.</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;">Inside this dialog you can specify if your entity participate on </span><strong><span style="font-family:Verdana;font-size:85%;">DWG/DWF </span></strong><span style="font-family:Verdana;font-size:85%;">protocols, if your entity implements </span><strong><span style="font-family:Verdana;font-size:85%;">OSNAP </span></strong><span style="font-family:Verdana;font-size:85%;">points, </span><strong><span style="font-family:Verdana;font-size:85%;">GRIP </span></strong><span style="font-family:Verdana;font-size:85%;">points and </span><strong><span style="font-family:Verdana;font-size:85%;">viewport </span></strong><span style="font-family:Verdana;font-size:85%;">dependent graphics and, at last, if it implements curve protocols. In this example we will enable only </span><strong><span style="font-family:Verdana;font-size:85%;">DWG protocol </span></strong><span style="font-family:Verdana;font-size:85%;">and all 3 AcDbEntity protocols which will allow us to implement some basic features (Figure 13).</span><br /><span style="font-family:Verdana;font-size:85%;">The third step, called </span><strong><span style="font-family:Verdana;font-size:85%;">Advanced</span></strong><span style="font-family:Verdana;font-size:85%;">, will allow you to add notification and cloning features to your custom entity. In this example we will not use these features. There are many other features you can redefine through a huge set of virtual methods but to keep this example simple we will only implement these ones.</span><br /><span style="font-family:Verdana;font-size:85%;">Click </span><strong><span style="font-family:Verdana;font-size:85%;">Finish </span></strong><span style="font-family:Verdana;font-size:85%;">to create your Custom Entity’s Class. Remember, it will be placed at you </span><strong><span style="font-family:Verdana;font-size:85%;">DBX </span></strong><span style="font-family:Verdana;font-size:85%;">module.</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><span style="font-family:Verdana;font-size:85%;"></span></span><a href="http://photos1.blogger.com/x/blogger/6284/765/640/821748/Figure13.jpg"><span style="color:#000000;"><img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/6284/765/320/43717/Figure13.jpg" border="0" /></span></a><br /><span style="color:#000000;"><span style="font-family:Verdana;font-size:85%;">Figure 13 – Custom Object Wizard - Protocols</span> </span></p><p><span style="color:#000000;"><span style="font-family:Verdana;font-size:85%;">The Custom Entity Wizard will create default virtual methods but, in this particular case, our base class </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbPolyline </span></strong><span style="font-family:Verdana;font-size:85%;">does not support all of these methods signatures. If you compile the solution you will get </span><u><span style="font-family:Verdana;font-size:85%;">4 error messages </span></u><span style="font-family:Verdana;font-size:85%;">exactly due that. For now, we will replace the explicit </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbPolyline:: </span></strong><span style="font-family:Verdana;font-size:85%;">prefix on these 4 return calls by </span><strong><span style="font-family:Verdana;font-size:85%;">AcDbCurve:: </span></strong><span style="font-family:Verdana;font-size:85%;">prefix which is the AcDbPolyline base class. Now you should get no errors.</span><br /><span style="font-family:Verdana;font-size:85%;">If you inspect your projects Solution Explorer you will note two new files: </span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline.h </span></strong><span style="font-family:Verdana;font-size:85%;">and </span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline.cpp</span></strong><span style="font-family:Verdana;font-size:85%;">. These files, inside your </span><strong><span style="font-family:Verdana;font-size:85%;">DBX </span></strong><span style="font-family:Verdana;font-size:85%;">module, are responsible to declare and implement your custom entity. Open these two files and walk through the generated code.</span><br /><span style="font-family:Verdana;font-size:85%;">Now you need to add a new command, inside your </span><strong><span style="font-family:Verdana;font-size:85%;">ARX </span></strong><span style="font-family:Verdana;font-size:85%;">module, to create an instance of your new custom entity. To do that, on the </span><strong><span style="font-family:Verdana;font-size:85%;">Solution Explorer</span></strong><span style="font-family:Verdana;font-size:85%;">, right click the </span><strong><span style="font-family:Verdana;font-size:85%;">AuUserInterface </span></strong><span style="font-family:Verdana;font-size:85%;">project and click “</span><strong><span style="font-family:Verdana;font-size:85%;">Set as Startup Project</span></strong><span style="font-family:Verdana;font-size:85%;">” (project name will turn to bold). Now, click on the first icon of </span><strong><span style="font-family:Verdana;font-size:85%;">ARXWizard </span></strong><span style="font-family:Verdana;font-size:85%;">toolbar (a icon with “</span><strong><span style="font-family:Verdana;font-size:85%;">a></span></strong><span style="font-family:Verdana;font-size:85%;">” text). This button will open the “</span><strong><span style="font-family:Verdana;font-size:85%;">ObjectARX Commands</span></strong><span style="font-family:Verdana;font-size:85%;">” dialog box. It has two command lists. </span><strong><span style="font-family:Verdana;font-size:85%;">Right click </span></strong><span style="font-family:Verdana;font-size:85%;">the first list and select </span><strong><span style="font-family:Verdana;font-size:85%;">New</span></strong><span style="font-family:Verdana;font-size:85%;">. A new line will be added to this list with a default command called “</span><strong><span style="font-family:Verdana;font-size:85%;">MyCommand1</span></strong><span style="font-family:Verdana;font-size:85%;">”. Click </span><strong><span style="font-family:Verdana;font-size:85%;">OK</span></strong><span style="font-family:Verdana;font-size:85%;">.</span><br /><span style="font-family:Verdana;font-size:85%;">If you open the </span><strong><span style="font-family:Verdana;font-size:85%;">acrxEntryPoint.cpp </span></strong><span style="font-family:Verdana;font-size:85%;">file of </span><strong><span style="font-family:Verdana;font-size:85%;">AuUserInterface </span></strong><span style="font-family:Verdana;font-size:85%;">project you will find, inside class </span><strong><span style="font-family:Verdana;font-size:85%;">CAuUserInterfaceApp</span></strong><span style="font-family:Verdana;font-size:85%;">, the </span><strong><span style="font-family:Verdana;font-size:85%;">AuUserInterface_MyCommand1() </span></strong><span style="font-family:Verdana;font-size:85%;">empty method which will be called when you fire </span><strong><span style="font-family:Verdana;font-size:85%;">MYCOMMAND1 </span></strong><span style="font-family:Verdana;font-size:85%;">command inside AutoCAD. Inside this method you will create an instance of your </span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline </span></strong><span style="font-family:Verdana;font-size:85%;">entity.</span><br /><span style="font-family:Verdana;font-size:85%;">Remember that your custom entity class implementation is located into the </span><strong><span style="font-family:Verdana;font-size:85%;">DBX </span></strong><span style="font-family:Verdana;font-size:85%;">project. Due that you will need to add (through </span><strong><span style="font-family:Verdana;font-size:85%;">#include </span></strong><span style="font-family:Verdana;font-size:85%;">compiler instruction) a reference to the </span><strong><span style="font-family:Verdana;font-size:85%;">AuPolyline </span></strong><span style="font-family:Verdana;font-size:85%;">class declaration file. To do that, add the following compiler instruction at the beginning of </span><strong><span style="font-family:Verdana;font-size:85%;">acrxEntryPoint.cpp </span></strong><span style="font-family:Verdana;font-size:85%;">file of your ARX module right after </span><strong><span style="font-family:Verdana;font-size:85%;">#include "resource.h" </span></strong><span style="font-family:Verdana;font-size:85%;">line:</span><br /><span style="font-family:Verdana;font-size:85%;"></span><br /><strong><span style="font-family:Lucida Console;font-size:85%;">#include "..\AuCustomObjects\AuPolyline.h"</span></strong><br /><span style="font-family:Verdana;font-size:85%;">The “</span><strong><span style="font-family:Verdana;font-size:85%;">..\</span></strong><span style="font-family:Verdana;font-size:85%;">” part of this include path goes up one folder level (getting back to the Solution’s root folder) and then goes into the </span><strong><span style="font-family:Verdana;font-size:85%;">DBX </span></strong><span style="font-family:Verdana;font-size:85%;">project folder. Now you can compile your project and shouldn’t get any errors. Next, open AutoCAD, </span><u><span style="font-family:Verdana;font-size:85%;">load first the DBX module and then the ARX module </span></u><span style="font-family:Verdana;font-size:85%;">(there will be two text messages at AutoCAD command prompt confirming that the both load processes were succeeded. Type your project’s command “</span><strong><span style="font-family:Verdana;font-size:85%;">MYCOMMAND1</span></strong><span style="font-family:Verdana;font-size:85%;">” and run a </span><strong><span style="font-family:Verdana;font-size:85%;">ZOOM EXTENTS </span></strong><span style="font-family:Verdana;font-size:85%;">command to see the generated entity. If you also run the </span><strong><span style="font-family:Verdana;font-size:85%;">LIST </span></strong><span style="font-family:Verdana;font-size:85%;">command and select this entity you will see its detailed information.</span><br /><span style="font-family:Verdana;font-size:85%;">The following code will create a </span><strong><span style="font-family:Verdana;font-size:85%;">10 sided polyline </span></strong><span style="font-family:Verdana;font-size:85%;">(closed) and will add it to the </span><strong><span style="font-family:Verdana;font-size:85%;">Model Space </span></strong><span style="font-family:Verdana;font-size:85%;">Block Table Record.</span></span><br /></p><p><span style="font-family:courier new;font-size:85%;color:#3333ff;">// - AuUserInterface._MyCommand1 command (do not rename)<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">static void AuUserInterface_MyCommand1(void)<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">{<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">// AuPolyline entity<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">AuPolyline* pL = new AuPolyline();<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">int nSides = 10;<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">double incAngle = 2*3.141592 / nSides;<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">// Add vertex list<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">for (int i=0; i<nSides; i++)<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">pL->addVertexAt(i,AcGePoint2d(10*cos(i*incAngle),10*sin(i*incAngle)));<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">// Set Polyline as closed<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">pL->setClosed(Adesk::kTrue);<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">// open the proper entity container<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">AcDbBlockTable* pBT = NULL;<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">AcDbDatabase* pDB = acdbHostApplicationServices()->workingDatabase();<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">pDB->getSymbolTable(pBT,AcDb::kForRead);<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">AcDbBlockTableRecord* pBTR = NULL;<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">pBT->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite);<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">pBT->close();<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">// now, add the entity to container<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">AcDbObjectId Id;<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">pBTR->appendAcDbEntity(Id, pL);<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">pBTR->close();<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">pL->close();<br /></span><span style="font-family:courier new;font-size:85%;color:#3333ff;">}</span></p><span style="color:#000000;"><span style="font-family:Verdana;font-size:85%;">On lines </span><strong><span style="font-family:Verdana;font-size:85%;">05-07 </span></strong><span style="font-family:Verdana;font-size:85%;">we instantiate the entity and initialize some local variables. Next, on lines </span><strong><span style="font-family:Verdana;font-size:85%;">9-10 </span></strong><span style="font-family:Verdana;font-size:85%;">we add a list of vertexes to the entity. Line </span><strong><span style="font-family:Verdana;font-size:85%;">12 </span></strong><span style="font-family:Verdana;font-size:85%;">set the polyline as closed. On lines </span><strong><span style="font-family:Verdana;font-size:85%;">14-19 </span></strong><span style="font-family:Verdana;font-size:85%;">we open the AutoCAD database, open the </span><strong><span style="font-family:Verdana;font-size:85%;">Block Table </span></strong><span style="font-family:Verdana;font-size:85%;">container and then get the </span><strong><span style="font-family:Verdana;font-size:85%;">Model Space </span></strong><span style="font-family:Verdana;font-size:85%;">container. On lines </span><strong><span style="font-family:Verdana;font-size:85%;">21-24 </span></strong><span style="font-family:Verdana;font-size:85%;">we add our entity do Model Space and then close it and the entity itself.</span><br /><strong><u><span style="font-family:Verdana;font-size:85%;">Note</span></u></strong><span style="font-family:Verdana;font-size:85%;">: </span><em><span style="font-family:Verdana;font-size:85%;">You cannot delete the entity’s pointer once it is added to AutoCAD database. In this case its management is delegated to AutoCAD and you only need to call the close() method. If you delete this pointer you will cause AutoCAD to crash.</span></em></span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-116864822986956076?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-1166180178831015952006-12-15T08:36:00.000-02:002007-01-08T12:11:26.153-02:00Hello,<br /><br />I'm sure you probably have faced a situation where you perform some <strong>heavy calculations</strong> inside AutoCAD with or without a dialog running. In these cases AutoCAD <strong>may look frozen</strong> and this may look strange to the user because it may think AutoCAD has really frozen and then the user may <strong>try to close it</strong>.<br /><br />Even if you use a progress bar like AutoCAD status bar if you change the current window and get back to AutoCAD it may look frozen in black/white colors.<br /><br />This occurs because the processor focus all its resources into your heavy loop and does not save enough time to both <strong>AutoCAD and your dialog process its own messages</strong>. These messages will affect several things like, for instance, the dialog graphics update.<br /><br />The below function will let AutoCAD do this and you may call it from inside your loop (maybe a <strong>FOR</strong> or <strong>WHILE</strong> heavy statements). This way, on each interaction, this function will let AutoCAD process its messages.<br /><br /><span style="font-family:courier new;color:#000099;">void PumpAcadMessages() </span><br /><span style="font-family:courier new;color:#000099;">{ </span><br /><span style="font-family:courier new;color:#000099;"><span style="color:#009900;"> // Get AutoCAD application</span> </span><br /><span style="font-family:courier new;color:#000099;"> CWinApp* app = acedGetAcadWinApp(); </span><br /><span style="font-family:courier new;color:#000099;"><span style="color:#009900;"> // Get Main window</span> </span><br /><span style="font-family:courier new;color:#000099;"> CWnd* wnd = app->GetMainWnd();<br /><span style="color:#009900;"> // dispatch incoming sent messages</span> </span><br /><span style="font-family:courier new;color:#000099;"> MSG msg; </span><br /><span style="font-family:courier new;color:#000099;"> while (::PeekMessage (&msg, wnd->m_hWnd, 0, 0, PM_NOREMOVE)) </span><br /><span style="font-family:courier new;color:#000099;"> { </span><br /><span style="font-family:courier new;color:#000099;"><span style="color:#009900;"> // if can't pump, break</span> </span><br /><span style="font-family:courier new;color:#000099;"> if (!app->PumpMessage()) </span><br /><span style="font-family:courier new;color:#000099;"> { </span><br /><span style="font-family:courier new;color:#000099;"> ::PostQuitMessage(0); </span><br /><span style="font-family:courier new;color:#000099;"> break; </span><br /><span style="font-family:courier new;color:#000099;"> } </span><br /><span style="font-family:courier new;color:#000099;"> } </span><br /><span style="font-family:courier new;color:#000099;"> LONG lIdle = 0; </span><br /><span style="font-family:courier new;color:#000099;"><span style="color:#009900;"> // Now it's time to MFC do the work</span> </span><br /><span style="font-family:courier new;color:#000099;"> while (app->OnIdle(lIdle++));</span><br /><span style="font-family:courier new;color:#000099;">}</span><br /><br />If you also would like to process your dialog messages you just need to change the first two lines and use your dialog's CWnd pointer instead of AutoCAD window's pointer.<br /><br />Cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-116618017883101595?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com4tag:blogger.com,1999:blog-10425945.post-1166124788701949242006-12-14T17:28:00.000-02:002006-12-14T17:33:09.073-02:00AU2006 was fantastic!Hello,<br /><br />Au2006 was amazing. There were almost <strong>7500</strong> people this year and several classes were provided.<br />If you would like to check those classes visit <strong>AU Online</strong> at: <a href="http://www.autodesk.com/auonline">http://www.autodesk.com/auonline</a><br /><br />I will post some content of my class but I need first to reorganize its topics and pictures.<br />Stay tuned.<br /><br />Cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-116612478870194924?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-1154976179635728722006-08-07T15:37:00.000-03:002006-09-14T08:56:01.046-03:00AU 2006Hello,<br /><br />Autodesk University 2006 registration is now open!<br /><br /><a href="http://www.autodeskevents.com/au2006">AU 2006</a><br /><br />I'm glad to inform you that this year I have been accepted as Speaker. My 1,5 hour class will be about Custom Entities. Class code is CP33-3 and more information can be found here:<br /><br /><a href="http://www.autodeskevents.com/au2006/index.cfm?site=design&mainsite=client.detail&eventID=2542&eschedulerID=721&eventoptionID=33092&optiontimeID=35270">The Power of ObjectARX(R) - CP33-3</a><br /><br />Hope to meet you in Las Vegas!<br />Regards,<br />Fernando.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-115497617963572872?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0tag:blogger.com,1999:blog-10425945.post-1154693757583041552006-08-04T09:12:00.000-03:002006-08-04T09:15:57.673-03:00Chat SessionsHello,<br /><br />I have recently added a new button at my Blog to allow <strong><em><span style="color:#ff0000;">chat conversations</span></em></strong>.<br />The idea is to schedule some chat sessions with users to discuss specific subjects.<br />You may start to send me your subject suggestions by e-mail so I can start to create a schedule for the chat sessions.<br /><br />As I always did all information at this Blog is free as any other provided tools. The idea is to keep this site alive with <strong>Google ads</strong> and now with "<strong>Make Donation</strong>" button.<br /><br />Cheers!<br />Fernando.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10425945-115469375758304155?l=arxdummies.blogspot.com'/></div>Fernando Malardhttp://www.blogger.com/profile/09852061806995998594noreply@blogger.com0