Wednesday, October 21, 2009

CEEFIT: I miss you

I first noticed on Sep 24th that the web-site that hosts the C++ implementation of FIT (CEEFIT) was gone. I get a "DNS Error. Cannot find server" error for the URL http://ceefit.woldrich.com/. Even http://www.woldrich.com/ is no longer found, with the same error might I add.

This is not good. Indicates that the company that hosted/developed CEEFIT is gone taking some of the documentation for CEEFIT with it. While the source code for CEEFIT is still available at http://sourceforge.net/projects/fit/files/, some of the implementation details that were key for me to customize various aspects of CEEFIT are no longer available. If you use any of the downloads that I provide through the "My Downloads" section, you have the necessary header files and libraries to use CEEFIT in your IntegratedTests. But you would need the original source code and documentation for any customizations.

I have emailed Dave (using an old email address I have, which unfortunately is part of the woldrich.com domain) and hope I will hear back from him. I have requested he upload the documentation for CEEFIT to sf.net and I am really, really hoping he grants wishes.

In the short term I am screwed, but fortunately there is an alternate implementation of FIT in C++ available through http://www.fitnesse.org/. I have briefly tried fitnesse and have found the requirements they place to use their library (that I learn their Wiki markup to create tests and the ability to run a HTTP server on my build machine to run the tests) quite burdensome. But if I am going to continue C++ development and want to run Integrated Tests, I guess I have no other choice. But this time, I will be careful enough to create a personal mirror of www.fitnesse.org for myself, in case this too disappears off the face of the world(wideweb).

But honestly this is one more of the reasons why I love open source. If CEEFIT was a closed source library and the company developing it, shut down, then I would definitely be screwed. Since I have the source for CEEFIT, I can continue to develop it (if I had the requisite skills, of course).

So does CEEFIT going AWOL affect you?

Friday, October 16, 2009

Did uninstalling SolidWorks delete half my hard drive?

I recently had to re-install SolidWorks 2009 on my laptop. During the uninstall process I noticed that several of my programs in the "C:\Program Files" folder went missing. Now I am not the one to start pointing fingers just yet, but this episode completely freaked me out. I had SolidWorks installed under "C:\Program Files\SolidWorks Corp" so would be more than surprised if this was in fact an error on the part of the SolidWorks uninstaller, but at the time of uninstallation, my laptop was not being used and no other "application window" was open. I also rarely log on with administrative privileges on either my XP or Vista laptop, so pretty low chance I accidentally deleted these folders myself (if I was that insane). I also did the usual checks for viruses, spyware and other junk, in vain.

Oh well! That's life I guess.

But during the reinstallation process I realized a quirk in the SolidWorks installation. Does it make sense to put header files required for SolidWorks Add-in development under the "samples" directory? Well that's what SolidWorks has done. So if you are developing SolidWorks add-ins, don't forget to select the "Examples" option in the SolidWorks Installation Manager, during the installation. Else you will not have the headers (e.g. "amapp.h") that you need for VC++ Add-in development.

Thursday, October 15, 2009

Who uses BRL-CAD? An Anonymous answer

This post is more of a response to a comment I received on my previous post titled And the World's Oldest Source Code Repository is.... Since the commenter chose to remain anonymous, I had no way to respond other than to blog a new post. I will resume posting "useful" information with my next post.

Firstly, Thanks 'Anonymous' (I knew I should not allowed people to comment on my posts anonymously, but it encourages more commenting from what I can tell), for your very detailed answer. I wonder if you are one of the seemingly many contributors to the BRL-CAD source code.

I would have been happier if you were able to provide some links to sites or people who use BRL-CAD, but I think I may be able to find at least 1 contact inside the U.S. Army Research Laboratory (ARL) who could enlighten me further.

It has been a long time since I downloaded and tested the latest version of BRLCAD. I am hoping to be surprised by their user-friendliness though from their screenshots (mostly updated in Mar 2008), it still appears command-driven rather than menu-driven.

Friday, September 25, 2009

And the World's Oldest Source Code Repository is...

