NO

Author Topic: Pelles-C + OLE for access to AutoCAD  (Read 5653 times)

Offline sergey

  • Member
  • *
  • Posts: 97
Re: Pelles-C + OLE for access to AutoCAD
« Reply #30 on: June 28, 2016, 01:08:44 am »
Fixed code.
Thank you, I would not have found.
Now polyline performed.
But the joy was short-lived.
Even after changing Sarray AutoCAD Text is not executed.
Also not working Rotate Polyline.
But in arguments of this function missing Variant-type.
Code: [Select]
/* create arrow as Polyline & put it on Point-1 & rotate it to calculated Angle */
void Arrow12 (double distance, double angle, double dArrowScale)
{
// add a polyline object into Model-Space
pLWP = drawLWP (pUtility, pModelSpace, dArrowScale);
rotPoint = rotpnt (pUtility,  pModelSpace);
// add a text object into Model-Space
txtPoint = rottxt (pUtility, pModelSpace, pText, distance, dArrowScale);

//rotate LWPolyline around BasePoint vp1
if (IAcadLWPolyline_Rotate(pLWP, rotPoint, angle))
IAcadLWPolyline_Update(pLWP);
//rotate Text around BasePoint vpT
if (IAcadText_Rotate(pText, txtPoint, angle))
IAcadText_Update(pText);

return;
}

IAcadLWPolyline* drawLWP (IAcadUtility* pUtility, IAcadModelSpace* pModelSpace, double dArrowScale)
{
// add a polyline object into Model-Space
HRESULT hr;
VARIANT vpnt; // TypedArray for LWPolyLine
SAFEARRAY* psarrayL = SafeArrayCreateVector(VT_VARIANT, 0, 10);

// LWPolyline
((VARIANT*)psarrayL->pvData)[0].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[0].dblVal = dblPnt1[0];
((VARIANT*)psarrayL->pvData)[1].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[1].dblVal = dblPnt1[1];
((VARIANT*)psarrayL->pvData)[2].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[2].dblVal = dblPnt1[0] + 0.5 * dArrowScale;
((VARIANT*)psarrayL->pvData)[3].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[3].dblVal = dblPnt1[1];
((VARIANT*)psarrayL->pvData)[4].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[4].dblVal = dblPnt1[0] + 0.25 * dArrowScale;
((VARIANT*)psarrayL->pvData)[5].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[5].dblVal = dblPnt1[1] + 0.05 * dArrowScale;
((VARIANT*)psarrayL->pvData)[6].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[6].dblVal = dblPnt1[0] + 0.25 * dArrowScale;
((VARIANT*)psarrayL->pvData)[7].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[7].dblVal = dblPnt1[1] - 0.05 * dArrowScale;
((VARIANT*)psarrayL->pvData)[8].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[8].dblVal = dblPnt1[0] + 0.5 * dArrowScale;
((VARIANT*)psarrayL->pvData)[9].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[9].dblVal = dblPnt1[1];

// sarray for LWPoly inserted in vpnt
hr = IAcadUtility_CreateTypedArray(pUtility, &vpnt, VT_R8, psarrayL);
SafeArrayDestroy(psarrayL);  // free array
// draw LWPolyline in ModelSpace
if (!hr) {
hr = IAcadModelSpace_AddLightWeightPolyline(pModelSpace, vpnt, &pLWP);
IAcadLWPolyline_Update(pLWP);
}

return pLWP;
}

VARIANT rotpnt (IAcadUtility* pUtility, IAcadModelSpace* pModelSpace)
{
HRESULT hr;
VARIANT vp1; // TypedArray for Text insertion-point
SAFEARRAY* psarrayP = SafeArrayCreateVector(VT_VARIANT, 0, 2);

// rotation point BasePoint
((VARIANT*)psarrayP->pvData)[0].vt = VT_R8;
((VARIANT*)psarrayP->pvData)[0].dblVal = dblPnt1[0];
((VARIANT*)psarrayP->pvData)[0].vt = VT_R8;
((VARIANT*)psarrayP->pvData)[0].dblVal = dblPnt1[1];

// sarray for LWPoly inserted in vpnt
hr = IAcadUtility_CreateTypedArray(pUtility, &vp1, VT_R8, psarrayP);
SafeArrayDestroy(psarrayP);  // free array

if (IAcadLWPolyline_Rotate(pLWP, vp1, 0.75))
IAcadLWPolyline_Update(pLWP);

return vp1;
}

