void multiAutocloseRegion(TStroke *stroke, const TMouseEvent &e) { TTool::Application *app = TTool::getApplication(); if (m_firstStroke) { multiApplyAutoclose(m_firstFrameId, getFrameId(), TRectD(), TRectD(), m_firstStroke, stroke); invalidate(); if (e.isShiftPressed()) { delete m_firstStroke; m_firstStroke = new TStroke(*stroke); m_firstFrameId = getFrameId(); } else { if (m_isXsheetCell) { app->getCurrentColumn()->setColumnIndex(m_currCell.first); app->getCurrentFrame()->setFrame(m_currCell.second); } else app->getCurrentFrame()->setFid(m_veryFirstFrameId); resetMulti(); } } else { m_isXsheetCell = app->getCurrentFrame()->isEditingScene(); // if (m_isXsheetCell) m_currCell = std::pair<int, int>(getColumnIndex(), getFrame()); m_firstStroke = new TStroke(*stroke); } return; }
void FullColorBrushTool::onActivate() { if (!m_notifier) m_notifier = new FullColorBrushToolNotifier(this); TTool::Application *app = getApplication(); if (app->getCurrentObject()->isSpline()) { m_currentColor = TPixel32::Red; return; } int styleIndex = app->getCurrentLevelStyleIndex(); TPalette *plt = app->getCurrentPalette()->getPalette(); if (plt) { int style = app->getCurrentLevelStyleIndex(); TColorStyle *colorStyle = plt->getStyle(style); m_currentColor = colorStyle->getMainColor(); } if (m_firstTime) { m_firstTime = false; m_thickness.setValue(TIntPairProperty::Value(FullcolorBrushMinSize, FullcolorBrushMaxSize)); m_pressure.setValue(FullcolorPressureSensibility ? 1 : 0); m_opacity.setValue(TDoublePairProperty::Value(FullcolorMinOpacity, FullcolorMaxOpacity)); m_hardness.setValue(FullcolorBrushHardness); } m_brushPad = ToolUtils::getBrushPad(m_thickness.getValue().second, m_hardness.getValue() * 0.01); setWorkAndBackupImages(); }
void RGBPickerTool::pickRect() { TImageP image = TImageP(getImage(false)); TTool::Application *app = TTool::getApplication(); TPaletteHandle *ph = app->getPaletteController()->getCurrentPalette(); int styleId = ph->getStyleIndex(); TPalette *palette = ph->getPalette(); TRectD area = m_selectingRect; if (!palette) return; if (m_selectingRect.x0 > m_selectingRect.x1) { area.x1 = m_selectingRect.x0; area.x0 = m_selectingRect.x1; } if (m_selectingRect.y0 > m_selectingRect.y1) { area.y1 = m_selectingRect.y0; area.y0 = m_selectingRect.y1; } m_selectingRect.empty(); if (area.getLx() <= 1 || area.getLy() <= 1) return; StylePicker picker(image, palette); // iwsw commented out temporarily // if (m_viewer->get3DLutUtil() && // Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) // m_viewer->get3DLutUtil()->bindFBO(); m_currentValue = picker.pickColor(area); // iwsw commented out temporarily // if (m_viewer->get3DLutUtil() && // Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) // m_viewer->get3DLutUtil()->releaseFBO(); }
void RGBPickerTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) { TTool::Application *app = TTool::getApplication(); TPaletteHandle *pltHandle = app->getPaletteController()->getCurrentPalette(); m_currentStyleId = pltHandle->getStyleIndex(); if (m_currentStyleId == 0) return; TColorStyle *colorStyle = pltHandle->getStyle(); if (colorStyle) m_oldValue = colorStyle->getMainColor(); if (m_pickType.getValue() == RECT_PICK) { m_selectingRect.x0 = e.m_pos.x; m_selectingRect.y0 = e.m_pos.y; m_selectingRect.x1 = e.m_pos.x; m_selectingRect.y1 = e.m_pos.y; m_drawingRect.x0 = pos.x; m_drawingRect.y0 = pos.y; m_drawingRect.x1 = pos.x; m_drawingRect.y1 = pos.y; invalidate(); return; } else if (m_pickType.getValue() == FREEHAND_PICK) { startFreehand(pos, convert(e.m_pos)); return; } else if (m_pickType.getValue() == POLYLINE_PICK) { addPointPolyline(pos, convert(e.m_pos)); return; } else { pick(e.m_pos); } }
void SkeletonTool::magicLink(int index) { if (index < 0 || index >= (int)m_magicLinks.size()) return; HookData h0 = m_magicLinks[index].m_h0; HookData h1 = m_magicLinks[index].m_h1; TTool::Application *app = TTool::getApplication(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); int columnIndex = app->getCurrentColumn()->getColumnIndex(); TStageObjectId id = TStageObjectId::ColumnId(columnIndex); TStageObject *obj = xsh->getStageObject(id); int parentColumnIndex = h1.m_columnIndex; TStageObjectId parentId = TStageObjectId::ColumnId(parentColumnIndex); std::string parentHandle = h1.getHandle(); std::string handle = ""; if (h0.m_columnIndex < 0) { handle = obj->getHandle(); } else { handle = h0.getHandle(); } //TUndoManager *undoManager = TUndoManager::manager(); //undoManager->beginBlock(); TStageObjectCmd::setHandle(id, handle, app->getCurrentXsheet()); TStageObjectCmd::setParent(id, parentId, parentHandle, app->getCurrentXsheet()); //undoManager->endBlock(); }
void onImageChanged() override { if (!m_multi.getValue()) return; TTool::Application *app = TTool::getApplication(); TXshSimpleLevel *xshl = 0; if (app->getCurrentLevel()->getLevel()) xshl = app->getCurrentLevel()->getSimpleLevel(); if (!xshl || m_level.getPointer() != xshl || (m_closeType.getValue() == RECT_CLOSE && m_selectingRect.isEmpty()) || ((m_closeType.getValue() == FREEHAND_CLOSE || m_closeType.getValue() == POLYLINE_CLOSE) && !m_firstStroke)) resetMulti(); else if (m_firstFrameId == getFrameId()) m_firstFrameSelected = false; // nel caso sono passato allo stato 1 e // torno all'immagine iniziale, torno allo // stato iniziale else { // cambio stato. m_firstFrameSelected = true; if (m_closeType.getValue() == RECT_CLOSE) { assert(!m_selectingRect.isEmpty()); m_firstRect = m_selectingRect; } } }
void resetMulti() { m_firstFrameSelected = false; m_firstRect.empty(); m_firstPoint = TPointD(); m_selectingRect.empty(); TTool::Application *app = TTool::getApplication(); m_level = app->getCurrentLevel()->getLevel() ? app->getCurrentLevel()->getSimpleLevel() : 0; m_firstFrameId = m_veryFirstFrameId = getFrameId(); m_firstStroke = 0; }
void FullColorBrushTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) { m_brushPos = m_mousePos = pos; TRasterImageP ri = (TRasterImageP)getImage(true); if (!ri) return; if (m_points.size() != 1) { double maxThickness = m_thickness.getValue().second; double thickness = m_pressure.getValue() ? computeThickness(e.m_pressure, m_thickness) : maxThickness; double opacity = (m_pressure.getValue() ? computeThickness(e.m_pressure, m_opacity) : m_opacity.getValue().second) * 0.01; TPointD rasCenter = ri->getRaster()->getCenterD(); TThickPoint point(pos + rasCenter, thickness); m_points.push_back(point); int m = m_points.size(); vector<TThickPoint> points; points.push_back(m_points[m - 3]); points.push_back(m_points[m - 2]); points.push_back(m_points[m - 1]); TRect bbox = m_brush->getBoundFromPoints(points); updateWorkAndBackupRasters(bbox); m_tileSaver->save(bbox); m_brush->addArc(points[0], points[1], points[2], m_oldOpacity, opacity); m_brush->updateDrawing(ri->getRaster(), m_backUpRas, m_currentColor, bbox, m_opacity.getValue().second * 0.01); TRectD invalidateRect = ToolUtils::getBounds(points, maxThickness); invalidate(invalidateRect.enlarge(2) - rasCenter); m_strokeRect += bbox; m_lastRect.empty(); } if (m_brush) { delete m_brush; m_brush = 0; } m_workRaster->unlock(); if (m_tileSet->getTileCount() > 0) { delete m_tileSaver; TTool::Application *app = TTool::getApplication(); TXshLevel *level = app->getCurrentLevel()->getLevel(); TXshSimpleLevelP simLevel = level->getSimpleLevel(); TFrameId frameId = getCurrentFid(); TRasterP ras = ri->getRaster()->extract(m_strokeRect)->clone(); TUndoManager::manager()->add(new FullColorBrushUndo(m_tileSet, simLevel.getPointer(), frameId, m_isFrameCreated, ras, m_strokeRect.getP00())); } notifyImageChanged(); m_strokeRect.empty(); }
bool SkeletonTool::doesApply() const { TTool::Application *app = TTool::getApplication(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); assert(xsh); TStageObjectId objId = app->getCurrentObject()->getObjectId(); if (objId.isColumn()) { TXshColumn *column = xsh->getColumn(objId.getIndex()); if (column && column->getSoundColumn()) return false; } return true; }
FullColorBrushToolNotifier::FullColorBrushToolNotifier(FullColorBrushTool *tool) : m_tool(tool) { TTool::Application *app = m_tool->getApplication(); TXshLevelHandle *levelHandle; if (app) levelHandle = app->getCurrentLevel(); bool ret = false; if (levelHandle) { bool ret = connect(levelHandle, SIGNAL(xshCanvasSizeChanged()), this, SLOT(onCanvasSizeChanged())); assert(ret); } }
void SkeletonTool::onActivate() { TTool::Application *app = TTool::getApplication(); if (m_firstTime) { m_globalKeyframes.setValue(SkeletonGlobalKeyFrame ? 1 : 0); m_mode.setValue(BUILD_SKELETON); // m_ikEnabled.setValue(SkeletonInverseKinematics ? 1 : 0); m_firstTime = false; } TStageObjectId objId = app->getCurrentObject()->getObjectId(); if (objId == TStageObjectId::NoneId) { int index = app->getCurrentColumn()->getColumnIndex(); objId = TStageObjectId::ColumnId(index); } // app->editStageObject(objId); }
void leftButtonDown(const TPointD &pos, const TMouseEvent &) override { TToonzImageP ti = TToonzImageP(getImage(true)); if (!ti) return; if (m_closeType.getValue() == RECT_CLOSE) { m_selecting = true; m_selectingRect.x0 = pos.x; m_selectingRect.y0 = pos.y; m_selectingRect.x1 = pos.x + 1; m_selectingRect.y1 = pos.y + 1; return; } else if (m_closeType.getValue() == FREEHAND_CLOSE) { startFreehand(pos); return; } else if (m_closeType.getValue() == POLYLINE_CLOSE) { addPointPolyline(pos); return; } else if (m_closeType.getValue() == NORMAL_CLOSE) { if (m_multi.getValue()) { TTool::Application *app = TTool::getApplication(); if (m_firstFrameSelected) { multiApplyAutoclose(m_firstFrameId, getFrameId()); invalidate(); if (m_isXsheetCell) { app->getCurrentColumn()->setColumnIndex(m_currCell.first); app->getCurrentFrame()->setFrame(m_currCell.second); } else app->getCurrentFrame()->setFid(m_veryFirstFrameId); resetMulti(); } else { m_isXsheetCell = app->getCurrentFrame()->isEditingScene(); // if (m_isXsheetCell) m_currCell = std::pair<int, int>(getColumnIndex(), getFrame()); m_firstFrameSelected = true; m_firstPoint = pos; } invalidate(); return; } m_selecting = false; applyAutoclose(ti); invalidate(); notifyImageChanged(); } }
void setCurrentColorWithUndo(const TPixel32 &color) { TTool::Application *app = TTool::getApplication(); TPaletteHandle *ph = app->getPaletteController()->getCurrentPalette(); int styleId = ph->getStyleIndex(); TPalette *palette = ph->getPalette(); TXshSimpleLevel *level = app->getCurrentLevel()->getSimpleLevel(); if (palette) TUndoManager::manager()->add( new UndoPickRGBM(palette, styleId, color, level)); setCurrentColor(color); if (level) { std::vector<TFrameId> fids; level->getFids(fids); invalidateIcons(level, fids); } }
void RGBPickerTool::onImageChanged() { if (m_currentStyleId != 0 && m_makePick && (m_pickType.getValue() == POLYLINE_PICK || m_pickType.getValue() == RECT_PICK)) { TTool::Application *app = TTool::getApplication(); TPaletteHandle *ph = app->getPaletteController()->getCurrentPalette(); int styleId = ph->getStyleIndex(); TPalette *palette = ph->getPalette(); TXshSimpleLevel *level = app->getCurrentLevel()->getSimpleLevel(); if (palette) TUndoManager::manager()->add( new UndoPickRGBM(palette, styleId, m_currentValue, level)); setCurrentColor(m_currentValue); if (level) { std::vector<TFrameId> fids; level->getFids(fids); invalidateIcons(level, fids); } } m_makePick = false; }
void updateLevel() { TTool::Application *app = TTool::getApplication(); if (!app->getCurrentLevel()->getLevel()) return; TXshSimpleLevelP xl = app->getCurrentLevel()->getLevel()->getSimpleLevel(); if (app->getCurrentFrame()->getFrameType() != TFrameHandle::LevelFrame) return; TFrameId fid = app->getCurrentFrame()->getFid(); TVectorImageP src = xl->getFrame(fid, true); int count = src->getStrokeCount(); for (int i = 1; i < 10; i++) { ++fid; if (!xl->isFid(fid)) { TVectorImageP vi = new TVectorImage(); xl->setFrame(fid, vi); } TVectorImageP vi = xl->getFrame(fid, true); TVectorImageP dst = src->clone(); deform(dst.getPointer(), src.getPointer(), (double)i / (double)9); count = dst->getStrokeCount(); vi->mergeImage(dst, TAffine()); app->getCurrentTool()->getTool()->notifyImageChanged(fid); } }
void RGBPickerTool::pick(TPoint pos) { TImageP image = TImageP(getImage(false)); TTool::Application *app = TTool::getApplication(); TPaletteHandle *ph = app->getPaletteController()->getCurrentPalette(); int styleId = ph->getStyleIndex(); TPalette *palette = ph->getPalette(); if (!palette) return; TRectD area = TRectD(pos.x - 1, pos.y - 1, pos.x + 1, pos.y + 1); StylePicker picker(image, palette); // iwsw commented out temporarily // if (m_viewer->get3DLutUtil() && // Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) // m_viewer->get3DLutUtil()->bindFBO(); m_currentValue = picker.pickColor(area); // iwsw commented out temporarily // if (m_viewer->get3DLutUtil() && // Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) // m_viewer->get3DLutUtil()->releaseFBO(); TXshSimpleLevel *level = app->getCurrentLevel()->getSimpleLevel(); UndoPickRGBM *cmd = new UndoPickRGBM(palette, styleId, m_currentValue, level); TUndoManager::manager()->add(cmd); cmd->redo(); /* setCurrentColor(m_currentValue); if(level) { vector<TFrameId> fids; level->getFids(fids); invalidateIcons(level,fids); } */ }
TAffine TTool::getCurrentObjectParentMatrix2() const { TTool::Application *app = m_application; TFrameHandle *fh = app->getCurrentFrame(); if (fh->isEditingLevel()) return TAffine(); int frame = fh->getFrame(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); TStageObjectId id = app->getCurrentObject()->getObjectId(); double objZ = xsh->getZ(id, frame); TStageObjectId parentId = xsh->getStageObjectParent(id); if (parentId == TStageObjectId::NoneId) return TAffine(); id = parentId; TAffine objPlacement = xsh->getPlacement(id, frame); TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); TStageObject *camera = xsh->getStageObject(cameraId); TAffine cameraPlacement = camera->getPlacement(frame); double cameraZ = camera->getZ(frame); TAffine placement; TStageObject::perspective(placement, cameraPlacement, cameraZ, objPlacement, objZ, 0); return placement; }
void RGBPickerTool::pickStroke() { TImageP image = TImageP(getImage(false)); TTool::Application *app = TTool::getApplication(); TPaletteHandle *ph = app->getPaletteController()->getCurrentPalette(); int styleId = ph->getStyleIndex(); TPalette *palette = ph->getPalette(); if (!palette) return; StylePicker picker(image, palette); TStroke *stroke = new TStroke(*m_stroke); // iwsw commented out temporarily // if (m_viewer->get3DLutUtil() && // Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) // m_viewer->get3DLutUtil()->bindFBO(); m_currentValue = picker.pickColor(stroke); // iwsw commented out temporarily // if (m_viewer->get3DLutUtil() && // Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) // m_viewer->get3DLutUtil()->releaseFBO(); if (!(m_pickType.getValue() == POLYLINE_PICK)) { TXshSimpleLevel *level = app->getCurrentLevel()->getSimpleLevel(); TUndoManager::manager()->add( new UndoPickRGBM(palette, styleId, m_currentValue, level)); setCurrentColor(m_currentValue); if (level) { std::vector<TFrameId> fids; level->getFids(fids); invalidateIcons(level, fids); } } }
void SkeletonTool::draw() { // parent object reference system //glColor3d(1,0,0); //tglDrawRect(0,0,100,100); if (m_label != "") ToolUtils::drawBalloon(m_labelPos, m_label, TPixel32::Red, TPoint(20, -20), false); bool ikEnabled = m_mode.getValue() == INVERSE_KINEMATICS; assert(glGetError() == GL_NO_ERROR); // l'xsheet, oggetto (e relativo placement), frame corrente TTool::Application *app = TTool::getApplication(); TXsheet *xsh = getXsheet(); assert(xsh); TStageObjectId objId = app->getCurrentObject()->getObjectId(); // se l'oggetto corrente non e' una colonna non disegno nulla if (!objId.isColumn()) return; TStageObject *pegbar = xsh->getStageObject(objId); int col = objId.getIndex(); int frame = app->getCurrentFrame()->getFrame(); if (m_currentFrame != frame) m_temporaryPinnedColumns.clear(); TAffine aff = getMatrix(); // puo' suggere che il placement degeneri (es.: c'e' uno h-scale = 0%) if (fabs(aff.det()) < 0.00001) return; // m_unit = getPixelSize() * sqrt(fabs(aff.det())); if (!ikEnabled) drawLevelBoundingBox(frame, col); glPushMatrix(); tglMultMatrix(aff.inv()); // camera stand reference system //glColor3d(0,1,0); //tglDrawRect(0,0,100,100); bool changingParent = dynamic_cast<ParentChangeTool *>(m_dragTool) != 0; // !changingParent && if (m_mode.getValue() == BUILD_SKELETON && !xsh->getStageObjectParent(objId).isColumn()) { if (!changingParent) drawHooks(); } Skeleton skeleton; buildSkeleton(skeleton, col); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); drawSkeleton(skeleton, frame); glDisable(GL_BLEND); TXshCell cell = xsh->getCell(frame, objId.getIndex()); Skeleton::Bone *rootBone = skeleton.getRootBone(); for (int i = 0; i < skeleton.getBoneCount(); i++) { Skeleton::Bone *bone = skeleton.getBone(i); TStageObjectId currentId = bone->getStageObject()->getId(); bool isCurrent = (currentId == objId); TPointD pos = bone->getCenter(); if (isCurrent && m_mode.getValue() != BUILD_SKELETON) { drawDrawingBrowser(cell, pos); } bool isActiveChain = bone->isSelected(); glColor3d(0, 1, 0); if (ikEnabled) { drawIKJoint(bone); } else { TPointD pos = bone->getCenter(); if (isCurrent && m_mode.getValue() == ANIMATE) { drawMainGadget(pos); } } } m_currentFrame = frame; if (m_dragTool) m_dragTool->draw(); glPopMatrix(); }
void leftButtonUp(const TPointD &pos, const TMouseEvent &e) override { TToonzImageP ti = TToonzImageP(getImage(true)); if (!ti) return; /*-- Rectの座標の向きを揃える --*/ if (m_selectingRect.x0 > m_selectingRect.x1) tswap(m_selectingRect.x1, m_selectingRect.x0); if (m_selectingRect.y0 > m_selectingRect.y1) tswap(m_selectingRect.y1, m_selectingRect.y0); TTool::Application *app = TTool::getApplication(); m_selecting = false; TRasterCM32P ras; if (m_closeType.getValue() == RECT_CLOSE) { if (m_multi.getValue()) { if (m_firstFrameSelected) { multiApplyAutoclose(m_firstFrameId, getFrameId(), m_firstRect, m_selectingRect); invalidate(m_selectingRect.enlarge(2)); if (e.isShiftPressed()) { m_firstRect = m_selectingRect; m_firstFrameId = getFrameId(); } else { if (m_isXsheetCell) { app->getCurrentColumn()->setColumnIndex(m_currCell.first); app->getCurrentFrame()->setFrame(m_currCell.second); } else app->getCurrentFrame()->setFid(m_veryFirstFrameId); resetMulti(); } } else { m_isXsheetCell = app->getCurrentFrame()->isEditingScene(); // if (m_isXsheetCell) m_currCell = std::pair<int, int>(getColumnIndex(), this->getFrame()); } return; } /*-- AutoCloseが実行されたか判定する --*/ if (!applyAutoclose(ti, m_selectingRect)) { if (m_stroke) { delete m_stroke; m_stroke = 0; } invalidate(); return; } invalidate(); notifyImageChanged(); } else if (m_closeType.getValue() == FREEHAND_CLOSE) { closeFreehand(pos); if (m_multi.getValue()) multiAutocloseRegion(m_stroke, e); else applyAutoclose(ti, TRectD(), m_stroke); m_track.clear(); invalidate(); } if (m_stroke) { delete m_stroke; m_stroke = 0; } }
void SkeletonTool::drawHooks() { // camera stand reference system //glColor3d(0,0,1); //tglDrawRect(3,3,97,97); //glColor3d(0,1,1); //tglDrawRect(0,100,Stage::inch,110); QTime time; time.start(); m_magicLinks.clear(); computeMagicLinks(); TTool::Application *app = TTool::getApplication(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); int row = app->getCurrentFrame()->getFrame(); int col = app->getCurrentColumn()->getColumnIndex(); TPointD dpiScale = getViewer()->getDpiScale(); // glColor3d(1,0,1); // tglDrawRect(-100*dpiScale.x, -100*dpiScale.y, 0,0); // I should not show hooks of columns already connected with the current one // ("linking" to those hooks would create evil loops in the hierarchy) std::set<int> connectedColumns; getConnectedColumns(connectedColumns, xsh, col); std::vector<HookData> currentColumnHooks; std::vector<HookData> otherColumnsHooks; // fill currentColumnHooks // detect otherColumn (i.e. the active column during a click&drag operator int otherColumn = -1; if (m_parentProbeEnabled) { // qDebug(" parent probe enabled"); // currentColumnHooks <- current column & current handle int hookId = 0; std::string handle = xsh->getStageObject(TStageObjectId::ColumnId(col))->getHandle(); if (handle.find("H") == 0) { int j = 1; while (j < (int)handle.size() && '0' <= handle[j] && handle[j] <= '9') { hookId = hookId * 10 + (int)handle[j] - '0'; j++; } } currentColumnHooks.push_back(HookData(xsh, col, hookId, m_parentProbe)); // otherColumn = "picked" column not connected TPoint parentProbePos = getViewer()->worldToPos(m_parentProbe); std::vector<int> indexes; getViewer()->posToColumnIndexes(parentProbePos, indexes, getPixelSize() * 10, false); for (int i = (int)indexes.size() - 1; i >= 0; i--) { if (connectedColumns.count(indexes[i]) == 0) { otherColumn = indexes[i]; break; } } // if the mouse is not on a stroke, I'm using the "old" m_otherColumn, if any. // (this is needed because of the hooks put inside of unfilled regions) if (otherColumn < 0 && m_otherColumn >= 0) { if (m_otherColumnBBox.contains(m_otherColumnBBoxAff.inv() * m_parentProbe)) otherColumn = m_otherColumn; else m_otherColumn = -1; } } else { // parent probe not enabled: get all hooks of current column. other column = -1 getHooks(currentColumnHooks, xsh, row, col, TPointD(1, 1)); // dpiScale); } // other columns hooks <- all hooks of all unlinked columns for (int i = 0; i < xsh->getColumnCount(); i++) if (xsh->getColumn(i)->isCamstandVisible()) if (connectedColumns.count(i) == 0) getHooks(otherColumnsHooks, xsh, row, i, TPointD(1, 1)); // dpiScale); /* qDebug(" time=%dms", time.elapsed()); qDebug(" %d hooks (current column)", currentColumnHooks.size()); for(int i=0;i<(int)currentColumnHooks.size();i++) qDebug(" %d,%d",currentColumnHooks[i].m_columnIndex,currentColumnHooks[i].m_hookId); qDebug(" %d hooks (other columns)", otherColumnsHooks.size()); for(int i=0;i<(int)otherColumnsHooks.size();i++) qDebug(" %d,%d",otherColumnsHooks[i].m_columnIndex,otherColumnsHooks[i].m_hookId); */ std::vector<TRectD> balloons; // draw current column hooks for (int i = 0; i < (int)currentColumnHooks.size(); i++) { const HookData &hook = currentColumnHooks[i]; if (hook.m_name == "") continue; // should not happen int code = TD_Hook + hook.m_hookId; TPointD pos = hook.m_pos; ToolUtils::drawHook(pos, ToolUtils::OtherLevelHook); glPushName(code); TPixel32 color(200, 220, 205, 200); if (hook.m_isPivot) color = TPixel32(200, 200, 10, 200); else if (code == m_device) color = TPixel32(185, 255, 255); ToolUtils::drawBalloon(pos, hook.m_name, color, TPoint(20, 20), isPicking(), &balloons); glPopName(); } if (m_parentProbeEnabled) { for (int i = 0; i < (int)otherColumnsHooks.size(); i++) ToolUtils::drawHook(otherColumnsHooks[i].m_pos, ToolUtils::OtherLevelHook); } // search for magic links double minDist2 = 0; double snapRadius2 = 100 * getPixelSize() * getPixelSize(); double snapRadius2bis = 100; if (!m_parentProbeEnabled) { // "static" magic links: no parent probe for (int i = 0; i < (int)currentColumnHooks.size(); i++) { for (int j = 0; j < (int)otherColumnsHooks.size(); j++) { double dist2 = norm2(currentColumnHooks[i].m_pos - otherColumnsHooks[j].m_pos); if (currentColumnHooks[i].m_hookId == 0 || otherColumnsHooks[j].m_hookId == 0) continue; if (dist2 < snapRadius2bis) { m_magicLinks.push_back(MagicLink(currentColumnHooks[i], otherColumnsHooks[j], dist2)); qDebug(" magic link_a %d (%d,%d) %d (%d,%d); dist=%f", i, currentColumnHooks[i].m_columnIndex, currentColumnHooks[i].m_hookId, j, otherColumnsHooks[j].m_columnIndex, otherColumnsHooks[j].m_hookId, dist2); } } } } if (m_parentProbeEnabled) { // search for the closest hook of the picked column int i = -1, j = -1; double minDist2 = snapRadius2; for (i = 0; i < (int)otherColumnsHooks.size(); i++) { double dist2 = tdistance2(otherColumnsHooks[i].m_pos, m_parentProbe); if (dist2 < minDist2) { j = i; minDist2 = dist2; otherColumn = otherColumnsHooks[i].m_columnIndex; } } } if (m_parentProbeEnabled && otherColumn >= 0) // && m_magicLinks.empty() { // "dynamic" magic links: probing and picking a column // show image bounding box m_otherColumn = otherColumn; getImageBoundingBox(m_otherColumnBBox, m_otherColumnBBoxAff, row, otherColumn); if (!m_otherColumnBBox.isEmpty()) { glPushMatrix(); tglMultMatrix(m_otherColumnBBoxAff); ToolUtils::drawRect(m_otherColumnBBox, TPixel32(188, 202, 191), 0xF0F0); //tglDrawRect(img->getBBox()); glPopMatrix(); } /* TXshCell cell = xsh->getCell(row, otherColumn); //TAffine aff = xsh->getPlacement(TStageObjectId::ColumnId(otherColumn),row); //m_otherColumnAff = aff; TImageP img = cell.getImage(false); if(img) { getImageBoundingBox(m_otherColumnBBox, m_otherColumnBBoxAff, row, otherColumn); //glColor3d(188.0/255.0, 202.0/255.0, 191.0/255.0); glPushMatrix(); tglMultMatrix(aff * imageDpiAff); ToolUtils::drawRect(img->getBBox(), TPixel32(188,202,191), 0xF0F0); //tglDrawRect(img->getBBox()); glPopMatrix(); } */ // search for the closest hook of the picked column int i = -1, j = -1; double minDist2 = snapRadius2; for (i = 0; i < (int)otherColumnsHooks.size(); i++) if (otherColumnsHooks[i].m_columnIndex == otherColumn) { double dist2 = tdistance2(otherColumnsHooks[i].m_pos, m_parentProbe); if (j < 0) j = i; else if (dist2 < minDist2 || otherColumnsHooks[i].m_hookId == 0) { j = i; minDist2 = dist2; } } // visualize a balloon for the closest hook if (0 <= j && j < (int)otherColumnsHooks.size()) { // I want to get a specific color when overlaying the label on white int alfa = 100, ialfa = 255 - alfa; TPixel32 color(255 * (188 - ialfa) / alfa, 255 * (202 - ialfa) / alfa, 255 * (191 - ialfa) / alfa, alfa); ToolUtils::drawBalloon( otherColumnsHooks[j].m_pos, otherColumnsHooks[j].m_name, // getHandle(), color, TPoint(20, 20), false, &balloons); HookData baseHook = currentColumnHooks[0]; baseHook.m_pos = otherColumnsHooks[j].m_pos; // this is also a magic link m_magicLinks.push_back(MagicLink(baseHook, otherColumnsHooks[j], 10000)); } } // visualize all the magic links for (int i = 0; i < (int)m_magicLinks.size(); i++) { const MagicLink &magicLink = m_magicLinks[i]; const HookData &h1 = magicLink.m_h1; std::string name; name = (m_parentProbeEnabled ? "Linking " : "Link ") + removeTrailingH(magicLink.m_h0.getHandle()) + " to Col " + std::to_string(h1.m_columnIndex + 1) + "/" + removeTrailingH(h1.getHandle()); int code = TD_MagicLink + i; glPushName(code); TPixel32 color(100, 255, 100, 100); if (code == m_device) color = TPixel32(185, 255, 255); ToolUtils::drawBalloon(magicLink.m_h0.m_pos, name, color, TPoint(20, -20), isPicking(), &balloons); glPopName(); } }
void SkeletonTool::leftButtonDown(const TPointD &ppos, const TMouseEvent &e) { m_otherColumn = -1; m_otherColumnBBox = TRectD(); m_otherColumnBBoxAff = TAffine(); m_labelPos = TPointD(0, 0); m_label = ""; TUndoManager::manager()->beginBlock(); if (!doesApply()) return; assert(m_dragTool == 0); m_dragTool = 0; TTool::Application *app = TTool::getApplication(); int currentColumnIndex = app->getCurrentColumn()->getColumnIndex(); TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet(); TPointD pos = ppos; int selectedDevice = pick(e.m_pos); // cambio drawing if (selectedDevice == TD_ChangeDrawing || selectedDevice == TD_IncrementDrawing || selectedDevice == TD_DecrementDrawing) { int d = 0; if (selectedDevice == TD_IncrementDrawing) d = 1; else if (selectedDevice == TD_DecrementDrawing) d = -1; m_dragTool = new ChangeDrawingTool(this, d); m_dragTool->leftButtonDown(ppos, e); return; } // click su un hook: attacca la colonna corrente tramite quell'hook if (TD_Hook <= selectedDevice && selectedDevice < TD_Hook + 50) { TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); TStageObjectId objId = TStageObjectId::ColumnId(currentColumnIndex); TPointD p0 = getCurrentColumnMatrix() * TPointD(0, 0); HookData hook(xsh, currentColumnIndex, selectedDevice - TD_Hook, p0); TStageObjectCmd::setHandle(objId, hook.getHandle(), app->getCurrentXsheet()); app->getCurrentXsheet()->notifyXsheetChanged(); invalidate(); return; } // magic link if (TD_MagicLink <= selectedDevice && selectedDevice < TD_MagicLink + (int)m_magicLinks.size()) { magicLink(selectedDevice - TD_MagicLink); app->getCurrentXsheet()->notifyXsheetChanged(); return; } m_device = selectedDevice; bool justSelected = false; if (m_device < 0) { // nessun gadget cliccato. Eventualmente seleziono la colonna std::vector<int> columnIndexes; getViewer()->posToColumnIndexes(e.m_pos, columnIndexes, getPixelSize() * 5, false); if (!columnIndexes.empty()) { int columnIndex; columnIndex = columnIndexes.back(); if (columnIndex >= 0 && columnIndex != currentColumnIndex) { if (!isColumnLocked(columnIndex)) { pos = getMatrix() * pos; app->getCurrentColumn()->setColumnIndex(columnIndex); updateMatrix(); currentColumnIndex = columnIndex; justSelected = true; pos = getMatrix().inv() * pos; } else { m_label = "Column is locked"; m_labelPos = pos; } } } } if (m_device < 0) { if (m_mode.getValue() == INVERSE_KINEMATICS) m_device = TD_InverseKinematics; else if (m_mode.getValue() == ANIMATE) m_device = TD_Rotation; } // lock/unlock: modalita IK if (TD_LockStageObject <= m_device && m_device < TD_LockStageObject + 1000) { int columnIndex = m_device - TD_LockStageObject; int frame = app->getCurrentFrame()->getFrame(); togglePinnedStatus(columnIndex, frame, e.isShiftPressed()); invalidate(); m_dragTool = 0; return; } switch (m_device) { case TD_Center: m_dragTool = new DragCenterTool(this); break; case TD_Translation: m_dragTool = new DragPositionTool(this); break; case TD_Rotation: m_dragTool = new DragRotationTool(this, justSelected); break; case TD_ChangeParent: m_dragTool = new ParentChangeTool(this, getViewer()); break; case TD_InverseKinematics: { Skeleton *skeleton = new Skeleton(); buildSkeleton(*skeleton, currentColumnIndex); m_dragTool = new IKTool(this, getViewer(), skeleton, currentColumnIndex); break; } } if (m_dragTool) { m_dragTool->leftButtonDown(pos, e); invalidate(); } }