Many years ago (actually in 2006), I had written about an Open Source CAD program known as BRL-CAD (note: the links to tutorials I had included in that post are no longer active and give a message "BRL-CAD became an open source project in December of 2004 and is no longer hosted on FTP.ARL.ARMY.MIL").

Well surprisingly  BRL-CAD has been in the news for a while. Were you aware that according to Ohloh, BRL-CAD has the world's oldest open source repository? Can you believe that? The repository supposedly has been active since 1983.

Well if you thought that was interesting then check this. BRL-CAD was also a participating organization in the Google Summer of Code 2009 and had 3 student interns who worked on as many projects.

So the oldest CAD program is still being actively developed. That is interesting, but what I want to know is who is using BRL-CAD? I work for a CAD tools company and we have never been requested to even look at BRL-CAD as a possible CAD system to support. BRL-CAD's About page says that the U.S. Military is one of the clients. I have been on a Civilian installation of the U.S Army and have seen BRL-CAD installed on their lab computers. But none of the modelers were using it to deliver designs. So the question still stands - who is using BRL-CAD?

Do any of you have any experience with BRL-CAD at your work? Does anyone use BRL-CAD for anything? Let me know.

Friday, August 21, 2009

Which Free 3D CAD program would I suggest?

A few months ago I received a comment on one of my posts, asking me which free 3D CAD program I would suggest. You can see my response here.


Answering JOE's (the commenter) request reminded me that I had posted a few articles in the past about Open Source CAD programs. Since then though I had pretty much given up searching for an open source CAD program that would provide at least a usable modeling tool (primarily because my initial search was futile).


But I did keep my eyes open a little bit and came across NaroCAD a few months ago. Having followed NaroCAD's feeds for that period I noticed that it is under quite active development. From the developer's blog "NaroCAD is an opensource CAD design tool written in C#/.NET and is built on top of proven OpenCascade library". In fact NaroCAD reached 1.0 milestone a few months ago and they even provide .NET bindings for OpenCascade (including IronPython).


In my comment, I had recommended to JOE to use Alibre Design Xpress, since it is free, and offers great capability at that price (check out Alibre's CEO's blog - they even have a sale on Alibre Design Standard at the time of this writing, Aug 18 2009). I have not experimented with NaroCAD myself but considering its infancy I am relatively certain that its capabilities don't match Alibre's.


If the fact that I have a blog titled "Open Source Software and CAD" and am recommending a non-open-source program to my readers, alarms you, then don't be. I simply am recommending what I think is feasible. Most CAD users are not programmers. They may be versatile in creating Mapkey Automation or Macro scripts but mostly simply care about how complete their 2D/3D tools are for modeling purposes. In my experience with open source, attempting to use a program which has not matured, would usually result in much frustration to users who are not adept at looking at source code to solve any problems they may have (this is not to taint NaroCAD itself, it may be a great program, but just to explain my reason for the recommendation).


If you feel upto it, I would suggest downloading NaroCAD and experimenting with it. I am relatively certain that you may need to download OpenCascade separately as the installer for NaroCAD does not seem large enough (15.6MB) to accommodate all of OpenCascade (175MB).

UPDATE (8/30/2009): I stand corrected. One (of the 3 contributors to their blog) of the developers of NaroCAD (ciplogic) left a comment (still visible below this post) that NaroCAD uses only a subset of OpenCascade, which means that the ~15 MB download of NaroCAD is really all you need. So what are you waiting for? Have you downloaded NaroCAD? I have.

Friday, July 24, 2009

SWX Batch mode Integrated Tests with CEEFIT

If you have read any of my previous posts on Testing CAD Plugins, then you are aware of what I am trying to accomplish - an automated Integrated Test framework to test, at the very least, SolidWorks API Plugins. The following are some of the more relevant posts regarding Testing CAD Plugins:


Some of you have even downloaded the sample workspace "swbatch.zip" posted in one of the posts above (Batch mode SolidWorks). For convenience the following is the "swbatch.zip" file.



http://ossandcad.googlecode.com/files/swbatch.zip