VARIANT rottxt (IAcadUtility* pUtility, IAcadModelSpace* pModelSpace, IAcadText* pText, double distance, double dArrowScale)
{
HRESULT hr;
VARIANT vpT; // TypedArray for Text insertion-point
SAFEARRAY* psarrayT = SafeArrayCreateVector(VT_VARIANT, 0, 2);
wchar_t sDistance[8];

// Text Insert point
((VARIANT*)psarrayT->pvData)[0].vt = VT_R8;
((VARIANT*)psarrayT->pvData)[0].dblVal = dblPnt1[0]+0.05*dArrowScale;
((VARIANT*)psarrayT->pvData)[1].vt = VT_R8;
((VARIANT*)psarrayT->pvData)[1].dblVal = dblPnt1[1]+0.05*dArrowScale;

// sarray for BasePoint inserted in vp1
hr = IAcadUtility_CreateTypedArray(pUtility, &vpT, VT_R8, psarrayT);
SafeArrayDestroy(psarrayT);  // free array
// draw LWPolyline in ModelSpace
if (!hr) {
// Architect drawing units mm, Geodetic drawing units m
// draw text-label (in centimeters) nearest of arrow
_ltow( (long)(distance * iUserUnits), sDistance, 10 );
hr = IAcadModelSpace_AddText(pModelSpace, sDistance, vpT, 0.15*dArrowScale, &pText);
IAcadText_Update(pText);
}

return vpT;
}

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1642
Re: Pelles-C + OLE for access to AutoCAD
« Reply #31 on: June 28, 2016, 04:08:39 pm »
Code: [Select]
HRESULT (STDMETHODCALLTYPE *AddText)(IAcadModelSpace *This, BSTR TextString, VARIANT InsertionPoint, DOUBLE Height, IAcadText* *pResult); //!< Creates a single line of textSo use BSTR.
May the source be with you

Offline sergey

  • Member
  • *
  • Posts: 97
Re: Pelles-C + OLE for access to AutoCAD
« Reply #32 on: June 29, 2016, 06:01:25 pm »
Arrows (polylines) are now created (!!!).
The problem was in the third coordinate point: dblPnt1[2].

I changed the text of the declaration, but that nothing has changed.
The text is not created in any versions of the code, even if the test is introduced as:
Code: [Select]
IAcadModelSpace_AddText(pModelSpace, L"Text-test", vpT, 2.0, ppText);
Similarly, not created, and multi-line text.

Code: [Select]
double dblPnt[3], dblPnt1[3], dblPnt2[3]; // X,Y,Z arrays

VARIANT rotpnt (IAcadUtility* pUtility, IAcadModelSpace* pModelSpace)
{
HRESULT hr;
VARIANT vp1; // TypedArray for Text insertion-point
SAFEARRAY* psarrayP = SafeArrayCreateVector(VT_VARIANT, 0, 3);

// rotation point BasePoint
((VARIANT*)psarrayP->pvData)[0].vt = VT_R8;
((VARIANT*)psarrayP->pvData)[0].dblVal = dblPnt1[0];
((VARIANT*)psarrayP->pvData)[1].vt = VT_R8;
((VARIANT*)psarrayP->pvData)[1].dblVal = dblPnt1[1];
((VARIANT*)psarrayP->pvData)[2].vt = VT_R8;
((VARIANT*)psarrayP->pvData)[2].dblVal = dblPnt1[2];

// sarray for LWPoly inserted in vpnt
hr = IAcadUtility_CreateTypedArray(pUtility, &vp1, VT_R8, psarrayP);
SafeArrayDestroy(psarrayP);  // free array

return vp1;
}


IAcadText* *ppText = NULL;

