Skip to content

Commit

Permalink
point weight (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
shun-iwasawa authored Jan 30, 2024
1 parent a0aa564 commit f585f3a
Show file tree
Hide file tree
Showing 20 changed files with 572 additions and 123 deletions.
3 changes: 2 additions & 1 deletion sources/circletool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ CreateCircleShapeUndo::CreateCircleShapeUndo(QRectF& rect, IwProject* prj,
bpList << p[0] << p[1] << p[2] << p[3];

CorrPointList cpList;
cpList << 1.5 << 2.5 << 3.5 << 0.5;
CorrPoint c[4] = {{1.5, 1.0}, {2.5, 1.0}, {3.5, 1.0}, {0.5, 1.0}};
cpList << c[0] << c[1] << c[2] << c[3];

// 現在のフレーム
int frame = m_project->getViewFrame();
Expand Down
40 changes: 28 additions & 12 deletions sources/correspondencetool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,36 +65,37 @@ void CorrDragTool::onDrag(const QPointF& pos, const QMouseEvent* e) {
}

// 差分を得る
double dc = nearestBezierPos - m_orgCorrs.at(m_corrPointId);
double dc = nearestBezierPos - m_orgCorrs.at(m_corrPointId).value;

// 閉じたシェイプの場合、全部回す
if (m_shape.shapePairP->isClosed()) {
for (int c = 0; c < m_orgCorrs.size(); c++) {
double tmp = m_orgCorrs.at(c) + dc;
double tmp = m_orgCorrs.at(c).value + dc;
// 値をクランプ
if (tmp >= (double)m_shape.shapePairP->getBezierPointAmount())
tmp -= (double)m_shape.shapePairP->getBezierPointAmount();
if (tmp < 0.0)
tmp += (double)m_shape.shapePairP->getBezierPointAmount();

newCorrs.push_back(tmp);
newCorrs.push_back({tmp, m_orgCorrs.at(c).weight});
}
}
// 開いたシェイプの場合、端点以外をスライド。端についたらそこでストップ
else {
int cpAmount = m_shape.shapePairP->getCorrPointAmount();
// 正方向に移動
if (dc > 0)
dc = std::min(dc, m_orgCorrs.at(cpAmount - 1) -
m_orgCorrs.at(cpAmount - 2) - 0.05);
dc = std::min(dc, m_orgCorrs.at(cpAmount - 1).value -
m_orgCorrs.at(cpAmount - 2).value - 0.05);
// 負方向に移動
else
dc = std::max(dc, m_orgCorrs.at(0) - m_orgCorrs.at(1) + 0.05);
dc = std::max(dc,
m_orgCorrs.at(0).value - m_orgCorrs.at(1).value + 0.05);

newCorrs.push_back(m_orgCorrs.at(0));
for (int c = 1; c < m_orgCorrs.size() - 1; c++) {
double tmp = m_orgCorrs.at(c) + dc;
newCorrs.push_back(tmp);
double tmp = m_orgCorrs.at(c).value + dc;
newCorrs.push_back({tmp, m_orgCorrs.at(c).weight});
}
newCorrs.push_back(m_orgCorrs.last());
}
Expand All @@ -109,15 +110,15 @@ void CorrDragTool::onDrag(const QPointF& pos, const QMouseEvent* e) {
m_corrPointId + 1 >= m_shape.shapePairP->getCorrPointAmount())
? 0
: m_corrPointId + 1;
double rangeBefore = m_orgCorrs.at(beforeIndex);
double rangeBefore = m_orgCorrs.at(beforeIndex).value;
double beforeSpeed = m_shape.shapePairP->getBezierSpeedAt(
frame, m_shape.fromTo, rangeBefore, 0.001);
rangeBefore += std::min(0.01, 0.001 / beforeSpeed);
// 値をクランプ
if (rangeBefore >= (double)m_shape.shapePairP->getBezierPointAmount())
rangeBefore -= (double)m_shape.shapePairP->getBezierPointAmount();

double rangeAfter = m_orgCorrs.at(afterIndex);
double rangeAfter = m_orgCorrs.at(afterIndex).value;
double afterSpeed = m_shape.shapePairP->getBezierSpeedAt(
frame, m_shape.fromTo, rangeAfter, -0.001);
rangeAfter -= std::min(0.01, 0.001 / afterSpeed);
Expand All @@ -134,8 +135,8 @@ void CorrDragTool::onDrag(const QPointF& pos, const QMouseEvent* e) {
doSnap(nearestBezierPos, frame, rangeBefore, rangeAfter);
}
// 値を1つだけ変更
newCorrs = m_orgCorrs;
newCorrs[m_corrPointId] = nearestBezierPos;
newCorrs = m_orgCorrs;
newCorrs[m_corrPointId].value = nearestBezierPos;
}
//----- 対応点キーフレームを格納
m_shape.shapePairP->setCorrKey(frame, m_shape.fromTo, newCorrs);
Expand Down Expand Up @@ -252,6 +253,18 @@ void CorrDragTool::onRelease(const QPointF& /*pos*/, const QMouseEvent*) {
CorrPointList afterCorrs =
m_shape.shapePairP->getCorrPointList(frame, m_shape.fromTo);

bool somethingChanged = false;
for (int c = 0; c < m_orgCorrs.size(); c++) {
if (m_orgCorrs[c] == afterCorrs[c])
continue;
else {
somethingChanged = true;
break;
}
}

if (!somethingChanged) return;

// Undo登録 同時にredoが呼ばれるが、最初はフラグで回避する
IwUndoManager::instance()->push(new CorrDragToolUndo(
m_shape, m_orgCorrs, afterCorrs, m_wasKeyFrame, m_project, frame));
Expand Down Expand Up @@ -482,6 +495,7 @@ bool CorrespondenceTool::leftButtonDown(const QPointF& pos,
if ((name % 10) != 0) {
int corrPointId = (int)(name / 10) % 1000;
m_selection->setActiveCorrPoint(shape, corrPointId);
IwApp::instance()->getCurrentSelection()->notifySelectionChanged();

// オープンなシェイプで、端点は動かせない
if (!shape.shapePairP->isClosed() &&
Expand Down Expand Up @@ -538,6 +552,7 @@ bool CorrespondenceTool::leftButtonDown(const QPointF& pos,
bool CorrespondenceTool::leftButtonDrag(const QPointF& pos,
const QMouseEvent* e) {
if (m_dragTool) {
m_viewer->setFocus();
m_dragTool->onDrag(pos, e);
return true;
}
Expand Down Expand Up @@ -691,6 +706,7 @@ void CorrespondenceTool::onActivate() {

void CorrespondenceTool::onDeactivate() {
m_selection->setActiveCorrPoint(OneShape(), -1);
IwApp::instance()->getCurrentSelection()->notifySelectionChanged();
}

//--------------------------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion sources/freehandtool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,8 @@ void FreeHandTool::createShape() {

CorrPointList cpList;
for (int cp = 0; cp < 4; cp++) {
cpList.push_back((double)((bpCount - 1) * cp) / ((m_isClosed) ? 4.0 : 3.0));
cpList.push_back(
{(double)((bpCount - 1) * cp) / ((m_isClosed) ? 4.0 : 3.0), 1.0});
}

m_currentShape =
Expand Down
25 changes: 17 additions & 8 deletions sources/halfedge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,21 @@ double HEFace::size() const {
// Add new vertex at centroid and returns its pointer
// 重心にHEVertexを作成しポインタを返す
HEVertex* HEFace::createCentroidVertex() {
HEVertex* A = halfedge->vertex;
HEVertex* B = halfedge->next->vertex;
HEVertex* C = halfedge->prev->vertex;
QVector3D from = (A->from_pos + B->from_pos + C->from_pos) / 3.0;
QVector3D to = (A->to_pos + B->to_pos + C->to_pos) / 3.0;
HEVertex* A = halfedge->vertex;
HEVertex* B = halfedge->next->vertex;
HEVertex* C = halfedge->prev->vertex;
QVector3D from =
(A->from_pos * A->from_weight + B->from_pos * B->from_weight +
C->from_pos * C->from_weight) /
(A->from_weight + B->from_weight + C->from_weight);
double from_weight = (A->from_weight + B->from_weight + C->from_weight) / 3.0;
QVector3D to = (A->to_pos * A->to_weight + B->to_pos * B->to_weight +
C->to_pos * C->to_weight) /
(A->to_weight + B->to_weight + C->to_weight);
double to_weight = (A->to_weight + B->to_weight + C->to_weight) / 3.0;

return new HEVertex(from.toPointF(), to.toPointF(), from.z());
return new HEVertex(from.toPointF(), to.toPointF(), from.z(), from_weight,
to_weight);
}

bool HEFace::hasConstantDepth() const {
Expand Down Expand Up @@ -646,8 +654,9 @@ void HEModel::smooth(double offsetThreshold) {
QPointF fromOffset, toOffset;
Halfedge* tmp_he = v->halfedge;
while (1) {
fromOffset += tmp_he->getFromPos2DVector();
toOffset += tmp_he->getToPos2DVector();
fromOffset +=
tmp_he->getFromPos2DVector() * tmp_he->pair->vertex->from_weight;
toOffset += tmp_he->getToPos2DVector() * tmp_he->pair->vertex->to_weight;
// 次のエッジへ
tmp_he = tmp_he->prev->pair;
if (tmp_he == v->halfedge) break;
Expand Down
14 changes: 11 additions & 3 deletions sources/halfedge.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,29 @@ class HEVertex {
// ワープ後の座標
QVector3D to_pos;

double from_weight, to_weight;

// この頂点を始点にもつハーフエッジの1つ
Halfedge* halfedge = nullptr;
// 線分制約(動かない)かどうか
bool constrained = false;

HEVertex(double _x, double _y, double _z)
: from_pos(_x, _y, _z), halfedge(nullptr) {
: from_pos(_x, _y, _z)
, halfedge(nullptr)
, from_weight(1.0)
, to_weight(1.0) {
to_pos = from_pos;
}
HEVertex(const QPointF& _pos, double depth)
: HEVertex(_pos.x(), _pos.y(), depth) {}

HEVertex(const QPointF& _from_pos, const QPointF& _to_pos, double depth)
HEVertex(const QPointF& _from_pos, const QPointF& _to_pos, double depth,
double _from_weight = 1.0, double _to_weight = 1.0)
: from_pos(_from_pos.x(), _from_pos.y(), depth)
, to_pos(_to_pos.x(), _to_pos.y(), depth) {}
, to_pos(_to_pos.x(), _to_pos.y(), depth)
, from_weight(_from_weight)
, to_weight(_to_weight) {}

bool operator==(const HEVertex& v);

Expand Down
54 changes: 42 additions & 12 deletions sources/iwrenderinstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,20 @@ void IwRenderInstance::getCorrVectors(IwLayer* /*layer*/,
shapePair->getDiscreteCorrValues(onePix, m_frame, 0);
QList<double> discreteCorrValuesTo =
shapePair->getDiscreteCorrValues(onePix, m_frame, 1);
// 対応点の分割点のウェイトを求める
QList<double> discreteCorrWeightsFrom =
shapePair->getDiscreteCorrWeights(m_frame, 0);
QList<double> discreteCorrWeightsTo =
shapePair->getDiscreteCorrWeights(m_frame, 1);

assert(discreteCorrValuesFrom.size() == discreteCorrWeightsFrom.size());

QPointF firstPosFrom, lastPosFrom, prevPosFrom, firstPosTo, lastPosTo,
prevPosTo;

double firstWeightFrom, lastWeightFrom, prevWeightFrom, firstWeightTo,
lastWeightTo, prevWeightTo;

// 各ベジエ座標を格納
for (int d = 0; d < discreteCorrValuesFrom.size(); d++) {
QPointF tmpPosFrom = shapePair->getBezierPosFromValue(
Expand All @@ -406,13 +417,20 @@ void IwRenderInstance::getCorrVectors(IwLayer* /*layer*/,
tmpPosTo = QPointF(tmpPosTo.x() * (double)workAreaSize.width(),
tmpPosTo.y() * (double)workAreaSize.height());

double tmpWeightFrom = discreteCorrWeightsFrom.at(d);
double tmpWeightTo = discreteCorrWeightsTo.at(d);
assert(tmpWeightTo > 0.5);
if (d == 0) {
firstPosFrom = tmpPosFrom;
firstPosTo = tmpPosTo;
firstPosFrom = tmpPosFrom;
firstPosTo = tmpPosTo;
firstWeightFrom = tmpWeightFrom;
firstWeightTo = tmpWeightTo;
} else {
if (d == discreteCorrValuesFrom.size() - 1) {
lastPosFrom = tmpPosFrom;
lastPosTo = tmpPosTo;
lastPosFrom = tmpPosFrom;
lastPosTo = tmpPosTo;
lastWeightFrom = tmpWeightFrom;
lastWeightTo = tmpWeightTo;
}

// ここで、ワープ先(Toの方)のCorrVecの長さが、5ピクセルより短い場合、
Expand All @@ -424,13 +442,19 @@ void IwRenderInstance::getCorrVectors(IwLayer* /*layer*/,
!isDecimal(discreteCorrValuesTo.at(d)))
continue;

CorrVector corrVec = {
{prevPosFrom, tmpPosFrom}, {prevPosTo, tmpPosTo}, depth, false};
CorrVector corrVec = {{prevPosFrom, tmpPosFrom},
{prevPosTo, tmpPosTo},
depth,
false,
{prevWeightFrom, tmpWeightFrom},
{prevWeightTo, tmpWeightTo}};

corrVectors.append(corrVec);
}
prevPosFrom = tmpPosFrom;
prevPosTo = tmpPosTo;
prevPosFrom = tmpPosFrom;
prevPosTo = tmpPosTo;
prevWeightFrom = tmpWeightFrom;
prevWeightTo = tmpWeightTo;

if (shapePair->isParent()) {
parentShapeVerticesFrom.append(tmpPosFrom);
Expand All @@ -439,8 +463,12 @@ void IwRenderInstance::getCorrVectors(IwLayer* /*layer*/,
}
// 閉じたシェイプの場合、最後と最初を繋ぐベクトルを追加
if (shapePair->isClosed()) {
CorrVector corrVec = {
{lastPosFrom, firstPosFrom}, {lastPosTo, firstPosTo}, depth, false};
CorrVector corrVec = {{lastPosFrom, firstPosFrom},
{lastPosTo, firstPosTo},
depth,
false,
{lastWeightFrom, firstWeightFrom},
{lastWeightTo, firstWeightTo}};
corrVectors.append(corrVec);
}
}
Expand Down Expand Up @@ -526,7 +554,8 @@ void IwRenderInstance::HEcreateTriangleMesh(

if (!start) {
start = new HEVertex(corrVec.from_p[0], corrVec.to_p[0],
(double)corrVec.stackOrder);
(double)corrVec.stackOrder, corrVec.from_weight[0],
corrVec.to_weight[0]);
// モデルに点を追加
// B2 - 2) piを含む三角形ABCを発見し, この三角形をAB pi, BC pi, CA pi
// の3個の三角形に分割. この時, 辺AB, BC, CAをスタックSに積む. B2 -
Expand All @@ -547,7 +576,8 @@ void IwRenderInstance::HEcreateTriangleMesh(
HEVertex* end = model.findVertex(corrVec.from_p[1], corrVec.to_p[1]);
if (!end) {
end = new HEVertex(corrVec.from_p[1], corrVec.to_p[1],
(double)corrVec.stackOrder);
(double)corrVec.stackOrder, corrVec.from_weight[1],
corrVec.to_weight[1]);
model.addVertex(end, start);
} else // すでに追加済みの点の場合(平曲線の始点に戻ってきたときなど)は、制約のみ付加する
model.setConstraint(start, end, true);
Expand Down
4 changes: 3 additions & 1 deletion sources/iwrenderinstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ struct CorrVector {
QPointF to_p[2];
int stackOrder; // レイヤインデックス = 重ね順
bool isEdge; // 輪郭ならtrue, シェイプ由来ならtrue
int indices[2]; // samplePointsのインデックス
double from_weight[2];
double to_weight[2];
// int indices[2]; // samplePointsのインデックス
};

class MapTrianglesToRaster_Worker : public QRunnable {
Expand Down
3 changes: 2 additions & 1 deletion sources/iwshapepairselection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
class DeleteCorrPointUndo : public QUndoCommand {
ShapePair* m_shape;
IwProject* m_project;
QMap<int, double> m_deletedCorrPos[2];
QMap<int, CorrPoint> m_deletedCorrPos[2];
int m_deletedIndex;

public:
Expand Down Expand Up @@ -517,6 +517,7 @@ void IwShapePairSelection::onDeleteCorrPoint() {

// 対応点選択をクリア
setActiveCorrPoint(OneShape(), -1);
IwApp::instance()->getCurrentSelection()->notifySelectionChanged();
}

//---------------------------------------------------
Expand Down
17 changes: 13 additions & 4 deletions sources/iwtool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ void IwTool::drawCorrLine(OneShape shape)
// 対応点の座標リストを得る
QList<QPointF> corrPoints =
shape.shapePairP->getCorrPointPositions(frame, shape.fromTo);
// ウェイトのリストも得る
QList<double> corrWeights =
shape.shapePairP->getCorrPointWeights(frame, shape.fromTo);

// 名前
int shapeName = layer->getNameFromShapePair(shape);
Expand Down Expand Up @@ -179,10 +182,16 @@ void IwTool::drawCorrLine(OneShape shape)
glPopName();

// テキストの描画
glColor3d(cNumberCol[0], cNumberCol[1], cNumberCol[2]);
// TODO
// m_viewer->renderText(5.0, -15.0, 0.0,QString::number(p+1),f);

// ウェイトが1じゃない場合に描画する
double weight = corrWeights.at(p);
if (weight != 1.) {
glColor3d(cNumberCol[0], cNumberCol[1], cNumberCol[2]);
GLdouble model[16];
glGetDoublev(GL_MODELVIEW_MATRIX, model);
m_viewer->renderText(model[12] + 5.0, model[13] - 15.0,
QString::number(weight),
QFont("Helvetica", 10, QFont::Normal));
}
glPopMatrix();
}
}
Expand Down
Loading

0 comments on commit f585f3a

Please sign in to comment.