diff --git a/MainWindow.cpp b/MainWindow.cpp index ece4cf7..7ba2679 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -662,16 +662,28 @@ void MainWindow::addLayerItem(uint layerId) QString label; QIcon icon; + // Add mapper. + // XXX hardcoded for textures + std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(mapping); + Q_CHECK_PTR(textureMapping); + + Mapper::ptr mapper; + + // XXX Branching on nVertices() is crap + // Triangle if (mapping->getShape()->nVertices() == 3) { label = QString("Triangle %1").arg(mappingId); icon = QIcon(":/images/draw-triangle.png"); + mapper = Mapper::ptr(new TriangleTextureMapper(textureMapping)); } + // Mesh else if (mapping->getShape()->nVertices() == 4) { label = QString("Quad %1").arg(mappingId); icon = QIcon(":/images/draw-rectangle-2.png"); + mapper = Mapper::ptr(new MeshTextureMapper(textureMapping)); } else { @@ -679,13 +691,7 @@ void MainWindow::addLayerItem(uint layerId) icon = QIcon(":/images/draw-polygon-2.png"); } - // Add mapper. - // XXX hardcoded for textures - std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(mapping); - Q_CHECK_PTR(textureMapping); - - Mapper::ptr mapper( new TextureMapper(textureMapping) ); - + // Add to list of mappers. mappers[mappingId] = mapper; QWidget* mapperEditor = mapper->getPropertiesEditor(); propertyPanel->addWidget(mapperEditor); diff --git a/Mapper.cpp b/Mapper.cpp index 704843d..e6bfeab 100644 --- a/Mapper.cpp +++ b/Mapper.cpp @@ -22,30 +22,29 @@ TextureMapper::TextureMapper(std::tr1::shared_ptr mapping) : Mapper(mapping) { + // Assign members pointers. + textureMapping = std::tr1::static_pointer_cast(_mapping); + Q_CHECK_PTR(textureMapping); + + texture = std::tr1::static_pointer_cast(textureMapping->getPaint()); + Q_CHECK_PTR(texture); + + outputShape = std::tr1::static_pointer_cast(textureMapping->getShape()); + Q_CHECK_PTR(outputShape); + + inputShape = std::tr1::static_pointer_cast(textureMapping->getInputShape()); + Q_CHECK_PTR(inputShape); + + // Create editor. _propertyBrowser = new QtTreePropertyBrowser; _variantManager = new QtVariantPropertyManager; _variantFactory = new QtVariantEditorFactory; - _propertyBrowser->setFactoryForManager(_variantManager, _variantFactory); - - std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(mapping); - Q_CHECK_PTR(textureMapping); - - std::tr1::shared_ptr texture = std::tr1::static_pointer_cast(textureMapping->getPaint()); - Q_CHECK_PTR(texture); - _topItem = _variantManager->addProperty(QtVariantPropertyManager::groupTypeId(), QObject::tr("Texture mapping")); - if (std::tr1::dynamic_pointer_cast(textureMapping->getShape())) - { - Mesh* mesh = (Mesh*)textureMapping->getShape().get(); - _meshItem = _variantManager->addProperty(QVariant::Size, QObject::tr("Dimensions")); - _meshItem->setValue(QSize(mesh->nColumns(), mesh->nRows())); - _topItem->addSubProperty(_meshItem); - } - else - _meshItem = 0; + _propertyBrowser->setFactoryForManager(_variantManager, _variantFactory); + // Input shape. _inputItem = _variantManager->addProperty(QtVariantPropertyManager::groupTypeId(), @@ -76,23 +75,14 @@ void TextureMapper::setValue(QtProperty* property, const QVariant& value) if (it != _propertyToVertex.end()) { QPointF p = value.toPointF(); - it->second.first->setVertex(it->second.second, Point(p.x(), p.y())); - //qDebug() << "Changing vertex: " << it->second.second << " to " << p.x() << "," << p.y() << endl; + Shape* shape = it->second.first; + int v = it->second.second; + if (shape->getVertex(v).toQPointF() != p) + { + shape->setVertex(v, Point(p)); + emit valueChanged(); + } } - else if (property == _meshItem) - { - std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(_mapping); - Q_CHECK_PTR(textureMapping); - - Mesh* outputMesh = static_cast(textureMapping->getShape().get()); - Mesh* inputMesh = static_cast(textureMapping->getInputShape().get()); - QSize size = (static_cast(property))->value().toSize(); - outputMesh->resize(size.width(), size.height()); - inputMesh->resize(size.width(), size.height()); - } - - emit valueChanged(); -// qDebug() << "Property changed to " << property->propertyName() << " " << value.toPointF().x() << ", " << value.toPointF().y() << endl; } void TextureMapper::updateShape(Shape* shape) @@ -123,19 +113,6 @@ QWidget* TextureMapper::getPropertiesEditor() void TextureMapper::draw() { - // FIXME: use typedefs, member of the class for type names that are too long to type: - std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(_mapping); - Q_CHECK_PTR(textureMapping); - - std::tr1::shared_ptr texture = std::tr1::static_pointer_cast(textureMapping->getPaint()); - Q_CHECK_PTR(texture); - - std::tr1::shared_ptr outputShape = std::tr1::static_pointer_cast(textureMapping->getShape()); - Q_CHECK_PTR(outputShape); - - std::tr1::shared_ptr inputShape = std::tr1::static_pointer_cast(textureMapping->getInputShape()); - Q_CHECK_PTR(inputShape); - // Only works for similar shapes. Q_ASSERT( outputShape->nVertices() == outputShape->nVertices()); @@ -154,57 +131,9 @@ void TextureMapper::draw() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - if (std::tr1::dynamic_pointer_cast(outputShape)) - { - std::tr1::shared_ptr outputMesh = std::tr1::static_pointer_cast(outputShape); - std::tr1::shared_ptr inputMesh = std::tr1::static_pointer_cast(inputShape); - std::vector > outputQuads = outputMesh->getQuads2d(); - std::vector > inputQuads = inputMesh->getQuads2d(); - for (int x = 0; x < outputMesh->nHorizontalQuads(); x++) - { - for (int y = 0; y < outputMesh->nVerticalQuads(); y++) - { - Quad& outputQuad = outputQuads[x][y]; - Quad& inputQuad = inputQuads[x][y]; - glBegin(GL_QUADS); - for (int i = 0; i < 4; i++) - { - Util::correctGlTexCoord( - (inputQuad.getVertex(i).x - texture->getX()) / (GLfloat) texture->getWidth(), - (inputQuad.getVertex(i).y - texture->getY()) / (GLfloat) texture->getHeight()); - glVertex2f( - outputQuad.getVertex(i).x, - outputQuad.getVertex(i).y - ); - } - glEnd(); - } - } - } - else - { - if (std::tr1::dynamic_pointer_cast(outputShape)) - glBegin(GL_QUADS); - else if (std::tr1::dynamic_pointer_cast(outputShape)) - glBegin(GL_TRIANGLES); - else - // TODO: untested - glBegin(GL_POLYGON); - { - for (int i = 0; i < inputShape->nVertices(); i++) - { - Util::correctGlTexCoord( - (inputShape->getVertex(i).x - texture->getX()) / (GLfloat) texture->getWidth(), - (inputShape->getVertex(i).y - texture->getY()) / (GLfloat) texture->getHeight()); - glVertex2f( - outputShape->getVertex(i).x, - outputShape->getVertex(i).y - ); - } - } - glEnd(); - } + // Perform the actual mapping (done by subclasses). + _doDraw(); glDisable(GL_TEXTURE_2D); } @@ -232,7 +161,7 @@ void TextureMapper::_updateShapeProperty(QtProperty* shapeItem, Shape* shape) for (int i=0; inVertices(); i++) { // XXX mesh control points are not added to properties - if (dynamic_cast(shape) == 0 && i < pointItems.size()) + if (i < pointItems.size()) { QtVariantProperty* pointItem = (QtVariantProperty*)pointItems[i]; Point p = shape->getVertex(i); @@ -241,3 +170,87 @@ void TextureMapper::_updateShapeProperty(QtProperty* shapeItem, Shape* shape) } } +TriangleTextureMapper::TriangleTextureMapper(std::tr1::shared_ptr mapping) + : TextureMapper(mapping) +{ +} + +void TriangleTextureMapper::_doDraw() +{ + glBegin(GL_TRIANGLES); + { + for (int i = 0; i < inputShape->nVertices(); i++) + { + Util::correctGlTexCoord( + (inputShape->getVertex(i).x - texture->getX()) / (GLfloat) texture->getWidth(), + (inputShape->getVertex(i).y - texture->getY()) / (GLfloat) texture->getHeight()); + glVertex2f( + outputShape->getVertex(i).x, + outputShape->getVertex(i).y + ); + } + } + glEnd(); + +} + +MeshTextureMapper::MeshTextureMapper(std::tr1::shared_ptr mapping) + : TextureMapper(mapping) +{ + // Add mesh sub property. + Mesh* mesh = (Mesh*)textureMapping->getShape().get(); + _meshItem = _variantManager->addProperty(QVariant::Size, QObject::tr("Dimensions")); + _meshItem->setValue(QSize(mesh->nColumns(), mesh->nRows())); + _topItem->insertSubProperty(_meshItem, 0); // insert at the beginning +} + +void MeshTextureMapper::setValue(QtProperty* property, const QVariant& value) +{ + if (property == _meshItem) + { + std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(_mapping); + Q_CHECK_PTR(textureMapping); + + Mesh* outputMesh = static_cast(textureMapping->getShape().get()); + Mesh* inputMesh = static_cast(textureMapping->getInputShape().get()); + QSize size = (static_cast(property))->value().toSize(); + if (outputMesh->nColumns() != size.width() || outputMesh->nRows() != size.height() || + inputMesh->nColumns() != size.width() || inputMesh->nRows() != size.height()) + { + outputMesh->resize(size.width(), size.height()); + inputMesh->resize(size.width(), size.height()); + + emit valueChanged(); + } + } + else + TextureMapper::setValue(property, value); +} + +void MeshTextureMapper::_doDraw() +{ + std::tr1::shared_ptr outputMesh = std::tr1::static_pointer_cast(outputShape); + std::tr1::shared_ptr inputMesh = std::tr1::static_pointer_cast(inputShape); + std::vector > outputQuads = outputMesh->getQuads2d(); + std::vector > inputQuads = inputMesh->getQuads2d(); + for (int x = 0; x < outputMesh->nHorizontalQuads(); x++) + { + for (int y = 0; y < outputMesh->nVerticalQuads(); y++) + { + Quad& outputQuad = outputQuads[x][y]; + Quad& inputQuad = inputQuads[x][y]; + glBegin(GL_QUADS); + for (int i = 0; i < 4; i++) + { + Util::correctGlTexCoord( + (inputQuad.getVertex(i).x - texture->getX()) / (GLfloat) texture->getWidth(), + (inputQuad.getVertex(i).y - texture->getY()) / (GLfloat) texture->getHeight()); + glVertex2f( + outputQuad.getVertex(i).x, + outputQuad.getVertex(i).y + ); + } + glEnd(); + } + } +} diff --git a/Mapper.h b/Mapper.h index 885e12b..7f7cb37 100644 --- a/Mapper.h +++ b/Mapper.h @@ -80,43 +80,6 @@ public slots: } }; -//class ShapeDrawer -//{ -//protected: -// std:tr1::shared_ptr _shape; -// -//public: -// ShapeDrawer(const std:tr1::shared_ptr& shape) : _shape(shape) {} -// virtual ~ShapeDrawer() {} -// -// virtual void draw() = 0; -//}; -// -//class QuadDrawer -//{ -//public: -// QuadDrawer(const std:tr1::shared_ptr& quad) : ShapeDrawer(quad) {} -// -// virtual void draw() { -// std::tr1::shared_ptr quad = std::tr1::static_pointer_cast(_shape); -// wxASSERT(quad != NULL); -// -// glColor4f (1, 1, 1, 1); -// -// // Source quad. -// glLineWidth(5); -// glBegin (GL_LINE_STRIP); -// { -// for (int i=0; i<5; i++) { -// glVertex3f(quad->getVertex(i % 4).x / (GLfloat)texture->getWidth(), -// quad->getVertex(i % 4).y / (GLfloat)texture->getHeight(), -// 0); -// } -// } -// glEnd (); -// } -//}; - /** * Draws a texture. */ @@ -136,10 +99,13 @@ signals: void valueChanged(); public slots: - void setValue(QtProperty* property, const QVariant& value); - void updateShape(Shape* shape); + virtual void setValue(QtProperty* property, const QVariant& value); + virtual void updateShape(Shape* shape); -private: +protected: + virtual void _doDraw() = 0; + +protected: QtAbstractPropertyBrowser* _propertyBrowser; QtVariantEditorFactory* _variantFactory; QtVariantPropertyManager* _variantManager; @@ -151,8 +117,45 @@ private: std::map > _propertyToVertex; - void _buildShapeProperty(QtProperty* shapeItem, Shape* shape); - void _updateShapeProperty(QtProperty* shapeItem, Shape* shape); + // FIXME: use typedefs, member of the class for type names that are too long to type: + std::tr1::shared_ptr textureMapping; + std::tr1::shared_ptr texture; + std::tr1::shared_ptr outputShape; + std::tr1::shared_ptr inputShape; + + virtual void _buildShapeProperty(QtProperty* shapeItem, Shape* shape); + virtual void _updateShapeProperty(QtProperty* shapeItem, Shape* shape); +}; + +class TriangleTextureMapper : public TextureMapper +{ + Q_OBJECT + +public: + TriangleTextureMapper(std::tr1::shared_ptr mapping); + virtual ~TriangleTextureMapper() {} + +protected: + virtual void _doDraw(); +}; + + +class MeshTextureMapper : public TextureMapper +{ + Q_OBJECT + +public: + MeshTextureMapper(std::tr1::shared_ptr mapping); + virtual ~MeshTextureMapper() {} + +public slots: + virtual void setValue(QtProperty* property, const QVariant& value); + +protected: + virtual void _doDraw(); + +private: + QtVariantProperty* _meshItem; }; #endif /* MAPPER_H_ */