Author Topic: problem in Spline and Polyline construction using MSpace routines!  (Read 3765 times)

0 Members and 1 Guest are viewing this topic.

web.pawan

  • Guest
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

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7096
  • AKA Daniel
Re: problem in Spline and Polyline construction using MSpace routines!
« Reply #1 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;
}
« Last Edit: December 12, 2009, 10:44:39 AM by Daniel »
Retired

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7096
  • AKA Daniel
Re: problem in Spline and Polyline construction using MSpace routines!
« Reply #2 on: December 12, 2009, 10:52:30 AM »
Oh Yea! Welcome to theSwamp   8-)
Retired

web.pawan

  • Guest
Re: problem in Spline and Polyline construction using MSpace routines!
« Reply #3 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-)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: problem in Spline and Polyline construction using MSpace routines!
« Reply #4 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
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

web.pawan

  • Guest
Re: problem in Spline and Polyline construction using MSpace routines!
« Reply #5 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!

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: problem in Spline and Polyline construction using MSpace routines!
« Reply #6 on: December 12, 2009, 09:51:27 PM »

Thank you for the donation.
I'm sure Mark (site administrator) will appreciate it. 
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--