For the SDK to assign a gradient to a fill color, does the gradient need first be added to swatches?

Engaged ,
Feb 22, 2021 Feb 22, 2021

Copy link to clipboard

Copied

Updated 2-26-21: I need to create custom gradients to apply to path fills, and studied the "SnpGradient.cpp" snippet file to create this test gradient.

image.png

 

 

The sample code adds the gradient to the Swatches  panel, but most of my gradients have no reason to be there, and adding them all would just fill the panel up! If I just apply the color to the pathstyle fill, it doesn't apply the gradient origin or other info and I get this:

gradient-bad.png

 

That's the gradient annotator all squashed into that {0,0} point! When I read in the pathstyle info back from the path art, I see that the other gradient info is there, but doesn't get applied. The gradient is defined earlier, and here's the code to apply it to the art:

 

 

 

AIColor swatchColor;
swatchColor.kind = kGradient;
swatchColor.c.b.gradient = gradient;
swatchColor.c.b.gradientAngle = 0;
swatchColor.c.b.gradientLength = 100;
swatchColor.c.b.gradientOrigin = {0,50};
swatchColor.c.b.hiliteAngle = 0;
swatchColor.c.b.hiliteLength = 0;
AIPathStyle pathStyle;
result = sAIPathStyle->GetPathStyle(tempart->aiArtHandle(), &pathStyle, nullptr);
AIColor color;
result = sAISwatchList->GetAIColor(swatch, &color);
pathStyle.fill.color = swatchColor;
pathStyle.fillPaint = true;
result = sAIPathStyle->SetPathStyle(tempart->aiArtHandle(), &pathStyle);
AIPathStyle pathStyle2;
result = sAIPathStyle->GetPathStyle(tempart->aiArtHandle(), &pathStyle2, nullptr);

 

 

 

Applying the color to the swatch list, then reading it back allows the art to honor the gradient origin, etc.

 

 

 

result = sAISwatchList->SetAIColor(swatch, &swatchColor);
result = sAIPathStyle->GetPathStyle(tempart->aiArtHandle(), &pathStyle, nullptr);
AIColor color;
result = sAISwatchList->GetAIColor(swatch, &color);
pathStyle.fill.color = color;

 

 

 

Shouldn't one be able to apply the gradient origin, length, and angle without setting a swatch in the swatch list and Swatch panel? Any suggestions would be very much appreciated!

TOPICS
SDK

Views

112

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct Answer

Engaged , Mar 03, 2021 Mar 03, 2021
Well, I got it to work!I didn't use the matrix at all. In order to position the gradient on the path, I had to add the color to the Swatches panel, then retrieve it again before applying it to the art. If I don't want a particular gradient swatch to stay in the panel, I have to manually remove it later. In the code below, the gradient has already been built, in the variable "gradient." The first line here creates an ellipse-shaped path art object in CORE. hdi::core::ArtAP tempart = hdi::core::d...

Likes

Translate

Translate
Engaged ,
Feb 26, 2021 Feb 26, 2021

Copy link to clipboard

Copied

I've discovered that AIArtStylePaintData includes a point member fillRelativeGradientOrigin that should also position the gradient origin. As an anonymous art style with a gradient not in the Swatches panel, these settings, applied with sAIArtStyle->SetArtStyle, seem to do nothing. Surely somebody knows how to do this...

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Mar 02, 2021 Mar 02, 2021

Copy link to clipboard

Copied

Try with AIArtStyleParserSuite::NewPaintFieldFill.

 

  1. Get existing style using AIArtStyleSuite::GetArtStyle 
  2. Create new parser using AIArtStyleParserSuite::NewParser 
  3. Use AIArtStyleParserSuite::ParseStyle to parse style from art 
  4. Use AIArtStyleParserSuite::NewPaintFieldFill to append new paint field, or GetNthPaintField and SetFill to edit existing. This functions accepts AIArtStylePaintData where you can set gradient options.
  5. Create new style from parser AIArtStyleParserSuite::CreateNewStyle
  6. Apply style to art using AIArtStyleSuite::SetArtStyle 
  7. Dispose parser

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 03, 2021 Mar 03, 2021

