inital commit
This commit is contained in:
337
backplotwidget.cpp
Normal file
337
backplotwidget.cpp
Normal file
@ -0,0 +1,337 @@
|
||||
#include "backplotwidget.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QCamera>
|
||||
#include <QCameraLens>
|
||||
#include <QMaterial>
|
||||
#include <QGeometry>
|
||||
#include <Qt3DExtras/QCylinderMesh>
|
||||
#include <Qt3DExtras/QPlaneMesh>
|
||||
#include <Qt3DRender/qpointlight.h>
|
||||
#include <QRenderSettings>
|
||||
|
||||
BackPlotWidget::BackPlotWidget(QWidget *parent, double xLimit, double yLimit, double zLimit)
|
||||
: limits(xLimit, yLimit, zLimit),
|
||||
QWidget(parent)
|
||||
{
|
||||
|
||||
containerWdiget = QWidget::createWindowContainer(&view);
|
||||
hLayout.addWidget(containerWdiget);
|
||||
containerWdiget->setParent(this);
|
||||
setLayout(&hLayout);
|
||||
view.defaultFrameGraph()->setClearColor("Black");
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
void BackPlotWidget::reset()
|
||||
{
|
||||
view.setRootEntity(nullptr);
|
||||
|
||||
if(rootEntity)
|
||||
delete rootEntity;
|
||||
rootEntity = new Qt3DCore::QEntity();
|
||||
view.setRootEntity(rootEntity);
|
||||
view.renderSettings()->setRenderPolicy(Qt3DRender::QRenderSettings::OnDemand);
|
||||
|
||||
camController = new OrbitCameraController(QVector2D(100, 100), rootEntity);
|
||||
camController->setLinearSpeed(200.0f);
|
||||
camController->setLookSpeed(360.0f);
|
||||
camController->setCamera(view.camera());
|
||||
|
||||
axisMaterial = new Qt3DExtras::QPhongMaterial(rootEntity);
|
||||
rapidMaterial= new Qt3DExtras::QPhongMaterial(rootEntity);
|
||||
pathMaterial = new Qt3DExtras::QPhongMaterial(rootEntity);
|
||||
axisMaterial->setAmbient(QColorConstants::Red);
|
||||
rapidMaterial->setAmbient(QColorConstants::Gray);
|
||||
pathMaterial->setAmbient(QColorConstants::White);
|
||||
|
||||
view.camera()->setPosition(QVector3D(limits.x()/2, limits.y()/2, limits.z()*4));
|
||||
view.camera()->setUpVector(QVector3D(0, 1, 0));
|
||||
view.camera()->setViewCenter(QVector3D(limits.x()/2, limits.y()/2, 0));
|
||||
|
||||
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);
|
||||
Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
|
||||
light->setColor(QColorConstants::White);
|
||||
light->setIntensity(0.2);
|
||||
lightEntity->addComponent(light);
|
||||
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
|
||||
lightTransform->setTranslation(QVector3D(0-limits.x()/2, 0-limits.y()/2, 1000.0f));
|
||||
lightEntity->addComponent(lightTransform);
|
||||
|
||||
Qt3DCore::QEntity* xAxisEntity = new Qt3DCore::QEntity(rootEntity);
|
||||
Qt3DCore::QEntity* yAxisEntity = new Qt3DCore::QEntity(rootEntity);
|
||||
Qt3DCore::QEntity* zAxisEntity = new Qt3DCore::QEntity(rootEntity);
|
||||
Qt3DExtras::QPhongMaterial* xAxisMaterial = new Qt3DExtras::QPhongMaterial(xAxisEntity);
|
||||
Qt3DExtras::QPhongMaterial* yAxisMaterial = new Qt3DExtras::QPhongMaterial(yAxisEntity);
|
||||
Qt3DExtras::QPhongMaterial* zAxisMaterial = new Qt3DExtras::QPhongMaterial(zAxisEntity);
|
||||
xAxisMaterial->setAmbient(QColorConstants::Green);
|
||||
yAxisMaterial->setAmbient(QColorConstants::Red);
|
||||
zAxisMaterial->setAmbient(QColor(18,128,255));
|
||||
touchoffTransform = new Qt3DCore::QTransform(rootEntity);
|
||||
touchoffTransform->setTranslation(limits);
|
||||
xAxisEntity->addComponent(touchoffTransform);
|
||||
yAxisEntity->addComponent(touchoffTransform);
|
||||
zAxisEntity->addComponent(touchoffTransform);
|
||||
drawLine(QVector3D(0,0,0), QVector3D(-15,0,0), xAxisMaterial, xAxisEntity);
|
||||
drawLine(QVector3D(0,0,0), QVector3D(0,-15,0), yAxisMaterial, yAxisEntity);
|
||||
drawLine(QVector3D(0,0,0), QVector3D(0,0,15), zAxisMaterial, zAxisEntity);
|
||||
|
||||
drawBox(QVector3D(0, 0, 0), limits, axisMaterial, new Qt3DCore::QEntity(rootEntity));
|
||||
|
||||
Qt3DCore::QEntity* planeEntity = new Qt3DCore::QEntity(rootEntity);
|
||||
Qt3DExtras::QPlaneMesh* plane = new Qt3DExtras::QPlaneMesh(planeEntity);
|
||||
Qt3DCore::QTransform *planeTransform = new Qt3DCore::QTransform(planeEntity);
|
||||
Qt3DExtras::QPhongMaterial* planeMaterial = new Qt3DExtras::QPhongMaterial(planeEntity);
|
||||
planeMaterial->setDiffuse(QColorConstants::DarkGray);
|
||||
planeTransform->setTranslation(QVector3D(limits.x()/2, limits.y()/2, -1));
|
||||
planeTransform->setRotationX(90);
|
||||
plane->setHeight(limits.y()*2);
|
||||
plane->setWidth(limits.x()*2);
|
||||
planeEntity->addComponent(plane);
|
||||
planeEntity->addComponent(planeMaterial);
|
||||
planeEntity->addComponent(planeTransform);
|
||||
|
||||
Qt3DCore::QEntity* planeRevEntity = new Qt3DCore::QEntity(rootEntity);
|
||||
Qt3DExtras::QPlaneMesh* planeRev = new Qt3DExtras::QPlaneMesh(planeRevEntity);
|
||||
Qt3DCore::QTransform *planeRevTransform = new Qt3DCore::QTransform(planeRevEntity);
|
||||
planeRevTransform->setTranslation(QVector3D(limits.x()/2, limits.y()/2, -1));
|
||||
planeRevTransform->setRotationX(-90);
|
||||
planeRev->setHeight(limits.y()*2);
|
||||
planeRev->setWidth(limits.x()*2);
|
||||
planeRevEntity->addComponent(planeRev);
|
||||
planeRevEntity->addComponent(planeMaterial);
|
||||
planeRevEntity->addComponent(planeRevTransform);
|
||||
|
||||
toolEntity = new Qt3DCore::QEntity(rootEntity);
|
||||
Qt3DExtras::QCylinderMesh* toolMesh = new Qt3DExtras::QCylinderMesh(toolEntity);
|
||||
Qt3DExtras::QPhongMaterial* toolMaterial = new Qt3DExtras::QPhongMaterial(toolEntity);
|
||||
toolTransform = new Qt3DCore::QTransform(toolEntity);
|
||||
toolTransform->setTranslation(limits + QVector3D(0,0,5));
|
||||
toolTransform->setRotationX(90);
|
||||
toolMaterial->setDiffuse(QColorConstants::White);
|
||||
toolMaterial->setAmbient(QColor(64,64,64));
|
||||
toolMesh->setRadius(1);
|
||||
toolMesh->setLength(10);
|
||||
toolEntity->addComponent(toolMesh);
|
||||
toolEntity->addComponent(toolMaterial);
|
||||
toolEntity->addComponent(toolTransform);
|
||||
}
|
||||
|
||||
void BackPlotWidget::showView(ViewPos viewPos)
|
||||
{
|
||||
if(viewPos == VIEW_TOP)
|
||||
{
|
||||
view.camera()->setPosition(QVector3D(limits.x()/2, limits.y()/2, limits.z()*4));
|
||||
view.camera()->setUpVector(QVector3D(0, 1, 0));
|
||||
}
|
||||
else if(viewPos == VIEW_FRONT)
|
||||
{
|
||||
view.camera()->setPosition(QVector3D(limits.x()/2, 0-limits.y()*4, limits.z()/2));
|
||||
view.camera()->setUpVector(QVector3D(0, 0, 1));
|
||||
}
|
||||
else if(viewPos == VIEW_LEFT)
|
||||
{
|
||||
view.camera()->setPosition(QVector3D(0-limits.x()*4, limits.y()/2, limits.z()/2));
|
||||
view.camera()->setUpVector(QVector3D(0, 0, 1));
|
||||
}
|
||||
else if(viewPos == VIEW_RIGHT)
|
||||
{
|
||||
view.camera()->setPosition(QVector3D(limits.x()*4, limits.y()/2, limits.z()/2));
|
||||
view.camera()->setUpVector(QVector3D(0, 0, 1));
|
||||
}
|
||||
|
||||
if(viewPos == VIEW_TOP)
|
||||
view.camera()->setViewCenter(QVector3D(limits.x()/2, limits.y()/2, 0));
|
||||
else
|
||||
view.camera()->setViewCenter(QVector3D(limits.x()/2, limits.y()/2, limits.z()/2));
|
||||
camController->setZoomFactor(1);
|
||||
}
|
||||
|
||||
void BackPlotWidget::positionUpdate(std::vector<int> position)
|
||||
{
|
||||
assert(position.size() >= 3);
|
||||
toolTransform->setTranslation(limits - QVector3D(position[0]/1000.0, position[1]/1000.0, (position[2]/1000.0)-5));
|
||||
}
|
||||
|
||||
void BackPlotWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
double aspectRatio = static_cast<double>(geometry().width())/geometry().height();
|
||||
double screenWidth;
|
||||
double screenHeight;
|
||||
if(aspectRatio > 1.0)
|
||||
{
|
||||
screenWidth = 500.0;
|
||||
screenHeight = screenWidth/aspectRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
screenHeight = 500;
|
||||
screenWidth = aspectRatio*screenHeight;
|
||||
}
|
||||
camController->setOrthoSize(QVector2D(screenWidth, screenHeight));
|
||||
}
|
||||
|
||||
void BackPlotWidget::drawBox(const QVector3D& a, const QVector3D& b, Qt3DRender::QMaterial* material, Qt3DCore::QEntity* parent)
|
||||
{
|
||||
drawLine(QVector3D(a.x(), a.y(), a.z()), QVector3D(b.x(), a.y(), a.z()), material, parent);
|
||||
drawLine(QVector3D(a.x(), a.y(), a.z()), QVector3D(a.x(), b.y(), a.z()), material, parent);
|
||||
drawLine(QVector3D(a.x(), a.y(), a.z()), QVector3D(a.x(), a.y(), b.z()), material, parent);
|
||||
drawLine(QVector3D(b.x(), a.y(), a.z()), QVector3D(b.x(), b.y(), a.z()), material, parent);
|
||||
drawLine(QVector3D(b.x(), a.y(), a.z()), QVector3D(b.x(), a.y(), b.z()), material, parent);
|
||||
drawLine(QVector3D(a.x(), b.y(), a.z()), QVector3D(b.x(), b.y(), a.z()), material, parent);
|
||||
drawLine(QVector3D(a.x(), b.y(), a.z()), QVector3D(a.x(), b.y(), b.z()), material, parent);
|
||||
drawLine(QVector3D(a.x(), a.y(), b.z()), QVector3D(b.x(), a.y(), b.z()), material, parent);
|
||||
drawLine(QVector3D(a.x(), a.y(), b.z()), QVector3D(a.x(), b.y(), b.z()), material, parent);
|
||||
drawLine(QVector3D(b.x(), b.y(), a.z()), QVector3D(b.x(), b.y(), b.z()), material, parent);
|
||||
drawLine(QVector3D(a.x(), b.y(), b.z()), QVector3D(b.x(), b.y(), b.z()), material, parent);
|
||||
drawLine(QVector3D(b.x(), a.y(), b.z()), QVector3D(b.x(), b.y(), b.z()), material, parent);
|
||||
}
|
||||
|
||||
QByteArray BackPlotWidget::removeComments(const QByteArray& program)
|
||||
{
|
||||
int commentCounter = 0;
|
||||
QByteArray out;
|
||||
for(char ch : program)
|
||||
{
|
||||
if(ch == '/')
|
||||
++commentCounter;
|
||||
else if(ch == '\\' && commentCounter > 0)
|
||||
--commentCounter;
|
||||
else if(commentCounter == 0)
|
||||
out.push_back(ch);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
QList<int> BackPlotWidget::getFields(QByteArray command)
|
||||
{
|
||||
command.remove(0, 2);
|
||||
QList<QByteArray> fieldsText = command.split(',');
|
||||
QList<int> fields;
|
||||
for(const QByteArray& field : fieldsText)
|
||||
{
|
||||
if(field.size() == 0)
|
||||
fields.push_back(NO_FIELD);
|
||||
else
|
||||
fields.push_back(field.toInt());
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
void BackPlotWidget::programChanged(QByteArray program)
|
||||
{
|
||||
for(Qt3DCore::QEntity* entitiy : pathEntitys)
|
||||
delete entitiy;
|
||||
pathEntitys.clear();
|
||||
|
||||
program = removeComments(program);
|
||||
QList<QByteArray> commands = program.split(';');
|
||||
|
||||
QVector3D lastPos = touchoffPosition;
|
||||
|
||||
qDebug()<<__func__;
|
||||
|
||||
for(QByteArray& command : commands)
|
||||
{
|
||||
command = command.trimmed().toUpper();
|
||||
if(command.size() < 2)
|
||||
continue;
|
||||
if(command[0] == 'P' || command[0] == 'G')
|
||||
{
|
||||
QList<int> fields = getFields(command);
|
||||
QVector3D pos;
|
||||
|
||||
if(fields.size() <= 2 || fields[2] == NO_FIELD)
|
||||
pos.setZ(command[1] != 'R' ? lastPos.z()-touchoffPosition.z() : 0);
|
||||
else if(fields.size() > 2)
|
||||
pos.setZ(fields[2]/1000.0);
|
||||
|
||||
if(fields.size() <= 1 || fields[1] == NO_FIELD)
|
||||
pos.setY(command[1] != 'R' ? lastPos.y()-touchoffPosition.y() : 0);
|
||||
else if(fields.size() > 1)
|
||||
pos.setY(fields[1]/1000.0);
|
||||
|
||||
if(fields.size() <= 0 || fields[0] == NO_FIELD)
|
||||
pos.setX(command[1] != 'R' ? lastPos.x()-touchoffPosition.x() : 0);
|
||||
else if(fields.size() > 0)
|
||||
pos.setX(fields[0]/1000.0);
|
||||
|
||||
if(command[1] == 'A')
|
||||
pos = pos+touchoffPosition;
|
||||
else if(command[1] == 'R')
|
||||
pos = pos+lastPos;
|
||||
|
||||
pathEntitys.push_back(new Qt3DCore::QEntity(rootEntity));
|
||||
drawLine(limits-lastPos, limits-pos, command[0] == 'G' ? rapidMaterial : pathMaterial, pathEntitys.back());
|
||||
|
||||
lastPos = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BackPlotWidget::touchoffUpdate(std::vector<int> position)
|
||||
{
|
||||
assert(position.size() >= 3);
|
||||
touchoffPosition.setX(position[0]/1000.0);
|
||||
touchoffPosition.setY(position[1]/1000.0);
|
||||
touchoffPosition.setZ(position[2]/1000.0);
|
||||
touchoffTransform->setTranslation(limits-touchoffPosition);
|
||||
}
|
||||
|
||||
void BackPlotWidget::drawLine(const QVector3D& start, const QVector3D& end, Qt3DRender::QMaterial* material, Qt3DCore::QEntity* parent)
|
||||
{
|
||||
Qt3DCore::QGeometry* geometry = new Qt3DCore::QGeometry(parent);
|
||||
|
||||
// position vertices (start and end)
|
||||
QByteArray bufferBytes;
|
||||
bufferBytes.resize(3 * 2 * sizeof(float)); // start.x, start.y, start.end, end.x, end.y, end.z
|
||||
float* positions = reinterpret_cast<float*>(bufferBytes.data());
|
||||
*positions++ = start.x();
|
||||
*positions++ = start.y();
|
||||
*positions++ = start.z();
|
||||
*positions++ = end.x();
|
||||
*positions++ = end.y();
|
||||
*positions++ = end.z();
|
||||
|
||||
Qt3DCore::QBuffer* buf = new Qt3DCore::QBuffer(geometry);
|
||||
buf->setData(bufferBytes);
|
||||
|
||||
auto *positionAttribute = new Qt3DCore::QAttribute(geometry);
|
||||
positionAttribute->setName(Qt3DCore::QAttribute::defaultPositionAttributeName());
|
||||
positionAttribute->setVertexBaseType(Qt3DCore::QAttribute::Float);
|
||||
positionAttribute->setVertexSize(3);
|
||||
positionAttribute->setAttributeType(Qt3DCore::QAttribute::VertexAttribute);
|
||||
positionAttribute->setBuffer(buf);
|
||||
positionAttribute->setByteStride(3 * sizeof(float));
|
||||
positionAttribute->setCount(2);
|
||||
geometry->addAttribute(positionAttribute); // We add the vertices in the geometry
|
||||
|
||||
// connectivity between vertices
|
||||
QByteArray indexBytes;
|
||||
indexBytes.resize(2 * sizeof(unsigned int)); // start to end
|
||||
unsigned int *indices = reinterpret_cast<unsigned int*>(indexBytes.data());
|
||||
*indices++ = 0;
|
||||
*indices++ = 1;
|
||||
|
||||
Qt3DCore::QBuffer* indexBuffer = new Qt3DCore::QBuffer(geometry);
|
||||
indexBuffer->setData(indexBytes);
|
||||
|
||||
Qt3DCore::QAttribute *indexAttribute = new Qt3DCore::QAttribute(geometry);
|
||||
indexAttribute->setVertexBaseType(Qt3DCore::QAttribute::UnsignedInt);
|
||||
indexAttribute->setAttributeType(Qt3DCore::QAttribute::IndexAttribute);
|
||||
indexAttribute->setBuffer(indexBuffer);
|
||||
indexAttribute->setCount(2);
|
||||
geometry->addAttribute(indexAttribute); // We add the indices linking the points in the geometry
|
||||
|
||||
// mesh
|
||||
auto *line = new Qt3DRender::QGeometryRenderer(parent);
|
||||
line->setGeometry(geometry);
|
||||
line->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
|
||||
|
||||
// entity
|
||||
auto *lineEntity = new Qt3DCore::QEntity(parent);
|
||||
lineEntity->addComponent(line);
|
||||
lineEntity->addComponent(material);
|
||||
}
|
Reference in New Issue
Block a user