VARIANT rottxt (IAcadUtility* pUtility, IAcadModelSpace* pModelSpace, double distance, double dArrowScale)
{
HRESULT hr;
VARIANT vpT; // TypedArray for Text insertion-point
SAFEARRAY* psarrayT = SafeArrayCreateVector(VT_VARIANT, 0, 3);
wchar_t sDistance[8];
//BSTR bstr = NULL;
// Text Insert point
((VARIANT*)psarrayT->pvData)[0].vt = VT_R8;
((VARIANT*)psarrayT->pvData)[0].dblVal = dblPnt1[0]+0.05*dArrowScale;
((VARIANT*)psarrayT->pvData)[1].vt = VT_R8;
((VARIANT*)psarrayT->pvData)[1].dblVal = dblPnt1[1]+0.05*dArrowScale;
((VARIANT*)psarrayT->pvData)[2].vt = VT_R8;
((VARIANT*)psarrayT->pvData)[2].dblVal = dblPnt1[2];

// sarray for BasePoint inserted in vp1
hr = IAcadUtility_CreateTypedArray(pUtility, &vpT, VT_R8, psarrayT);
SafeArrayDestroy(psarrayT);  // free array
// draw single-line Text in ModelSpace
if (!hr) {
// Architect drawing units mm, Geodetic drawing units m
// draw text-label (in centimeters) nearest of arrow
_ltow( (long)(distance * iUserUnits), sDistance, 10 );
BSTR bstr = NULL;
bstr = SysAllocString (sDistance);
hr = IAcadModelSpace_AddText(pModelSpace, bstr, vpT, 0.15*dArrowScale, ppText);
SysFreeString (bstr);
IAcadText_Update(*ppText);
}

return vpT;
}

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1642
Re: Pelles-C + OLE for access to AutoCAD
« Reply #33 on: June 29, 2016, 07:56:19 pm »
I think this works:
Code: [Select]
...
VARIANT vpt1; // for points
BSTR bstr;
IAcadText *pText;
hr = CadCreateUtilityPoint(pUtility, &vpt1, 0.0, 0.0, 0.0);
if (!hr) {
bstr = SysAllocString(L"Test text");
hr = IAcadModelSpace_AddText(pModelSpace, bstr, vpt1, 10.0, &pText);
if (pText) IAcadEntity_Rotate((IAcadEntity*)pText, vpt1, (45*M_PI/180));
SysFreeString(bstr);
VariantClear(&vpt1);
}
...
Code: [Select]
HRESULT CadCreateUtilityPoint(IAcadUtility *pUtility, VARIANT *vpt1, double x, double y, double z)
{
HRESULT hr;
SAFEARRAY* psarr = SafeArrayCreateVector(VT_VARIANT, 0, 3);
((VARIANT*)psarr->pvData)[0].vt = VT_R8;
((VARIANT*)psarr->pvData)[0].dblVal = x;
((VARIANT*)psarr->pvData)[1].vt = VT_R8;
((VARIANT*)psarr->pvData)[1].dblVal = y;
((VARIANT*)psarr->pvData)[2].vt = VT_R8;
((VARIANT*)psarr->pvData)[2].dblVal = z;
hr = IAcadUtility_CreateTypedArray(pUtility, vpt1, VT_R8, psarr);
SafeArrayDestroy(psarr); // free array
if (hr) ErrorString(hr);
return hr;
}

HRESULT CadCreateUtilityPoints(IAcadUtility *pUtility, VARIANT *vpt1, int nCount, double  dblPoints[])
{
HRESULT hr;
SAFEARRAY* psarr = SafeArrayCreateVector(VT_VARIANT, 0, nCount);
for (int i = 0; i < nCount; i++) {
((VARIANT*)psarr->pvData)[i].vt = VT_R8;
((VARIANT*)psarr->pvData)[i].dblVal = dblPoints[i];
}
hr = IAcadUtility_CreateTypedArray(pUtility, vpt1, VT_R8, psarr);
SafeArrayDestroy(psarr); // free array
if (hr) ErrorString(hr);
return hr;
}
« Last Edit: June 29, 2016, 09:15:21 pm by TimoVJL »
May the source be with you

Offline sergey

  • Member
  • *
  • Posts: 97
Re: Pelles-C + OLE for access to AutoCAD
« Reply #34 on: June 29, 2016, 11:58:05 pm »
Еще раз спасибо!
Danke nochmals!
Thanks again!


I still think that without VARIANT-type in the library (and as a whole in AutoCAD) creation of a working code would be much easier and more correct.