Copy link to clipboard

Copied

Thanks, Milos. I've tried variations of NewPaintFieldFill and GetNthPaintField, but nothing seems to work. The gradient annotator remains collapsed at the {0,0} point. I wish this were documented somewhere other than the cryptic header notes. With so many overlapping structs, I wonder if something gets set up correctly, then canceled out by a function that should apply it. I'll post results if I figure this out.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Mar 03, 2021 Mar 03, 2021

Copy link to clipboard

Copied

I am pretty sure we managed to do this at one point in our plugin, but I cannot remember how. Did you define gradient steps correctly? Also it is possible to apply transformations for gradient (using AITransformSuite::TransformArt), there is an option to apply transformation matrix only for gradients, you could try and play with that. 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 03, 2021 Mar 03, 2021

Copy link to clipboard

Copied

LATEST

Well, I got it to work!

Image.png

I didn't use the matrix at all. In order to position the gradient on the path, I had to add the color to the Swatches panel, then retrieve it again before applying it to the art. If I don't want a particular gradient swatch to stay in the panel, I have to manually remove it later.

 

In the code below, the gradient has already been built, in the variable "gradient." The first line here creates an ellipse-shaped path art object in CORE.

 

 

hdi::core::ArtAP tempart = hdi::core::draw::ellipse(hdi::core::ArtboardPoint(-20,150), 180, 180, true);

// define the swatch color
AISwatchRef swatch;
result = sAISwatchList->SetSwatchName(swatch, ai::UnicodeString("My test swatch"));

AIColor swatchColor;
swatchColor.kind = kGradient;
swatchColor.c.b.gradient = gradient;
swatchColor.c.b.gradientAngle = -90;
swatchColor.c.b.gradientLength = tempart->noStrokeBounds().size.height;
swatchColor.c.b.gradientOrigin = gradientStartPt(tempart->noStrokeBounds().topCenter());
swatchColor.c.b.hiliteAngle = 0;
swatchColor.c.b.hiliteLength = 0;

// add to swatch panel
AISwatchGroupRef swatchGroup;
swatchGroup = sAISwatchGroup->GetSwatchGroupByName(NULL, ai::UnicodeString("My Swatches"));
if (swatchGroup == NULL){
	result = sAISwatchGroup->NewSwatchGroup(NULL, kAISGKindGradientsOnly, -1, &swatchGroup);
	result = sAISwatchGroup->SetSwatchGroupName(swatchGroup, ai::UnicodeString("My Swatches"));
}
swatch = sAISwatchGroup->GetSwatchByName(swatchGroup, ai::UnicodeString("My test swatch"));
if (swatch == NULL)
	swatch = sAISwatchGroup->InsertNthSwatch(swatchGroup, &swatchColor, -1);


// get color from swatch panel
AIColor color;
result = sAISwatchList->GetAIColor(swatch, &color);

// apply color to art
AIPathStyle pathStyle;
pathStyle.fill.color = color;
pathStyle.fillPaint = true;
result = sAIPathStyle->SetPathStyle(tempart->aiArtHandle(), &pathStyle);

// remove the swatch from the panel if it won't be used again
result = sAISwatchGroup->RemoveSwatch(swatchGroup, swatch, false);

 

 

The swatches will be placed in my own group, and managed by swatch name.

 

I want my gradients to run top to bottom, so I set the gradient length to the object height. The gradient origin is essentially the art top-center, flipped vertically. I've included below a small function to convert the CORE artboard point to the adjusted AIRealPoint.

 

 

AIRealPoint test::Plugin::gradientStartPt(hdi::core::ArtboardPoint pt){
	AIRealPoint p;
	p.h = pt.x;
	p.v = pt.y * -1;
	return p;
}

 

 

 

 Now that my test code works, I'll clean it up to check error codes and use variables for the swatch and swatch group names. There's probably a better way to do it, but for now at least, this works!

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines