static OfxStatus interactPenDown(OfxImageEffectHandle effect, OfxInteractHandle interactInstance, OfxPropertySetHandle inArgs) { // get my data handle MyInteractData *data = getInteractData(interactInstance); double penPos[2]; gPropHost->propGetDoubleN(inArgs, kOfxInteractPropPenPosition, 2, penPos); Instance *instance = (Instance*)ofxuGetEffectInstanceData(effect); // Get the image size const std::pair<int, int> &size = instance->Mask.getSize (); data->DownX = (int)penPos[0]; data->DownY = size.second-(int)penPos[1]-1; data->Down = true; return kOfxStatOK; }
// draw an interact instance static OfxStatus interactDraw(OfxImageEffectHandle effect, OfxInteractHandle interactInstance, OfxPropertySetHandle drawArgs) { // get my private interact data MyInteractData *data = getInteractData(interactInstance); Instance *instance = (Instance*)ofxuGetEffectInstanceData(effect); if (data->Down) { double penPos[2]; gPropHost->propGetDoubleN(drawArgs, kOfxInteractPropPenPosition, 2, penPos); // Get the image size const std::pair<int, int> &size = instance->Mask.getSize (); const float x0 = (float)data->DownX; const float y0 = size.second-(float)data->DownY-1; const float x1 = (float)penPos[0]; const float y1 = (float)penPos[1]; glPushAttrib (GL_ENABLE_BIT|GL_CURRENT_BIT); // if the we have selected the Xhair, draw it highlit glColor3f(1, 1, 1); glEnable(GL_COLOR_LOGIC_OP); glLogicOp(GL_XOR); glLineStipple(1, 0xF0F0); glEnable(GL_LINE_STIPPLE); glBegin(GL_LINE_STRIP); glVertex2f(x0, y0); glVertex2f(x1, y0); glVertex2f(x1, y1); glVertex2f(x0, y1); glVertex2f(x0, y0); glEnd(); glPopAttrib (); } return kOfxStatOK; }
// Convinience wrapper to get private data static MyInstanceData * getMyInstanceData(OfxImageEffectHandle effect) { MyInstanceData *myData = (MyInstanceData *) ofxuGetEffectInstanceData(effect); return myData; }
static OfxStatus interactPenUp(OfxImageEffectHandle effect, OfxInteractHandle interactInstance, OfxPropertySetHandle inArgs) { // get my data handle MyInteractData *data = getInteractData(interactInstance); Instance *instance = (Instance*)ofxuGetEffectInstanceData(effect); double penPos[2]; gPropHost->propGetDoubleN(inArgs, kOfxInteractPropPenPosition, 2, penPos); if (data->Down) { // Get the image size const std::pair<int, int> &size = instance->Mask.getSize (); const int upX = (int)penPos[0]; const int upY = size.second-(int)penPos[1]-1; std::set<std::string> names; openexrid::Sample sample; const int alpha = instance->Mask.findSlice ("A"); const int maxX = std::min (std::max (upX, data->DownX)+1, size.first); const int maxY = std::min (std::max (upY, data->DownY)+1, size.second); for (int y = std::max (std::min (upY, data->DownY), 0); y < maxY; ++y) for (int x = std::max (std::min (upX, data->DownX), 0); x < maxX; ++x) { // Get the max coverage sample in the pixel float maxCoverage = 0; uint32_t maxId = ~0U; const int sampleN = instance->Mask.getSampleN (x, y); for (int s = 0; s < sampleN; ++s) { openexrid::Sample sample; instance->Mask.getSample (x, y, s, sample); if (alpha == -1 || sample.Values[alpha] > maxCoverage) { maxId = sample.Id; if (alpha != -1) maxCoverage = sample.Values[alpha]; } } // Found something ? if (maxId != ~0U) { const char *name = instance->Mask.getName (maxId); names.insert (escapeRegExp (name)); } } // Get the old pattern const char *_oldPattern; gParamHost->paramGetValue (data->patternParam, &_oldPattern); std::string oldPattern = _oldPattern; /* Nuke escapes the \ of the text parameter */ std::set<std::string> oldNames (split (oldPattern.c_str (), "\n\r")); // Shift ? if (data->Shift) { // Reverse the selection for the previously selected names for (const auto &name : oldNames) { // Try insert auto r = names.insert (name); // Already there, remove it if (!r.second) names.erase (r.first); } } // get the point param's value std::string pattern = join (names, "\n"); gParamHost->paramSetValue(data->patternParam, pattern.c_str ()); data->Down = false; } return kOfxStatOK; }