TheSwamp

Code Red => ARX Programming => Topic started by: web.pawan on December 12, 2009, 08:41:54 AM

Title: problem in Spline and Polyline construction using MSpace routines!
Post by: web.pawan on December 12, 2009, 08:41:54 AM
Dear members,

   I went through both ARX Programming and General Programming (was C++) boards. Atlast i decided to post this question over here.

   I am having problem in creating complex structures like spline and polyline in C++ due to inability to create verticesList
   I know how to create a single variant from a ads_point. It works.
   
   I have tried searching various available help from web related to VARIANT (including MSDN) but nowhere(probably i did not get right link)
   i could find out a VARIANT for a list.
   
   I know how to create spline and polyline using AcDb* routines. I am interested to use MSpace->AddPolyline routines.

   
Code: [Select]
VARIANT VerticesList;
#error "help required, do not know how to come up with vertices list"

/* declaration
virtual HRESULT __stdcall AddPolyline (
        /*[in]* / VARIANT VerticesList,
        /*[out,retval]* / struct IAcadPolyline * * pPolyline ) = 0;
*/
hr = test->pMSpace->AddPolyline(/*VARIANT*/ VerticesList, &testPolyLine);

for creating a VARIANT type from ads_point i use following.
void fn_VARIANT_From_ads_point(VARIANT &ptVariant, ads_point pt)
{
SAFEARRAYBOUND rgsaBound;
rgsaBound.lLbound = 0L;
rgsaBound.cElements = 3;
long i;

SAFEARRAY* pPoint = NULL;
pPoint = SafeArrayCreate(VT_R8, 1, &rgsaBound);

i = 0;
double value = pt[X];
SafeArrayPutElement(pPoint, &i, &value);
i = 1;
value = pt[Y];
SafeArrayPutElement(pPoint, &i, &value);

i = 2;
value = pt[Z];
SafeArrayPutElement(pPoint, &i, &value);

ptVariant.vt = VT_ARRAY | VT_R8;
ptVariant.parray = pPoint;
}
   
   I have also attached the my compilable problems.cpp file. test_main() should be called to invoke this code.
   
Code: [Select]
//    acedRegCmds->addCommand(_T("AsdkComAccess_COMMANDS"), _T("test"), _T("test"), ACRX_CMD_MODAL, test_main);

   here is the complete .cpp file
   .cpp
   
Code: [Select]
#if defined(_DEBUG) && !defined(AC_FULL_DEBUG)
#error _DEBUG should not be defined except in internal Adesk debug builds
#endif
#pragma warning( disable : 4278 )
#import "acax17ENU.tlb" no_implementation raw_interfaces_only named_guids
#pragma warning( default : 4278 )
#pragma warning ( disable : 4996 )

#include <rxregsvc.h>
#include <aced.h>
#include <adslib.h>
#include <tchar.h>
#include <acgi.h>
#include <gevec2d.h>
#include <gepnt2d.h>

//copy the point
#define SETPOINT(a,valX,valY,valZ) a[X]=valX; a[Y]=valY; a[Z]=valZ;

typedef struct sTest_s{

//autocade related
    AutoCAD::IAcadDocument *pDoc;
    AutoCAD::IAcadModelSpace *pMSpace;

}sTest_t;

//open and close the doc
HRESULT doc_open(sTest_t *test);
HRESULT doc_close(sTest_t *test);

//variant creation and destroy
void fn_VARIANT_From_ads_point(VARIANT &ptVariant, ads_point pt);
void fn_VARIANT_Destroy(VARIANT ptVariant);

//function that draws polyline and spline
AutoCAD::IAcadLine * test_DrawPolyLine(sTest_t *test);
AutoCAD::IAcadSpline * test_DrawSpline(sTest_t *test);

