Copy link to clipboard
Copied
Hi,everyone~
I am trying to make an AI plug-in based on CEP/HTML5 and C++.
But in the process of testing, I encountered a problem about AIAPI AIErr (*GetPathBezier) ( AIArtHandle path, ai::int16 segNumber, AIRealBezier *bezier ); function.
The specific problems are as follows:
1)Bulided 2020 SDK files as an .aip file.
2)Start AI software, and then enter GetPathBezier function for the first time, this time I can get bezier parameter correct.
3)Start the plug-in and will enter the GetPathBezier function again. At this time, the values of parameters path, segNumber have no change compared with the first time, but the bezier parameter is wrong.
I checked that the plug-in did nothing else before calling GetPathBezier function a second time, so I do not know why.
Please confirm this problem, Thanks a lot.
Please refer to the attachment for details。Thanks.
 
 
 
Ok. That part, regarding acquiring suite, seems to be ok.
PushAppContext should be called whenever you want to invoke SDK API functions from non SDK events/notifiers (such as CSXS). It isn't however documented in detail anywhere.
It establishes the current document and view. Most SDK functions do not take a document or a view as a parameter, but use the current document or view as defined by the application context.Most plug-ins don't need to use these functions, because Illustrator manages the
...1. I am not sure about older SDK versions. It was then probably introduced at some point. As far as I can remember it was there in 2017 also, so it not introduced in latest SDK.
2. Yes it establish context only, which, by documentation, setup default document and view. But, as I said, it is poorly documented, so we don't know for sure what else it does.
Copy link to clipboard
Copied
Strange. How did you trigger function first time and how second time, via csxs event? If so, did you set app context?
AppContext appContext(gPlugin->GetPluginRef());
Copy link to clipboard
Copied
Also check function for errors. It will probably give you reasonable explanation in form of error code.
Copy link to clipboard
Copied
Hi, MilosR
Thanks for your reply.
>How did you trigger function first time and how second time, via csxs event?
The first time is through the following function call:
PlugMain()->handlerPluginCaller()->goMenuItem()
and second time is csxs event.
>If so, did you set app context?
yes, I set app context.
>Also check function for errors. It will probably give you reasonable explanation in form of error code.
Thanks for your prompt, I checked the return value of the GetPathBezier function, errorcode is always 0,
Could you check it again? Thanks a lot.
Copy link to clipboard
Copied
Hmm. Bug in SDK is not ruled out, however it is rare. How do you get pathArt in second case?
Copy link to clipboard
Copied
Hi,MilosR
I'm sorry to reply you so late.
>How do you get pathArt in second case?
The pathArt will be saved with a global variable during initialization.
By the way, I developed using existing code.The previous version can be obtained normally.
I made some major changes in this development:
1)SDK files changed from ver2014 to ver2020.
2)Compilation options changed from 32bit to 64bit.
After that, the above problems occurred when running the plug-in,first time OK, and second time NG.
Please confirm again, thanks a lot.
Copy link to clipboard
Copied
This still sounds to me like context is not set. Did you try some other API calls on csxs event? How did you set context, using AIAppContextSuite::PushAppContext?
Copy link to clipboard
Copied
I'm sorry, maybe I didn't make it clear about CSXS event.
In my current project, there is no event involved in calling GetPathBezier function.
I used GetPathBezier function like this:
==========
AIErr LoadPathBeziers( AIArtHandle pathArt, BezierModifyProc modifyBezier, AIRealBezier **bzOut, int *bzCnt ){
short segCount;
AIBoolean bClosed;
int bzIndex,cntLoad;
AIRealBezier bzTmp,bzMod;
sAIPath->GetPathSegmentCount( pathArt, &segCount );
sAIPath->GetPathClosed( pathArt, &bClosed );
cntLoad = bClosed ? segCount : segCount - 1; //beziers to load
(*bzOut) = (AIRealBezier *)realloc( (*bzOut), ((*bzCnt) + cntLoad)* sizeof(AIRealBezier) );
for( bzIndex = 0; bzIndex < cntLoad; bzIndex++ ){
sAIPath->GetPathBezier(pathArt, bzIndex, &bzTmp); ★
==========
I call it through the global variable sAIPath(Whether it's the first time or the second time).
and the declaration and assignment process of sAIPath is as follows:
==========
AIPathSuite *sAIPath;
==========
In SPErr PluginMain() function,
sAIPath gets the value through the SPErr (*AcquireSuite) function.
Therefore, the PushAppContext function is not used in my code.
If I follow the above workflow, do I still need to set the context? If so, could you tell me how to set it?
and how to use it.
Thanks a lot.
Copy link to clipboard
Copied
Ok. That part, regarding acquiring suite, seems to be ok.
PushAppContext should be called whenever you want to invoke SDK API functions from non SDK events/notifiers (such as CSXS). It isn't however documented in detail anywhere.
It establishes the current document and view. Most SDK functions do not take a document or a view as a parameter, but use the current document or view as defined by the application context.Most plug-ins don't need to use these functions, because Illustrator manages the context. In rare situations, however, a plug-in may need to make changes to the context. For example, if a plug-in is called directly by the operating system, Illustrator has not established the context. If the plug-in wants to make SDK calls in response, it should use PushAppContext() and PopAppContext().
On receiving event you should call PushAppContext, and when you finish PopAppContext from AIContextSuite. There is also a cpp AppContext wrapper, which is easier to use.
Just add
AppContext appContext(gPlugin->GetPluginRef());
in place where you receive CSXS event.
Copy link to clipboard
Copied
Hi,MilosR
Good news!
I tried to append the following code in csxs event function:
==========
static void PositionChangeFunc(const csxs::event::Event* const eventParam, void* const context)
{
// Add AppContext start.
AppContext appContext(g->pluginRef);
// Add AppContext end.
ExportVecDialogController *exportVecController = (ExportVecDialogController *)context;
std::string xmlString = eventParam->data;
==========
and GetPathBezier function can get the data correctly!!!
Thank you very much!!!
Copy link to clipboard
Copied
Hi,MilosR
Sorry to disturb you again.
According to your method, after I append AppContext, the code can run normally.
But there are two things I don't understand. Could you tell me?
1)Appcontext was not used in the 2014 SDK, but data can be obtained normally.
It is needed in the 2020 SDK. Is it because of any changes in the SDK?
2)AppContext only sets the context, which has no effect on other functions. If I understand right?
Thanks again for your advice.
Copy link to clipboard
Copied
1. I am not sure about older SDK versions. It was then probably introduced at some point. As far as I can remember it was there in 2017 also, so it not introduced in latest SDK.
2. Yes it establish context only, which, by documentation, setup default document and view. But, as I said, it is poorly documented, so we don't know for sure what else it does.
Copy link to clipboard
Copied
Hi,MilosR
Thank you very much for your help.
We have solved the problem successfully.