Here's how it looks now.
A little more work and we can forget about this monster called "Computer drawing assistant".
There are others more worthy and understandable programs.

Offline sergey

  • Member
  • *
  • Posts: 97
Re: Pelles-C + OLE for access to AutoCAD
« Reply #35 on: June 30, 2016, 11:10:25 pm »
He remembered that no management layers and color, little programs for practical work. Therefore, I decided to slightly improve the program:
1.
For the arrows to create a new layer called 'Arrows'
For inscriptions deviation creates a new layer called 'OrtoDiff'
But here I waited for surprises from AutoDesk.
The second layer is not created and the program crashes.
Quote from AutoDesk:
"Layers Collection: To add a new member to the collection, use the Add method."
Code: [Select]
IAcadLayers* pLayers = NULL;
IAcadLayer* pLayer1;
IAcadLayer* pLayer2;

void SetLayer1 (void)
{
VARIANT_BOOL *pbRes = NULL;

// add new layer for 'Arrows' (Strelka)
IAcadDatabase_get_Layers(pDataBase, &pLayers);
// add new layer  for 'Arrows' (Strelka)
IAcadLayers_Add(pLayers, L"Arrows", &pLayer1);
IAcadLayer_put_color(pLayer1, acGreen);
IAcadLayer_get_LayerOn(pLayer1, pbRes);
// and make layer active
IAcadDocument_put_ActiveLayer(pACadDoc, pLayer1);
}

void SetLayer2 (void)
{
VARIANT_BOOL *pbRes = NULL;

// add new layer for 'OrtoDiff' text-labels
IAcadDatabase_get_Layers(pDataBase, &pLayers);
// add new layer  for 'Arrows' (Strelka)
IAcadLayers_Add(pLayers, L"OrtoDiff", &pLayer2);
IAcadLayer_put_color(pLayer2, acRed);
IAcadLayer_get_LayerOn(pLayer2, pbRes);
// and make layer active
IAcadDocument_put_ActiveLayer(pACadDoc, pLayer2);
}

2.
And again, the value is often the result of deviations from the project are normalized (eg construction).
Therefore, he added combo box to set the limit of the normalized deviations.
For values above the limit, the text color of the deviation varies from green to red.
Then these inscriptions are clearly visible.
It turned out that to change the text color is not easy.
These two options do not work:
Code: [Select]
IAcadAcCmColor* pAcCmColor;
// IAcadAcCmColor_put_ColorIndex(pAcCmColor, 1);
// IAcadEntity_put_TrueColor(pText, pAcCmColor);

// IAcadAcCmColor_SetRGB(pAcCmColor, (LONG)1024, (LONG)64, (LONG)64);
// IAcadEntity_put_TrueColor((IAcadEntity*)pText, pAcCmColor);
However, more complex than the text of the object is done as follows:
Code: [Select]
//!< Specifies the color of the dimension text (DIMCLRT system variable)
hr=put_TextColor(IAcadDimAligned *This, ACAD_COLOR TextColor);
3.
Before exiting the program is executed drawing regeneration:
Code: [Select]
bstr = SysAllocString (L"_REGENALL ");
IAcadDocument_SendCommand(pACadDoc, bstr);

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1642
Re: Pelles-C + OLE for access to AutoCAD
« Reply #36 on: July 01, 2016, 08:50:23 am »
1:
Code: [Select]
HRESULT (STDMETHODCALLTYPE *Add)(IAcadLayers *This, BSTR Name, IAcadLayer* *pResult);
Code: [Select]
...
IAcadLayers* pLayers = NULL;
IAcadDatabase_get_Layers(pDataBase, &pLayers);
if (pLayers) {
IAcadLayer* pLayer1;
IAcadLayer* pLayer2;
BSTR bstr;
bstr = SysAllocString(L"Layer1");
IAcadLayers_Add(pLayers, bstr, &pLayer1);
SysFreeString(bstr);
if (pLayer1) {
IAcadLayer_put_color(pLayer1, acGreen);
IAcadLayer_Release(pLayer1);
}
bstr = SysAllocString(L"Layer2");
IAcadLayers_Add(pLayers, bstr, &pLayer2);
SysFreeString(bstr);
if (pLayer2) {
IAcadLayer_put_color(pLayer2, acRed);
IAcadLayer_Release(pLayer2);
}
IAcadLayers_Release(pLayers);
}
...
2:
Code: [Select]
...
if (pText) {
IAcadAcCmColor* pAcCmColor;
IAcadText_get_TrueColor(pText, &pAcCmColor);
if (pAcCmColor) {
IAcadAcCmColor_SetRGB(pAcCmColor, 255, 64, 64);
IAcadText_put_TrueColor(pText, pAcCmColor);
IAcadAcCmColor_Release(pAcCmColor);
}
//IAcadText_put_color(pText, acBlue);
IAcadText_Rotate(pText, vpt1, (45*M_PI/180));
IAcadText_Release(pText);
}
...
3:
Code: [Select]
...
IAcadApplication_Update(pCad);
...
« Last Edit: July 01, 2016, 10:28:18 am by TimoVJL »
May the source be with you