If you prefer to download from the source, you can do so using the following link with your SVN client (e.g. TortoiseSVN (follow the instructions at http://code.google.com/p/ossandcad/source/checkout)):


https://ossandcad.googlecode.com/svn/trunk/swbatch


 



The Pursuit of "CAD Plugin Testingness"
With this post I continue my pursuit of an automated Integrated Test Framework, using CEEFIT and dare I say it, I have come quite close to achieving my goal (my wishlist of sub-goals not yet achieved are listed at the end of this post).

Download the IntegratedTests workspace 
You can choose the zip format or access from SVN directly:
http://ossandcad.googlecode.com/files/swxbatch_ceefit_6_16_2009.zip







https://ossandcad.googlecode.com/svn/trunk/swxbatch_ceefit



 The "swxbatch_ceefit" workspace is an extension of the "swxbatch" workspace. The main difference is the ability to load SolidWorks and using API and CEEFIT, pass it input from the CEEFIT tables and verify expected output as mentioned in the CEEFIT tables.

The solution is documented - but its my contention that nothing is ever documented enough - so if you need more information on how things work then leave a comment. I will put up another post that has more details.

Assumptions:
  • You have SolidWorks installed and are working with appropriate licenses
  • You may need to have the SolidWorks API SDK installed to write SolidWorks API-based code.
  • You have access to Visual Studio (at least 2005, as this solution is provided in that version). Later versions should work but I have not tested them out.
Wish list of sub-goals
  • Passing in only HTML file (with CEEFIT tables) at a time is supported. This is how CEEFIT works by default, but it is not easy to test CAD stuff with all data in one single table. I wish for a solution to this and will post if I am successful. But for now it works as intended.
  • Currently integration of CEEFIT-based solutions with Continuous Integration systems (e.g. CruiseControl.NET) is poor, as CEEFIT only puts out HTML files and at least CruiseControl.NET does not merge HTML output as part of its build log, which is a bummer as "true" integration would help us identify a failure, location and cause, which this current framework does not do. I wish to write out the output of CEEFIT as XML (at least) so that it can be integrated into build systems. (To be honest, FIT and thereby CEEFIT profess to be tools that enhances customer interaction with systems in development, so HTML works best, but for developers HTML is difficult to incorporate into their workflow).
  • The provided workspace is good only for SolidWorks. I wish for a solution that allows interaction with various CAD systems, through their individual API, and tests my plugin application with all of them.
Notes and Tips:
  • The workspace, when run, starts SolidWorks in background (aka batch mode) by using a SolidWorks API, which simply hides the SolidWorks window.

    swApp->put_Visible(FALSE)
  • If you want to make SolidWorks visible during its batch operations, then change the FALSE to TRUE and rerun. SolidWorks starts up and you can see all API actions play out like a movie. I should say it is almost as fun to watch as a video on Youtube.
  • I have used a global variable "swApp" as I don't know how else to pass variables in to the CEEFIT run test classes. While not a big problem, I hate global variables as they make testing otherwise hard to do.
  • Please visit the home page for this and other projects: http://ossandcad.googlecode.com for more information. I will try to update those pages soon and as regularly as possible.
  • For more information on CEEFIT you can read the short summary I have at http://ossandcad.blogspot.com/2008/05/protoolkit-solidworks-api-development.html or even visit the CEEFIT homepage at http://ceefit.woldrich.com/?page=Home. I should warn though that CEEFIT has not been updated for many years, but it works relatively well in its current stage. Hopefully enough of us use it to get the original author dave@woldrich.com to continue development.
If you have downloaded "swxbatch.zip" to develop SolidWorks plugin applications (or Addins) then I sure that this workspace will be very useful to you. Let me know if you do or don't. Comments and suggestions are most welcome and will be responded to, so feel free to communicate your needs.

Friday, July 03, 2009

New "My Downloads" Section

First, thanks to everyone who downloaded the workspaces that I had uploaded to this blog (using http://www.box.net). I hope you found them useful.

Previously you could only find the uploaded workspaces by going to the individual posts. After noticing that these workspaces were being downloaded many times a week, I wanted to make it simpler for you, my readers, to find and download these workspaces.

I have added a "My Downloads" section, on the left sidebar (at the time of this posting, just below the "Older posts of mine" section) that links the relevant downloads. This will be a permanent fixture on each blog post page.

If you notice, these workspaces are being hosted on Google Code at http://ossandcad.googlecode.com which is my new repository for storing and sharing my CAD-API-based plugins and applications.

At the time of writing this post the following workspaces are made available on http://ossandcad.googlecode.com:

  1. Pro/Toolkit + Visual Studio 2005 Workspace (http://ossandcad.googlecode.com/files/ProToolkitVisualCpp.zip)
  2. SolidWorks Batch mode using SolidWorks API+COM (http://ossandcad.googlecode.com/files/swbatch.zip)
  3. SWX+CEEFIT Integrated Test Workspace (http://ossandcad.googlecode.com/files/swxbatch_ceefit_6_16_2009.zip)
Comments, suggestions most welcome.

Thursday, July 02, 2009

New Google Code project to accompany this blog

Thanks to all of you who have downloaded the various zips from my blog. I was using www.box.net to store and share my files. While box.net was sufficient, it was getting difficult to track usage and download rate, since I was only using the free version.

To solve that problem and to find a simpler method to share my code, using a source code repository I have created a Google Code project. You can find my project at http://ossandcad.googlecode.com. I have added an introduction and some Wiki pages and some files for download.

The following files are available for download:

  1. http://ossandcad.googlecode.com/files/swbatch.zip
  2. http://ossandcad.googlecode.com/files/ProToolkitVisualCpp.zip
  3. http://ossandcad.googlecode.com/files/swxbatch_ceefit_6_16_2009.zip -If you wondering what this is, then you have two options - wait for my blog post detailing how to use CEEFIT with SolidWorks API to run IntegratedTests - or - you could download and start working with the source code right away.
The following Wiki pages are also available (but mostly duplicating content originally posted on this blog)
  1. http://code.google.com/p/ossandcad/wiki/SwxBatch
The biggest advantage of this for users is that you could download/browse my source code directly from SVN from http://code.google.com/p/ossandcad/source/browse/#svn/trunk.  For me the biggest advantage is the ability to track usage using Google Analytics.

Comments/suggestions most welcome.

Tuesday, May 19, 2009

Unlocking Pro/TK Applications - Blog Referral

In one of previous posts titled "License needed to run my Pro/Toolkit add-ins" I received a comment requesting help using protk_unclock.exe to unlock the Pro/TK application provided in the same post. (For sake of convenience the following is the zip of the source for Pro/TK application)



http://ossandcad.googlecode.com/files/ProToolkitVisualCpp.zip


As an answer to the question posed in that comment, I refer you to a post by my colleague, Amar Junankar, on his blog at http://cadinterface.blogspot.com/2009/05/unlocking-protoolkit-application.html. Amar has posted solutions for both developers and non-developers.

Welcome to the blogging world Amar.

Tuesday, April 07, 2009

MbUnit + AutoCAD = Unit testing for CAD Plugins

If you follow my blog, you know that I develop CAD plug-ins in both .NET and C++. And in various posts of mine I have written about the difficulty of writing unit tests for these CAD plug-ins. The following are some of my more relevant posts regarding this topic.

My usual solution was to avoid unit testing these CAD plugins and simply write integrated tests for them. The last post mentioned above (Writing CEEFIT class like a regular C++ class) specifically shows a sample CEEFIT (Framework for Integrated Test for C/C++) class that enables integrated testing using SWX (I will post the complete workspace to do this soon).

But imagine my surprise when I read the following post about the release of MbUnit v3.0.5 - http://weblogs.asp.net/astopford/archive/2009/04/02/mbunit-3-rtm.aspx. The below text is an excerpt from that post (bold and italics are my addition):
Gallio provides MbUnit with the runner infrastructure and the list of supported runners is amazing, like MbUnit v2 you can still run MbUnit v3 in MSBuild, NAnt, TD.Net, CruiseControl, commandline (much more ehanched in v3) and GUI (also vastly enhanced in v3) but now tools such as TeamCity, VSTS, Resharper, Powershell, NCover, TypeMock and even AutoCAD.
That last word really caught my attention. What is this? Unit test support for CAD system plug-ins? That is so awesome it is beyond belief. A Google search for "AutoCAD MbUnit" gave more information via http://blog.bits-in-motion.com/2008/11/announcing-gallio-and-mbunit-v305.html. An excerpt:

AutoCAD Integration

Mike Sandberg has added support for testing AutoCAD plugins.
It turns out that AutoCAD has a managed extensibility model so you can create your own plugins using .Net and the ObjectARX toolkit.  Unfortunately it is somewhat difficult to write unit tests for plugins becuase they must run within the main UI thread of AutoCAD.
The AutoCAD integration for Gallio works by loading a shim into the AutoCAD application from which it can launch tests.  To enable this integration, specify the "AutoCAD" runner type to the Echo, Icarus, MSBuild, NAnt or PowerShell runners.
For example:

    Gallio.Echo.exe MyTestAssembly.dll /r:AutoCAD [other options...]

AutoCAD integration is not yet available from within the IDE.  We will be working to improve this use case in the future.
OK. This definitely is promising. The post provides usage scenario, and although low on details on how this is achieved beyond saying "loading a shim", it is exactly what we CAD developers need.

To learn more on how MbUnit developers solved this problem, I turned to the source code available at http://mb-unit.googlecode.com/svn/trunk/v3/src/Extensions/AutoCAD. From first glances it looks as though the shim can connect or load (via the "acad.exe" file) AutoCAD. The shim finds the path to "acad.exe" via the registry key
"HKEY_CURRENT_USER\Software\Autodesk\DWGCommon\shellex\Apps\{F29F85E0-4FF9-1068-AB91-08002B27B3D9}:AutoCAD". 
It then determines if your plugin is loaded and if yes, sends commands to it using a TestDriver (AcadTestDriver).

What I found even more intriguing was the description of the problem that MbUnit developers intended to solve i.e. "difficulty of running unit tests as they run in the main UI thread of AutoCAD ". As I have contended, this is an universal problem for CAD developers. Replace AutoCAD with SolidWorks and the posts that I list above were intended to solve this very problem, although with a hack of a solution, but still following the same lines of thought. The CEEFIT workspace that I work with, loads SolidWorks in the background and using COM, connects to the running instance and then executes SWX-API-based tests. I let CEEFIT be the TestDriver and validate my output. The MbUnit framework has packaged idea this in beautiful .NET code.

This brings up the possibility that since SolidWorks plugins can also be .NET based, would replacing AutoCAD connection commands with SolidWorks connection commands in MbUnit's framework, allow loading the shim into SolidWorks and run unit tests against SolidWorks. I will be exploring this possiblity in the coming weeks/months, as time permits.

Do you develop AutoCAD plugins? Is this new functionality of MbUnit useful to you? Comments welcome.

Monday, March 02, 2009

SolidWorks API - In-process or Global methods - Which to use?

Two SWX API to rule them (or is it 'Two SWX API to confuse us'?)
Did you know that SolidWorks (SWX) provides two distinct (yet confusingly similar) interfaces to 'get' or 'set' arrays through its API? Well it does. I recently installed SWX 2009 SP 2.0 (I know, I know - this release has been out for a while, but I never needed the newer features) - but I upgraded from SWX 2007 SP 0.0 when I ran into some vexing problem with the SWX API and hoping that it was an SWX bug, decided to try their newest version. Turns out the problem were me and my limited knowledge of these two API interfaces.

The one advantage of installing SWX 2009 was the updated API documentation. The 2007 API documentation did not contain a page titled "In-process methods", which the 2009 version does. The following is an excerpt from that SWX 2009 API page (apihelp.chm) (italics are my addition) (note to lawyers: if it is not legal to publish portions of the SWX help documentation, please leave a comment and I will remove the appropriate sections)

In-process Methods
The SolidWorks API provides two types of methods for interfaces that get or set arrays:
  • in-process
  • global
For example, IView contains these methods:
  • IView::IGetCThreads (in-process)
  • IView::GetCThreads  (global)
Both types of methods perform the same work, but each is more or less appropriate for a given language and application.
In-process methods typically begin with the letter I and get or set pointers to arrays that only unmanaged C++ applications can handle. The in-process companion methods (i.e., similarly named methods that do not begin with the letter I) are more globally useful both inside a process and across processes and return predictable results for all of the SolidWorks supported languages.
In VBA, VB6, VB.NET, C#, and C++/CLI (also called managed C++), global methods typically get or set a VARIANT or object that the programmer can iterate as an array. In unmanaged C++, these methods get or set a pointer to a Dispatch object that should be cast as a SafeDISPATCHArray. (SafeDISPATCHArray is a VARIANT helper class defined in a template class, which is available on the API Support website.)
Q. To chose or not to chose
So how do you decide which interface to use? Does it even matter?
A. The answer to the 2nd question 'does it even matter' is - simply - YES IT DOES MATTER.

To answer the 1st question 'how do you decide which interface to use' - consider the following:
  • If 
    1. you are building a DLL Add-in to SWX,

      AND 


    2. you plan to only load that DLL through SWX

      THEN

       
    3. you can comfortably use the "in-process method".
  • But if
    1. you are building an EXE that loads SWX through COM

      AND
       
    2. loads your SWX Add-in DLL (i.e. instantiates classes from the Add-in DLL in the EXE), allowing calls from the Add-in DLL to go to SWX

      THEN
       
    3. you need to use the "global method" in

      BOTH
       
    4. the COM+EXE and Add-in DLL.

      AND

    5. LUCKILY YOU CAN STILL LOAD THE DLL ADD-IN DIRECTLY INTO SWX (doesn't that sound ideal?)
So how do you work this "global method"?
If you are like me and have little experience with COM, DISPATCH and VARIANTS then fear not because SolidWorks is gracious enough to provide us with a C++ template to simplify our lives. The files you need are hosted at http://files.solidworks.com/API/Examples/00000/0100s/0126/Example.htm. Simply download the zip file and include the "smartvars.h" file in your solution. The zip file also contains a sample in the file "usage.cpp", but for the sake of completness let me provide you with an example of my own:
VARIANT vxform;
LPSKETCH pSketch;
...
... // code to InsertSketch() so that pSketch is a valid pointer
...
pSketch->get_ModelToSketchXform(&vxform);
SafeDoubleArray varDimArr(vxform);
wofstream wfs;
wfs.open(L"dimension_data_swx3dexpextrusion.txt");
for( int i = 0 ; i < 13 ; i ++ ) {
     wfs << "\nXFormData at\t" << i << "\t=\t" << varDimArr[i];
}
wfs.close();
CONCLUSION
SolidWorks API while easy to work with have a few surprises - though in this case the missing documentation would have spoiled the surprise for me in the 2007 version. So all in all, I am able to run batch-mode integration test using the combination of CEEFIT and "global methods" to access array data from SolidWorks.

Monday, February 02, 2009

Writing CEEFIT class like a regular C++ class

FIT / CEEFIT?
If you need to write integrated tests that can take a table specifying input data and expected output data, and run the tests in a batch, then you should consider Fit: Framework for Integrated Test. If you develop applications with C++, then look to CEEFIT to satisfy your FIT needs.

CEEFIT is well documented, flexible and an excellent integrated test framework. In most cases you can use the Macro method to create your test-classes, but CEEFIT also provides a way to create test-classes manually from scratch. This second 'manually from scratch' method is what this post talks about.

Why would you want to write CEEFIT classes from scratch?
Well one reason for me was to ensure that I could still use Doxygen to document the classes and their methods and parameters i.e. make the code-documentation doxygen-visible. I have not been able to figure out how to have the documentation be doxygen visible when using the macros.

How to write CEEFIT class from scratch?
The example posted on CEEFIT's website is excellent and provides everything you need, but I found it a little too much. I simply wanted to write a class that inherits from COLUMNFIXTURE that looks like a regular C++ class - I did not want to mess with TABLE or DoRows(). Turned out to be very simple to do and here it is:

TestSWX.h
namespace swx_ceefit {
/** A CEEFIT class created from scratch without macros to test batch-mode processing of SWX API cases.
        \author GRI
        \date Dec 1 2008
    */
    class TestSWX :
        public CEEFIT::COLUMNFIXTURE
    {
    public:
        inline ceefit_init_spec TestSWX();
        inline virtual ceefit_dtor_spec ~TestSWX();
    private:
         ceefit_init_spec TestSWX(const TestSWX&);
         TestSWX& ceefit_init_spec operator=(const TestSWX&);
        /** fit_var
        */
        CEEFIT::STRING m_sldprt_name;
        /** fit_test
        */
        double ceefit_call_spec nos_feats();
        /** where is this executable executing from?
        */
        void ExecutingPath();
        /** Get the full path to the input file i.e. the *.sldprt file
            \author GRI
            \date Jan 8 2009
        */
        void GetFullPath(std::wstring & wsFullPath);
    };
 }

TestSWX.cpp
CComPtr swApp;

namespace swx_ceefit
{
    ceefit_init_spec TestSWX::TestSWX()
    {
        RegisterCeefitField(this, "sldprt_name", m_sldprt_name);
        RegisterCeefitTest(this, "nos_feats", &TestSWX::nos_feats);

        //cout << endl << "constructing";
    }

    ceefit_dtor_spec TestSWX::~TestSWX() {
        //cout << endl << "destructing";
    }

    double ceefit_call_spec TestSWX::nos_feats() {
        ExecutingPath();
        wstring wsFullPath;
        GetFullPath(wsFullPath);
        if( swApp ) {
            IModelDoc* swModel = NULL;
            if( swApp->put_Visible(FALSE) == S_OK ) {
                if( swApp->DocumentVisible(FALSE, swDocPART) == S_OK ) {
                    //wcout << "\nfull path in nos_feats = " << wsFullPath.c_str() << endl;
                    CComBSTR sFileName(wsFullPath.c_str());
                    CComBSTR sDefaultConfiguration(L"Default");
                    long fileerror;
                    if( swApp->IOpenDocSilent(sFileName.m_str, swDocPART, &fileerror, &swModel) == S_OK ) {
                        if( swModel != NULL ) {
                            IPartDoc *part;
                            HRESULT hres = swModel->QueryInterface(IID_IPartDoc, (LPVOID *)&part);
                            if( swModel->put_Visible(FALSE) == S_OK ) {
                                CComPtr swfeat;
                                if( part->IFirstFeature(&swfeat) == S_OK ) {
                                    CComBSTR name;
                                    swfeat->get_Name(&name);
                                   
                                    wcout << endl << "1st feat name = " << name.m_str;
                                    swModel->Quit();
                                } else wcout << endl << "no first feature";
                            } else wcout << endl << "swModel still visible";
                        }
                        else {
                            wcout << endl << "swModel = NULL with fileerror = " << fileerror;
                        }
                    } else wcout << endl << "open doc not silent";
                } else wcout << endl << "document still visible";
            }
        }
        else wcout << endl << "ERROR: swApp = NULL" << "\tfile\t=\t" << __FILE__ << "\tline\t=\t" << __LINE__;
        VARIANT_BOOL ret;
        swApp->CloseAllDocuments(TRUE, &ret);
        return 1;
    }

    void TestSWX::ExecutingPath() {
        wchar_t sExecPath[MAX_PATH];
        GetModuleFileName(NULL, sExecPath, MAX_PATH);
        //wcout << endl << "executable = " << sExecPath;
    }

    void TestSWX::GetFullPath(wstring & wsFullPath) {
        wchar_t cFullPath[MAX_PATH] = TEXT("");
        LPTSTR  lpszFilePart = NULL;
        GetFullPathName(m_sldprt_name.GetBuffer(), MAX_PATH, cFullPath, & lpszFilePart);
        //wcout << endl << "full path = " << cFullPath;
        wsFullPath = cFullPath;
    }

    static REGISTERFIXTURECLASS< TestSWX > FatTableFixtureRegistration("swx_ceefit::TestSWX", "AKA_TESTSWX"); 


Conclusion
If you are wondering why this class is called TestSWX (SWX = short for SolidWorks), then consider this: using the solution from a previous post of mine "Batch mode SolidWorks" we can start SolidWorks without GUI and using the above CEEFIT class, call SolidWorks API and run your integrated tests. But that my readers is possibly a separate post.