AutoCAD::IAcadLine * test_DrawPolyLine(sTest_t *test)
{
AutoCAD::IAcadLine * testPolyLine;
HRESULT hr;

acutPrintf(_T("doc_close() exit!"));

ads_point startPoint, endPoint, varPointInBetween1, varPointInBetween2;
SETPOINT(startPoint,10,10,0);
SETPOINT(endPoint,20, 15,0);
SETPOINT(varPointInBetween1,12,13,0);
SETPOINT(varPointInBetween2,13,14,0);

//construct VARIANT type from ads_point
VARIANT startTangent, endTangent;

fn_VARIANT_From_ads_point(startTangent, startPoint);
fn_VARIANT_From_ads_point(endTangent, endPoint);

//how to construct Vertices List VARIANT type for points ads_point startPoint, endPoint, varPointInBetween1, varPointInBetween2;
VARIANT VerticesList;
#error "help required, do not know how to come up with vertices list"

/* declaration
virtual HRESULT __stdcall AddPolyline (
        /*[in]* / VARIANT VerticesList,
        /*[out,retval]* / struct IAcadPolyline * * pPolyline ) = 0;
*/

hr = test->pMSpace->AddPolyline(/*VARIANT*/ VerticesList, &testPolyLine);

if(FAILED(hr))
acutPrintf(_T("Failed to draw polyline");

fn_VARIANT_Destroy(VerticesList);

return testPolyLine;
}

AutoCAD::IAcadSpline * test_DrawSpline(sTest_t *test)
{
AutoCAD::IAcadLine * test_DrawSpline;
HRESULT hr;

/*
(setq  startPoint (list 10 10))
(setq  endPoint (list 20 15))
(setq  varPointInBetween1 (list 12 13))
(setq  varPointInBetween2 (list 13 14))
(command "spline" startPoint varPointInBetween1 varPointInBetween2 endPoint "" startPoint endPoint)
*/
ads_point startPoint, endPoint, varPointInBetween1, varPointInBetween2;
SETPOINT(startPoint,10,10,0);
SETPOINT(endPoint,20, 15,0);
SETPOINT(varPointInBetween1,12,13,0);
SETPOINT(varPointInBetween2,13,14,0);

//construct VARIANT type from ads_point
VARIANT startTangent, endTangent;
fn_VARIANT_From_ads_point(startTangent, startPoint);
fn_VARIANT_From_ads_point(endTangent, endPoint);

//how to construct Vertices List VARIANT type for points ads_point startPoint, endPoint, varPointInBetween1, varPointInBetween2;
VARIANT VerticesList;
#error "help required, do not know how to come up with vertices list"

/*
      virtual HRESULT __stdcall AddSpline (
        /*[in]* / VARIANT PointsArray,
        /*[in]* / VARIANT StartTangent,
        /*[in]* / VARIANT EndTangent,
        /*[out,retval]* / struct IAcadSpline * * pSpline ) = 0;
*/
hr = test->pMSpace->AddSpline(/*VARIANT*/ VerticesList, startTangent, endTangent,&test_DrawSpline);

if(FAILED(hr))
acutPrintf(_T("Failed to draw spline");

fn_VARIANT_Destroy(startTangent);
fn_VARIANT_Destroy(endTangent);
fn_VARIANT_Destroy(VerticesList);

return testPolyLine;
}

//    acedRegCmds->addCommand(_T("AsdkComAccess_COMMANDS"), _T("test"), _T("test"), ACRX_CMD_MODAL, test_main);
void test_main()
{
sTest_t *test = (sTest_t*) malloc(sizeof(sTest_t));

doc_open(test);
test_DrawPolyLine(test);
test_DrawSpline(test);
//doc_save_as_DWG(test);
//doc_save_as_PDF(test);
doc_close(test);
}

HRESULT doc_open(sTest_t *test)
{
    AutoCAD::IAcadApplication *pAcad;
    AutoCAD::IAcadDocument *pDoc;
    AutoCAD::IAcadModelSpace *pMSpace;
    LPUNKNOWN pUnk = NULL;
HRESULT hr = NOERROR;
ULONG ret;
    LPDISPATCH pAcadDisp = acedGetIDispatch(TRUE);

acutPrintf(_T("doc_open()"));

if(pAcadDisp==NULL)
return E_ABORT;

hr = pAcadDisp->QueryInterface(AutoCAD::IID_IAcadApplication,(void**)&pAcad);
ret = pAcadDisp->Release();
if (FAILED(hr))
return E_ABORT;

hr = pAcad->get_ActiveDocument(&pDoc);
ret = pAcad->Release();
if (FAILED(hr))
return E_ABORT;

hr = pDoc->get_ModelSpace(&pMSpace);
if (FAILED(hr))
return E_ABORT;

test->pDoc = pDoc;
test->pMSpace = pMSpace;

acutPrintf(_T("doc_open() exit!"));

return hr;
}

HRESULT doc_close(sTest_t *test)
{
HRESULT hr = NOERROR;
ULONG retVal;
acutPrintf(_T("ac_doc_close()"));

hr = test->pDoc->Close();

if (FAILED(hr))
acutPrintf(_T("Error in pDoc->Release"));
else
acutPrintf(_T("pDoc->Release"));

retVal = test->pDoc->Release();

if (retVal!=S_OK)
acutPrintf(_T("Error in pDoc->Release"));
else
acutPrintf(_T("pDoc->Release"));

hr = test->pMSpace->Delete();

retVal = test->pMSpace->Release();
if (retVal!=S_OK)
acutPrintf(_T("Error in pMSpace->Release"));
else
acutPrintf(_T("pMSpace->Release"));

acutPrintf(_T("doc_close() exit!"));

return hr;
}

void fn_VARIANT_From_ads_point(VARIANT &ptVariant, ads_point pt)
{
    SAFEARRAYBOUND rgsaBound;
    rgsaBound.lLbound = 0L;
    rgsaBound.cElements = 3;
    long i;

SAFEARRAY* pPoint = NULL;
    pPoint = SafeArrayCreate(VT_R8, 1, &rgsaBound);

    i = 0;
double value = pt[X];
    SafeArrayPutElement(pPoint, &i, &value);
    i = 1;
value = pt[Y];
    SafeArrayPutElement(pPoint, &i, &value);

    i = 2;
    value = pt[Z];
    SafeArrayPutElement(pPoint, &i, &value);

ptVariant.vt = VT_ARRAY | VT_R8;
    ptVariant.parray = pPoint;
}

void fn_VARIANT_Destroy(VARIANT ptVariant)
{
SafeArrayDestroyData(ptVariant.parray);
SafeArrayDestroy(ptVariant.parray);
}
   
   Any help or links is highly appreciated.
   
Thanks,
P.


P.S I know its quite easy in VB or .NET. I need to know how to do it in C++. Already read following
//http : // www.roblocher.com/whitepapers/oletypes.aspx
Title: Re: problem in Spline and Polyline construction using MSpace routines!
Post by: It's Alive! on December 12, 2009, 10:39:25 AM
have a look at this pline sample and see if it helps you.   :-)

Code: [Select]
#include "StdAfx.h"
#include "MyCom.h"

typedef CComPtr<IAcadApplication>    _Application;
typedef CComPtr<IAcadDocument>       _Document;
typedef CComPtr<IAcadDatabase>       _Database;
typedef CComPtr<IAcadModelSpace>     _ModelSpace;
typedef CComPtr<IAcadPolyline>       _PLine;

int MyCOM(const AcGePoint3dArray &arr)
{
  HRESULT hr = 0;
  CComPtr<IAcadApplication> App = NULL;

  std::vector<double> dbls;
  for(size_t i = 0 ; i < arr.length(); i++){
    dbls.push_back(arr[i].x);
    dbls.push_back(arr[i].y);
    dbls.push_back(arr[i].z);
  }

  SAFEARRAYBOUND rgsabound[1];
  rgsabound[0].lLbound = 0;
  rgsabound[0].cElements = dbls.size();
  LPSAFEARRAY psa = SafeArrayCreate(VT_R8, 1, rgsabound);
  if(psa == NULL){
    acutPrintf(_T("Failed to create array"));
    return -1;
  }

  long index[1];
  for(size_t i = 0 ; i < dbls.size(); i++){
    index[0] = i;
    SafeArrayPutElement(psa,index,&dbls[i]);
  }

  VARIANT ptList;
  ptList.vt = VT_ARRAY | VT_R8;
  ptList.parray = psa;

  if(App == NULL){
    CoInitialize(NULL);
    CComQIPtr<IAcadApplication>
      _app = acedGetIDispatch(TRUE);
    App = _app;
  }

  if (!App){
    acutPrintf(_T("Failed to get Application"));
    return -1;
  }

  _Document Doc;
  hr = App->get_ActiveDocument( &Doc );
  if(FAILED(hr)){
    acutPrintf(_T("Failed to get ActiveDocument %ld"),hr);
    return -1;
  }

  _Database Db;
  hr = Doc->get_Database( &Db );
  if(FAILED(hr)){
    acutPrintf(_T("Failed to get Database %ld"),hr);
    return -1;
  }

  _ModelSpace MSpace;
  hr = Db->get_ModelSpace( &MSpace );
  if(FAILED(hr)){
    acutPrintf(_T("Failed to get Database %ld"), hr);
    return -1;
  }

  _PLine PLine;
  hr = MSpace->AddPolyline( ptList, &PLine );
  if(FAILED(hr)){
    acutPrintf(_T("Failed to add polyline %ld"), hr);
    return -1;
  }

  VariantClear(&ptList);
  CoUninitialize();
  return 0;
}
Title: Re: problem in Spline and Polyline construction using MSpace routines!
Post by: It's Alive! on December 12, 2009, 10:52:30 AM
Oh Yea! Welcome to theSwamp   8-)
Title: Re: problem in Spline and Polyline construction using MSpace routines!
Post by: web.pawan on December 12, 2009, 12:16:47 PM
Perfect, i made some changes and it worked!

Happy to be here! :-)

btw, the donate link on your footer doesn't work!

Oh Yea! Welcome to theSwamp   8-)
Title: Re: problem in Spline and Polyline construction using MSpace routines!
Post by: Kerry on December 12, 2009, 04:31:15 PM

btw, the donate link on your footer doesn't work!


try this .. http://www.theswamp.org/donate.html

and welcome to theSwamp
Title: Re: problem in Spline and Polyline construction using MSpace routines!
Post by: web.pawan on December 12, 2009, 09:44:16 PM
 :-) I could find out Donate link at the top,& i did it already!
It was just FYI for all for correction!
Title: Re: problem in Spline and Polyline construction using MSpace routines!
Post by: Kerry on December 12, 2009, 09:51:27 PM

Thank you for the donation.
I'm sure  Mark (site administrator) (http://www.theswamp.org/index.php?action=profile;u=2) will appreciate it.