Offline sergey

  • Member
  • *
  • Posts: 97
Re: Pelles-C + OLE for access to AutoCAD
« Reply #37 on: July 02, 2016, 07:53:30 pm »
1.
Fixed code for 'Layers' and 'Colors' (from TimoVJL).
Code: [Select]
void SetLayers (void)
{
IAcadLayers* pLayers = NULL;
IAcadDatabase_get_Layers(pDataBase, &pLayers);
if (pLayers) {
BSTR bstr;
bstr = SysAllocString(L"OrtoDiff");
IAcadLayers_Add(pLayers, bstr, &pLayer2);
SysFreeString(bstr);
if (pLayer2) {
IAcadLayer_put_color(pLayer2, acGreen);
}
bstr = SysAllocString(L"Arrows");
IAcadLayers_Add(pLayers, bstr, &pLayer1);
SysFreeString(bstr);
if (pLayer1) {
IAcadLayer_put_color(pLayer1, acGreen);
IAcadDocument_put_ActiveLayer(pACadDoc, pLayer1);
}
IAcadLayers_Release(pLayers);
}
}
Code: [Select]
VARIANT rottxt ( ... )
...
if (pText && distance>(dTolerance*iUserUnits)) {
IAcadText_get_TrueColor(pText, &pAcCmColor);
if (pAcCmColor) {
IAcadAcCmColor_SetRGB(pAcCmColor, 255, 64, 64);
IAcadText_put_TrueColor(pText, pAcCmColor);
IAcadAcCmColor_Release(pAcCmColor);
}
//IAcadText_put_color(pText, acBlue);
IAcadText_Release(pText);
}
...
2.
Add calculate OrtoDiffs with Tolerance deviations.
3.
LogInFile() - ad function to write in logfile.txt session with Date-Time indication.
Code: [Select]
Log a meassured orto-diffs:
Date 02-07-16 Time 20-12-39
OrtoDiff=19.9797 TO BIG!!
OrtoDiff=20.0202 TO BIG!!
OrtoDiff=3.30772 accepted
OrtoDiff=5.82749 accepted
OrtoDiff=29.0576 TO BIG!!
OrtoDiff=25.3733 TO BIG!!
OrtoDiff=8.27729 accepted
OrtoDiff=34.4855 TO BIG!!
OrtoDiff=8.27729 accepted
OrtoDiff=34.4855 TO BIG!!
End of session: Time 20-13-30
« Last Edit: July 11, 2016, 01:55:41 pm by sergey »

Offline sergey

  • Member
  • *
  • Posts: 97
Re: Pelles-C + OLE for access to AutoCAD
« Reply #38 on: July 11, 2016, 01:53:37 pm »
Delaunay Triangulation - one more attractive for solving the problem in AutoCAD.
There are old, but the quality of C-source:
http://www.cs.cmu.edu/~quake/triangle.html
http://www.netlib.org/voronoi/triangle.zip
http://www.codeproject.com/KB/recipes/587629/triangulation-source.zip

For this we need to get from the drawing all '3dPoints' with their coordinates.
Function:
Code: [Select]
IAcadUtility_GetPoint (pUtility, Point, Prompt, & vpnt);gives the coordinates of points, but it works in the interactive mode, you have to manually Pick each point, so it is not applicable.

