Fix merge conflict

This commit is contained in:
baydam
2015-12-28 13:24:56 +00:00
6 changed files with 139 additions and 43 deletions
+3
View File
@@ -74,6 +74,9 @@ public:
static const qreal ZOOM_FACTOR;
static const qreal ZOOM_MIN;
static const qreal ZOOM_MAX;
// Misc.
static const int MESH_SUBDIVISION_MIN_AREA = 400;
};
#endif
+1
View File
@@ -2744,6 +2744,7 @@ bool MainWindow::setTextureVolume(int texture_id, double volume)
if (paint->getType() == "media")
{
Media *media = static_cast<Media*>(paint.data()); // FIXME: use sharedptr cast
//Media *media = (Media *) paint.data(); // FIXME: use sharedptr cast
videoTimer->stop();
media->setVolume(volume);
videoTimer->start();
+1
View File
@@ -89,6 +89,7 @@ private slots:
void openRecentFile();
void clearRecentFileList();
void openRecentVideo();
void quitMapMap();
// Edit menu.
void deleteItem();
// Context menu for mappings.
+3
View File
@@ -83,6 +83,9 @@ public:
/// Set the currently active vertex
void setActiveVertexIndex(int activeVertex) { _activeVertex = activeVertex; }
bool shapeGrabbed() const { return _shapeGrabbed; }
bool vertexGrabbed() const { return _vertexGrabbed; }
qreal getZoomFactor() const { return qBound(qPow(MM::ZOOM_FACTOR, _zoomLevel), MM::ZOOM_MIN, MM::ZOOM_MAX); }
/// This function needs to be called after a shape inside the canvas has been changed for appropriate signals to be activated.
+109 -41
View File
@@ -309,6 +309,12 @@ PolygonTextureGraphicsItem::PolygonTextureGraphicsItem(Mapping::ptr mapping, boo
_controlPainter.reset(new PolygonControlPainter(this));
}
MeshTextureGraphicsItem::MeshTextureGraphicsItem(Mapping::ptr mapping, bool output) : PolygonTextureGraphicsItem(mapping, output) {
_controlPainter.reset(new MeshControlPainter(this));
_nHorizontalQuads = _nVerticalQuads = -1;
_wasGrabbing = false;
}
void MeshTextureGraphicsItem::_doDrawOutput(QPainter* painter)
{
Q_UNUSED(painter);
@@ -318,61 +324,123 @@ void MeshTextureGraphicsItem::_doDrawOutput(QPainter* painter)
QSharedPointer<Mesh> inputMesh = qSharedPointerCast<Mesh>(_inputShape);
QVector<QVector<Quad> > outputQuads = outputMesh->getQuads2d();
QVector<QVector<Quad> > inputQuads = inputMesh->getQuads2d();
// Check if we increased or decreased number of columns/rows in mesh.
bool forceRebuild = false;
if (_nHorizontalQuads != outputMesh->nHorizontalQuads() ||
_nVerticalQuads != outputMesh->nVerticalQuads())
{
forceRebuild = true;
_cachedQuadItems.resize(_nHorizontalQuads = outputMesh->nHorizontalQuads());
for (int i=0; i<_nHorizontalQuads; i++)
_cachedQuadItems[i].resize(_nVerticalQuads = outputMesh->nVerticalQuads());
}
// Keep track of whether we are currently grabbing the shape or a vertex so as to
// reduce resolution when editing (to prevent lags).
bool grabbing = (getCanvas()->shapeGrabbed() || getCanvas()->vertexGrabbed());
// Max depth is adjusted to draw less quads during click & drag.
int maxDepth = (grabbing ? 4 : -1);
// Force rebuild on shape/vertex release.
if (_wasGrabbing && !grabbing) {
forceRebuild = true;
}
_wasGrabbing = grabbing;
// Go through the mesh quad by quad.
for (int x = 0; x < outputMesh->nHorizontalQuads(); x++)
{
for (int y = 0; y < outputMesh->nVerticalQuads(); y++)
{
QSizeF size = mapFromScene(outputQuads[x][y].toPolygon()).boundingRect().size();
float area = size.width() * size.height();
_drawQuad(*_texture.toStrongRef(), inputQuads[x][y], outputQuads[x][y], area);
Quad& inputQuad = inputQuads[x][y];
Quad& outputQuad = outputQuads[x][y];
// Verify if item needs recomputing.
CacheQuadItem& item = _cachedQuadItems[x][y];
if (forceRebuild ||
item.parent.input.toPolygon() != inputQuad.toPolygon() ||
item.parent.output.toPolygon() != outputQuad.toPolygon()) {
// Copy input and output quads for verification purposes.
item.parent.input = inputQuad;
item.parent.output = outputQuad;
// Recompute sub quads.
item.subQuads.clear();
QSizeF size = mapFromScene(outputQuad.toPolygon()).boundingRect().size();
float area = size.width() * size.height();
// Rebuild cache quad item.
_buildCacheQuadItem(item, inputQuad, outputQuad, area, 0.0001f, 0.001f, MM::MESH_SUBDIVISION_MIN_AREA, maxDepth);
}
// Draw all the cached items.
foreach (CacheQuadMapping m, item.subQuads)
{
glBegin(GL_QUADS);
for (int i = 0; i < outputQuad.nVertices(); i++)
{
Util::setGlTexPoint(*_texture.toStrongRef(), m.input.getVertex(i), mapFromScene(m.output.getVertex(i)));
}
glEnd();
}
}
}
}
}
MeshTextureGraphicsItem::MeshTextureGraphicsItem(Mapping::ptr mapping, bool output) : PolygonTextureGraphicsItem(mapping, output) {
_controlPainter.reset(new MeshControlPainter(this));
}
void MeshTextureGraphicsItem::_drawQuad(const Texture& texture, const Quad& inputQuad, const Quad& outputQuad, float outputArea, float inputThreshod, float outputThreshold)
void MeshTextureGraphicsItem::_buildCacheQuadItem(CacheQuadItem& item, const Quad& inputQuad, const Quad& outputQuad, float outputArea, float inputThreshod, float outputThreshold, int minArea, int maxDepth)
{
QPointF oa = mapFromScene(outputQuad.getVertex(0));
QPointF ob = mapFromScene(outputQuad.getVertex(1));
QPointF oc = mapFromScene(outputQuad.getVertex(2));
QPointF od = mapFromScene(outputQuad.getVertex(3));
bool stop = false;
if (maxDepth == 0 || outputArea < minArea)
stop = true;
else {
QPointF oa = mapFromScene(outputQuad.getVertex(0));
QPointF ob = mapFromScene(outputQuad.getVertex(1));
QPointF oc = mapFromScene(outputQuad.getVertex(2));
QPointF od = mapFromScene(outputQuad.getVertex(3));
QPointF ia = inputQuad.getVertex(0);
QPointF ib = inputQuad.getVertex(1);
QPointF ic = inputQuad.getVertex(2);
QPointF id = inputQuad.getVertex(3);
QPointF ia = inputQuad.getVertex(0);
QPointF ib = inputQuad.getVertex(1);
QPointF ic = inputQuad.getVertex(2);
QPointF id = inputQuad.getVertex(3);
// compute the dot products for the polygon
float outputV1dotV2 = QPointF::dotProduct(oa-ob, oc-ob);
float outputV3dotV4 = QPointF::dotProduct(oc-od, oa-od);
float outputV1dotV4 = QPointF::dotProduct(oa-ob, oa-od);
float outputV2dotV3 = QPointF::dotProduct(oc-ob, oc-od);
QPointF outputV1 = oa-ob;
QPointF outputV2 = oc-ob;
QPointF outputV3 = oc-od;
QPointF outputV4 = oa-od;
// compute the dot products for the texture
float inputV1dotV2 = QPointF::dotProduct(ia-ib, ic-ib);
float inputV3dotV4 = QPointF::dotProduct(ic-id, ia-id);
float inputV1dotV4 = QPointF::dotProduct(ia-ib, ia-id);
float inputV2dotV3 = QPointF::dotProduct(ic-ib, ic-id);
QPointF inputV1 = ia-ib;
QPointF inputV2 = ic-ib;
QPointF inputV3 = ic-id;
QPointF inputV4 = ia-id;
// Stopping criterion.
if (outputArea < 200 ||
(fabs(outputV1dotV2 - outputV3dotV4) < outputThreshold &&
fabs(outputV1dotV4 - outputV2dotV3) < outputThreshold &&
fabs(inputV1dotV2 - inputV3dotV4) < inputThreshod &&
fabs(inputV1dotV4 - inputV2dotV3) < inputThreshod))
// compute the dot products for the polygon
float outputV1dotV2 = QPointF::dotProduct(outputV1, outputV2);
float outputV3dotV4 = QPointF::dotProduct(outputV3, outputV4);
float outputV1dotV4 = QPointF::dotProduct(outputV1, outputV4);
float outputV2dotV3 = QPointF::dotProduct(outputV2, outputV3);
// compute the dot products for the texture
float inputV1dotV2 = QPointF::dotProduct(inputV1, inputV2);
float inputV3dotV4 = QPointF::dotProduct(inputV3, inputV4);
float inputV1dotV4 = QPointF::dotProduct(inputV1, inputV4);
float inputV2dotV3 = QPointF::dotProduct(inputV2, inputV3);
// Stopping criterion.
stop = (fabs(outputV1dotV2 - outputV3dotV4) < outputThreshold &&
fabs(outputV1dotV4 - outputV2dotV3) < outputThreshold &&
fabs(inputV1dotV2 - inputV3dotV4) < inputThreshod &&
fabs(inputV1dotV4 - inputV2dotV3) < inputThreshod);
}
//
if (stop)
{
glBegin(GL_QUADS);
for (int i = 0; i < outputQuad.nVertices(); i++)
{
Util::setGlTexPoint(texture, inputQuad.getVertex(i), mapFromScene(outputQuad.getVertex(i)));
}
glEnd();
item.subQuads.append( (CacheQuadMapping){ inputQuad, outputQuad } );
}
else // subdivide
{
@@ -380,7 +448,7 @@ void MeshTextureGraphicsItem::_drawQuad(const Texture& texture, const Quad& inpu
QList<Quad> outputSubQuads = _split(outputQuad);
for (int i = 0; i < inputSubQuads.size(); i++)
{
_drawQuad(texture, inputSubQuads[i], outputSubQuads[i], outputArea*0.25, inputThreshod, outputThreshold);
_buildCacheQuadItem(item, inputSubQuads[i], outputSubQuads[i], outputArea*0.25, inputThreshod, outputThreshold, minArea, (maxDepth == -1 ? -1 : maxDepth - 1));
}
}
}
+22 -2
View File
@@ -201,9 +201,22 @@ public:
};
/// Graphics item for textured mesh.
/**
* Graphics item for textured mesh.
* The drawing technique recursively subdivides the quad to approximate projective mapping and thus
* avoiding artifacts on the diagonals. Subdivided structure is cached to increase performance.
* Source: Oliveira, M. "Correcting Texture Mapping Errors Introduced by Graphics Hardware"
*/
class MeshTextureGraphicsItem : public PolygonTextureGraphicsItem
{
struct CacheQuadMapping {
Quad input;
Quad output;
};
struct CacheQuadItem {
CacheQuadMapping parent;
QList<CacheQuadMapping> subQuads;
};
public:
MeshTextureGraphicsItem(Mapping::ptr mapping, bool output=true);
virtual ~MeshTextureGraphicsItem(){}
@@ -212,8 +225,15 @@ public:
private:
// Draws quad recursively using the technique described in Oliveira, M. "Correcting Texture Mapping Errors Introduced by Graphics Hardware"
void _drawQuad(const Texture& texture, const Quad& inputQuad, const Quad& outputQuad, float outputArea, float inputThreshold = 0.0001f, float outputThreshold = 0.001f);
void _buildCacheQuadItem(CacheQuadItem& item, const Quad& inputQuad, const Quad& outputQuad,
float outputArea, float inputThreshold = 0.0001f, float outputThreshold = 0.001f,
int minArea=MM::MESH_SUBDIVISION_MIN_AREA, int maxDepth=-1);
QList<Quad> _split(const Quad& quad);
QVector<QVector<CacheQuadItem> > _cachedQuadItems;
int _nHorizontalQuads;
int _nVerticalQuads;
bool _wasGrabbing;
};
/// Graphics item for textured mesh.