| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| using namespace PlasticToolLocals; |
| |
| |
| |
| |
| |
| namespace |
| { |
| |
| enum { RIGID_IDX = 0, |
| FLEX_IDX }; |
| |
| } |
| |
| |
| |
| |
| |
| namespace |
| { |
| |
| class PaintRigidityUndo : public TUndo |
| { |
| TXshCell m_cell; |
| std::vector<std::map<int, double>> m_vertices; |
| |
| double m_paintValue; |
| |
| public: |
| PaintRigidityUndo(const TXshCell &cell, |
| const std::vector<std::map<int, double>> &vertices, |
| double paintValue) |
| : m_cell(cell), m_vertices(vertices), m_paintValue(paintValue) {} |
| |
| int getSize() const { return 1 << 20; } |
| |
| void redo() const |
| { |
| TXshSimpleLevel *sl = static_cast<TXshSimpleLevel *>(m_cell.m_level.getPointer()); |
| sl->setDirtyFlag(true); |
| |
| TMeshImageP mi(sl->getFrame(m_cell.m_frameId, true)); |
| if (!mi || mi->meshes().size() != m_vertices.size()) |
| return; |
| |
| int m, mCount = int(mi->meshes().size()); |
| for (m = 0; m != mCount; ++m) { |
| TTextureMesh &mesh = *mi->meshes()[m]; |
| |
| std::map<int, double>::const_iterator vt, vEnd(m_vertices[m].end()); |
| for (vt = m_vertices[m].begin(); vt != vEnd; ++vt) |
| mesh.vertex(vt->first).P().rigidity = m_paintValue; |
| } |
| |
| PlasticDeformerStorage::instance()->invalidateMeshImage( |
| mi.getPointer(), PlasticDeformerStorage::MESH); |
| } |
| |
| void undo() const |
| { |
| TXshSimpleLevel *sl = static_cast<TXshSimpleLevel *>(m_cell.m_level.getPointer()); |
| sl->setDirtyFlag(true); |
| |
| TMeshImageP mi(sl->getFrame(m_cell.m_frameId, true)); |
| if (!mi || mi->meshes().size() != m_vertices.size()) |
| return; |
| |
| int m, mCount = int(mi->meshes().size()); |
| for (m = 0; m != mCount; ++m) { |
| TTextureMesh &mesh = *mi->meshes()[m]; |
| |
| std::map<int, double>::const_iterator vt, vEnd(m_vertices[m].end()); |
| for (vt = m_vertices[m].begin(); vt != vEnd; ++vt) |
| mesh.vertex(vt->first).P().rigidity = vt->second; |
| } |
| |
| PlasticDeformerStorage::instance()->invalidateMeshImage( |
| mi.getPointer(), PlasticDeformerStorage::MESH); |
| } |
| }; |
| |
| } |
| |
| |
| |
| |
| |
| namespace |
| { |
| |
| class RigidityPainter : public tcg::polymorphic |
| { |
| std::vector<std::map<int, double>> m_oldRigidities; |
| double m_sqRadius, m_value; |
| |
| public: |
| RigidityPainter() : m_sqRadius(), m_value() {} |
| |
| void startPainting(double radius, int rigidIdx); |
| void paint(const TPointD &pos); |
| void commit(); |
| |
| private: |
| void reset() |
| { |
| m_sqRadius = 0.0, m_value = 0.0; |
| std::vector<std::map<int, double>>().swap(m_oldRigidities); |
| } |
| }; |
| |
| |
| |
| void RigidityPainter::startPainting(double radius, int rigidIdx) |
| { |
| m_sqRadius = sq(radius); |
| m_value = (rigidIdx == RIGID_IDX) ? 1e4 : 1.0; |
| |
| assert(m_oldRigidities.empty()); |
| } |
| |
| |
| |
| void RigidityPainter::paint(const TPointD &pos) |
| { |
| const TXshCell &cell = ::xshCell(); |
| |
| TXshSimpleLevel *sl = dynamic_cast<TXshSimpleLevel *>(cell.m_level.getPointer()); |
| if (!sl) |
| return; |
| |
| TMeshImageP meshImg = TTool::getImage(true); |
| if (!meshImg) |
| return; |
| |
| |
| sl->setDirtyFlag(true); |
| |
| |
| const std::vector<TTextureMeshP> &meshes = meshImg->meshes(); |
| int m, mCount = int(meshImg->meshes().size()); |
| |
| m_oldRigidities.resize(mCount); |
| |
| for (m = 0; m != mCount; ++m) { |
| TTextureMesh &mesh = *meshes[m]; |
| |
| int v, vCount = mesh.verticesCount(); |
| for (v = 0; v != vCount; ++v) { |
| RigidPoint &vxPos = mesh.vertex(v).P(); |
| |
| if (tcg::point_ops::dist2(pos, (const TPointD &)vxPos) < m_sqRadius) { |
| if (!m_oldRigidities[m].count(v)) |
| m_oldRigidities[m][v] = vxPos.rigidity; |
| |
| vxPos.rigidity = m_value; |
| } |
| } |
| } |
| |
| PlasticDeformerStorage::instance()->invalidateMeshImage( |
| meshImg.getPointer(), PlasticDeformerStorage::MESH); |
| } |
| |
| |
| |
| void RigidityPainter::commit() |
| { |
| TUndoManager::manager()->add(new PaintRigidityUndo(::xshCell(), m_oldRigidities, m_value)); |
| reset(); |
| } |
| |
| } |
| |
| |
| |
| |
| |
| std::auto_ptr<tcg::polymorphic> PlasticTool::createRigidityPainter() |
| { |
| return std::auto_ptr<tcg::polymorphic>(new RigidityPainter); |
| } |
| |
| |
| |
| void PlasticTool::mouseMove_rigidity(const TPointD &pos, const TMouseEvent &e) |
| { |
| |
| m_pos = pos; |
| |
| invalidate(); |
| } |
| |
| |
| |
| void PlasticTool::leftButtonDown_rigidity(const TPointD &pos, const TMouseEvent &) |
| { |
| |
| m_pressedPos = m_pos = pos; |
| |
| RigidityPainter *painter = static_cast<RigidityPainter *>(m_rigidityPainter.get()); |
| |
| painter->startPainting(m_thickness.getValue(), m_rigidValue.getIndex()); |
| painter->paint(m_pos); |
| |
| invalidate(); |
| } |
| |
| |
| |
| void PlasticTool::leftButtonDrag_rigidity(const TPointD &pos, const TMouseEvent &) |
| { |
| |
| m_pos = pos; |
| |
| RigidityPainter *painter = static_cast<RigidityPainter *>(m_rigidityPainter.get()); |
| |
| painter->paint(m_pos); |
| invalidate(); |
| } |
| |
| |
| |
| void PlasticTool::leftButtonUp_rigidity(const TPointD &pos, const TMouseEvent &) |
| { |
| |
| m_pos = pos; |
| |
| RigidityPainter *painter = static_cast<RigidityPainter *>(m_rigidityPainter.get()); |
| |
| painter->commit(); |
| } |
| |
| |
| |
| void PlasticTool::addContextMenuActions_rigidity(QMenu *menu) |
| { |
| } |
| |
| |
| |
| void PlasticTool::draw_rigidity() |
| { |
| if (TTool::getApplication()->getCurrentFrame()->isEditingScene()) { |
| |
| |
| |
| |
| const TPointD &dpiScale = TTool::getViewer()->getDpiScale(); |
| glPushMatrix(); |
| { |
| tglMultMatrix(TScale(1.0 / dpiScale.x, 1.0 / dpiScale.y)); |
| |
| double pixelSize = sqrt(tglGetPixelSize2()); |
| |
| |
| const PlasticSkeletonP &skeleton = this->skeleton(); |
| if (skeleton) { |
| drawOnionSkinSkeletons_build(pixelSize); |
| drawSkeleton(*skeleton, pixelSize); |
| drawSelections(m_sd, *skeleton, pixelSize); |
| } |
| } |
| glPopMatrix(); |
| } |
| |
| |
| glColor3f(1.0f, 0.0f, 0.0f); |
| tglDrawCircle(m_pos, m_thickness.getValue()); |
| } |
| |