Function:
Code: [Select]
QueryInterface (IAcadUtility * This, GUID * riid, VOID ** ppvObj);in the cycle to give all the objects in the drawing, of which the object name 'AcDbPoint' need to create a list of coordinates.
This list is then passed to the triangulation functions.
But there is no function that identifies the coordinates of the object 'Entity'.
Code: [Select]
IAcadModelSpace_get_Count (pModelSpace, & nCount);
for (...) {
IAcadModelSpace_Item (pModelSpace, var, & pEntity);
IAcadUtility_QueryInterface (pUtility, (GUID *) & IID_IAcadEntity, (void **) pEntity);
IAcadEntity_get_EntityName (pEntity, & pResult);
// Call function:
getentcoords (pUtility, pEntity, dblPnt);
// ...
}
Here, there is a program crashing.

The structure 'Entity' as well as the structure 'Point' present its coordinates.
But how to get them?

After receiving the 'Entity -> Name==Point'
it is necessary to "tell the program", that:
pPoint == pEntity
or may be as follows:
ppPoint == ppEntity
to then get the coordinates, but it is impossible.

I suppose that such things exist functions:
Code: [Select]
get_Handle (IAcadModelSpace * This, BSTR * pResult);or:
Code: [Select]
get_ObjectID (IAcadModelSpace * This, LONG * pResult);but I found no indications for their use.

Got any bright ideas?

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1642
Re: Pelles-C + OLE for access to AutoCAD
« Reply #39 on: July 11, 2016, 04:31:00 pm »
Not so bright:
Code: [Select]
...
if (pEntity) {
IAcadPoint *pPoint = NULL;
hr = IAcadEntity_get_EntityName(pEntity, &bstr);
if (bstr) {
printf("\t%ls", bstr);
SysFreeString(bstr);
}
hr = ((IDispatch*)pEntity)->lpVtbl->QueryInterface((IDispatch*)pEntity, &IID_IAcadPoint, (void**)&pPoint);
if (!hr) {
VARIANT var1;
IAcadPoint_get_Coordinates(pPoint, &var1);
if (var1.vt == (VT_ARRAY | VT_R8)) {
printf("\t%f\t%f\t%f",
((double*)var1.parray->pvData)[0],
((double*)var1.parray->pvData)[1],
((double*)var1.parray->pvData)[2]
);
SafeArrayDestroy(var1.parray);
}
IAcadPoint_Release(pPoint);
}
printf("\n");
IAcadEntity_Release(pEntity);
}
...
« Last Edit: July 11, 2016, 06:05:57 pm by TimoVJL »
May the source be with you

Offline sergey

  • Member
  • *
  • Posts: 97
Re: Pelles-C + OLE for access to AutoCAD
« Reply #40 on: July 11, 2016, 05:32:05 pm »
Thank you. Let me see.

I have worked here such variant:
Code: [Select]
int getentcoords(IAcadEntity** pEntity)
{
HRESULT hr;
IDispatch *pDisp = NULL;
VARIANT var;
VariantInit(&var);

hr = IAcadEntity_Copy(*pEntity, &pDisp);
if (!hr) {
if (pDisp) {
hr = pDisp->lpVtbl->QueryInterface(pDisp, &IID_IAcadEntity, (void**)pEntity);
//char sVal[64];
//wchar_t* pResult;
//IAcadEntity_get_EntityName(*pEntity, &pResult);
//sprintf(sVal, TEXT("EntType=%p EntName %ls"), *pEntity, pResult);
//MessageBox(0, sVal, "Returned Entity Info", 0);
}
if (var.vt == (VT_ARRAY | VT_R8)) {
dblPnt[0] = ((double*)var.parray->pvData)[0];
dblPnt[1] = ((double*)var.parray->pvData)[1];
dblPnt[2] = ((double*)var.parray->pvData)[2];
SafeArrayDestroy(var.parray);
if (dblPnt[2] == 0) return hr;
//else: add dblPnt[] intolist-array
lPointsCount++;
}
}
if (!pDisp) {
*pEntity = NULL;
SafeArrayDestroy(var.parray);
return hr;
}
return hr;
}

I was wrong.
In my code, the coordinates are not available.
Your code works correctly - the coordinates there!
Thank you.
« Last Edit: July 11, 2016, 06:16:36 pm by sergey »

Offline sergey

  • Member
  • *
  • Posts: 97
Re: Pelles-C + OLE for access to AutoCAD
« Reply #41 on: August 12, 2016, 12:16:30 am »
First result to create 'Surface' from AutoCAD 3dPoints --> 3dFaces.
It's Delaunay-Triangulation.
To find 'Holes' in created 'Surface' need AutoCAD 'Hatch', but ...

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1642
Re: Pelles-C + OLE for access to AutoCAD
« Reply #42 on: August 12, 2016, 05:07:23 pm »
But IAcadModelSpace_AddHatch needs BSTR.
Code: [Select]
...
VARIANT vhot; vhot.vt = VT_I4; vhot.lVal = 0;
IAcadLWPolyline *pLWPL;
hr = CadCreateUtilityPoints(pUtility, &vpt1, 8, pts);
hr = IAcadModelSpace_AddLightWeightPolyline(pModelSpace, vpt1, &pLWPL);
bstr = SysAllocString(L"ANSI31");
hr = IAcadModelSpace_AddHatch(pModelSpace, 1, bstr, 1, vhot, &pHatch);
SysFreeString(bstr);
if (!hr) {
vobj.vt = VT_DISPATCH;
vobj.ppdispVal = (IDispatch **)pLWPL;
hr = IAcadHatch_AppendOuterLoop(pHatch, vobj);
if (hr) ErrorString(hr);
hr = IAcadHatch_Evaluate(pHatch);
} else ErrorString(hr);
VariantClear(&vpt1);
...
« Last Edit: August 13, 2016, 08:50:45 am by TimoVJL »
May the source be with you

Offline sergey

  • Member
  • *
  • Posts: 97
Re: Pelles-C + OLE for access to AutoCAD
« Reply #43 on: August 12, 2016, 11:30:20 pm »
Thank you for acax17enu.tlb.txt file - very comfortable to use.

Fixed function.
Here's how it looks now:
Code: [Select]
// check 3dFace-mesh: if Surface is created - Hatch all 3dFaces to view Holes
void FindHoles (IAcadUtility* pUtility, IAcadModelSpace* pModelSpace, VARIANT* varpntlist)
{
//acHatch = 17;
VARIANT vHatchType;
vHatchType.vt = VT_BOOL;
vHatchType.boolVal = 0;
BSTR bstr = NULL;
VARIANT vpnt; // TypedArray for LWPolyLine
SAFEARRAY* psarrayL = SafeArrayCreateVector(VT_VARIANT, 0, 8);
long i = 0;
char sVal[48];
long p0, p1, p2;

pFile2 = stdin;
freopen("triangles.txt","r",stdin);  // reopen file as stdin for read

while (scanf("%d %d %d", &p0, &p1, &p2) !=EOF) {
// make LWPolyline from varpoints of 3dFace
((VARIANT*)psarrayL->pvData)[0].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[0].dblVal = ((double*)varpntlist[p0].parray->pvData)[0];
((VARIANT*)psarrayL->pvData)[1].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[1].dblVal = ((double*)varpntlist[p0].parray->pvData)[1];
((VARIANT*)psarrayL->pvData)[2].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[2].dblVal = ((double*)varpntlist[p1].parray->pvData)[0];
((VARIANT*)psarrayL->pvData)[3].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[3].dblVal = ((double*)varpntlist[p1].parray->pvData)[1];
((VARIANT*)psarrayL->pvData)[4].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[4].dblVal = ((double*)varpntlist[p2].parray->pvData)[0];
((VARIANT*)psarrayL->pvData)[5].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[5].dblVal = ((double*)varpntlist[p2].parray->pvData)[1];
((VARIANT*)psarrayL->pvData)[6].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[6].dblVal = ((double*)varpntlist[p0].parray->pvData)[0];
((VARIANT*)psarrayL->pvData)[7].vt = VT_R8;
((VARIANT*)psarrayL->pvData)[7].dblVal = ((double*)varpntlist[p0].parray->pvData)[1];
// sarray for LWPoly inserted in vpnt
hr = IAcadUtility_CreateTypedArray(pUtility, &vpnt, VT_R8, psarrayL);
SafeArrayDestroy(psarrayL);  // free array
// draw LWPolyline in ModelSpace
if (!hr) {
hr = IAcadModelSpace_AddLightWeightPolyline(pModelSpace, vpnt, &pLWP);
IAcadLWPolyline_Update(pLWP);
}
bstr = SysAllocString(L"ANSI31");
hr = IAcadModelSpace_AddHatch(pModelSpace, 1, bstr, 1, vHatchType, &pHatch);
SysFreeString(bstr);
if (!hr) {
vpnt.vt = VT_DISPATCH;
vpnt.ppdispVal = (IDispatch **)pLWP;
hr = IAcadHatch_AppendOuterLoop(pHatch, vpnt);
if (hr) MessageBox(0, "hr error", "IAcadHatch_AppendOuterLoop", 0);
hr = IAcadHatch_Evaluate(pHatch);
MessageBox(0, "Hatch added", "AddHatch", 0);
i++;
}
else MessageBox(0, "hr error", "IAcadModelSpace_AddHatch", 0);
VariantClear(&vpnt);
}
sprintf(sVal, "End of Hatch 3dFaces: %d triangles", i);
MessageBox(0, sVal, "FindHoles", 0);
freopen("CON","r", stdin);
}
Not satisfied string:
Quote
hr = IAcadModelSpace_AddHatch (pModelSpace, 1, bstr, 1, vHatchType, & pHatch);

At the same time built a 1 polyline.
Then the following message:
Quote
else MessageBox (0, "hr error", "IAcadModelSpace_AddHatch", 0);
The program then falls.

Apparently the problem is ad declare of VARIANT 'vHatchType'

Here's my test drawing:

Offline sergey

  • Member
  • *
  • Posts: 97
Re: Pelles-C + OLE for access to AutoCAD
« Reply #44 on: August 22, 2016, 09:52:36 pm »
'Hatch' in AutoCAD for programming not an easy thing.
In the C-lang (unlike AutoLISP and VBA) function Hatch (AddHatch) does not work.
This is how it is written in the acax17enu.h (acax17enu.tlb):
hr = AddHatch (IAcadModelSpace * This, INT PatternType, BSTR PatternName, VARIANT_BOOL Associativity, VARIANT HatchObjectType, IAcadHatch * * pResult);
or through a macro:
IAcadModelSpace_AddHatch (This, PatternType, PatternName, Associativity, HatchObjectType, pResult);

Argument 'VARIANT HatchObjectType' not 'typedef enum acHatchObjectType'.
And if in AutoLISP or in VBA it's the optional argument (i.e., can be omitted), the C function without this argument does not work.
Nowhere except AddHatch function argument 'HatchObjectType' not found.
And so his "appearance" in the structure VARIANT unknown.

So, after many unsuccessful trials (and errors), after reading the forums on the theme of 'AutoCAD HATCH', had to use the function 'command' of AutoLISP.
This AutoLISP 'command' hatch successfully 3dFaces (according ACAD-Help it is impossible).
Also, the command-line, you can directly insert the various properties of the hatch.
In short: old AutoLISP rescued.

The attached archive example of creating a surface (Surface as TIN) from '3dFaces' on irregularly spaced points:
1 of the points existing in the current Drawing - button 'SURFACE',
2. the points X, Y, Z in the file 'points.txt' - Button 'Read File',

Same (1 and 2) can be performed using an external LISP program (DTM.lsp + DTM.dsl) Romanian programmer Nikolae Manda - button 'DTM LISP'.
These two files must be in the AutoCAD system folder, such as C:\Program Files\AutoCAD 20xx\Support\

The code that performs a triangulation:
vdefs.h
voron_main.c (main.c)
voronoi.c
geometry.c
heap.c
memory.c
edgelist.c
output.c
its author Steve J. Fortune ( (c)1987-1992 years).
Despite the age of the code, it took quite a bit fixes for inclusion in the project.

There are other available sources, such as Clarkson-Delaunay - Ken Clarkson (c) 1995

Almost everything that is in the public domain triangulate the so-called 'Convex Hull'.
For serious work requires the implementation of "Delaunay triangulation to the conditions," and like all serious in the public domain is not available.

It is for the overall development:
http://algolist.manual.ru/maths/geom/
http://gts.sourceforge.net
« Last Edit: August 23, 2016, 06:24:55 pm by sergey »