Skip to content

Commit

Permalink
WIP3
Browse files Browse the repository at this point in the history
  • Loading branch information
HuguesDelorme committed May 31, 2024
1 parent f5e7030 commit 58220ec
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 56 deletions.
38 changes: 32 additions & 6 deletions src/app/commands_tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <QtCore/QtDebug>
#include <QtQml/QJSEngine>
#include <QtWidgets/QFileDialog>
#include <TopAbs_ShapeEnum.hxx>

namespace Mayo {

Expand Down Expand Up @@ -124,22 +125,47 @@ void CommandExecScript::execute()
if (strFilePath.isEmpty())
return;

auto fnJsEvaluate = [](QJSEngine* jsEngine, const QString& program) {
auto jsVal = jsEngine->evaluate(program);
if (jsVal.isError()) {
qCritical() << "Error at line"
<< jsVal.property("lineNumber").toInt()
<< ":" << jsVal.toString();
}

return jsVal;
};

if (!m_jsEngine) {
m_jsEngine = new QJSEngine(this);
m_jsEngine->installExtensions(QJSEngine::ConsoleExtension);

auto jsApp = new JsApplication(this->context()->guiApp()->application(), m_jsEngine);
QJSValue scriptApp = m_jsEngine->newQObject(jsApp);
m_jsEngine->globalObject().setProperty("application", scriptApp);

QJSValue scriptShapeType = m_jsEngine->newObject();
scriptShapeType.setProperty("Compound", TopAbs_COMPOUND);
scriptShapeType.setProperty("CompoundSolid", TopAbs_COMPSOLID);
scriptShapeType.setProperty("Solid", TopAbs_SOLID);
scriptShapeType.setProperty("Shell", TopAbs_SHELL);
scriptShapeType.setProperty("Face", TopAbs_FACE);
scriptShapeType.setProperty("Wire", TopAbs_WIRE);
scriptShapeType.setProperty("Edge", TopAbs_EDGE);
scriptShapeType.setProperty("Vertex", TopAbs_VERTEX);
m_jsEngine->globalObject().setProperty("ShapeType", scriptShapeType);

QJSValue scriptShapeOrientation = m_jsEngine->newObject();
scriptShapeOrientation.setProperty("Forward", TopAbs_FORWARD);
scriptShapeOrientation.setProperty("Reversed", TopAbs_REVERSED);
scriptShapeOrientation.setProperty("Internal", TopAbs_INTERNAL);
scriptShapeOrientation.setProperty("External", TopAbs_EXTERNAL);
m_jsEngine->globalObject().setProperty("ShapeOrientation", scriptShapeOrientation);
}

QFile jsFile(strFilePath);
if (jsFile.open(QIODevice::ReadOnly)) {
auto jsVal = m_jsEngine->evaluate(jsFile.readAll());
if (jsVal.isError()) {
qCritical() << "Error at line"
<< jsVal.property("lineNumber").toInt()
<< ":" << jsVal.toString();
}
fnJsEvaluate(m_jsEngine, jsFile.readAll());
}
}

Expand Down
142 changes: 102 additions & 40 deletions src/qtscripting/js_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "js_document.h"

#include "../base/brep_utils.h"
#include "../base/caf_utils.h"
#include "../base/document.h"
#include "../qtcommon/filepath_conv.h"
Expand All @@ -15,6 +16,8 @@

#include <TDF_Tool.hxx>

#include <QtCore/QtDebug>

namespace Mayo {

int JsDocument::id() const
Expand Down Expand Up @@ -62,85 +65,144 @@ void JsDocument::traverseModelTree(QJSValue fn)
});
}

QString JsDocument::treeNodeName(unsigned treeNodeId) const
QColor JsDocument::tagShapeColor(const QString& tag) const
{
if (!m_doc)
return {};

TDF_Label label;
TDF_Tool::Label(m_doc->GetData(), to_OccAsciiString(tag), label);
if (label.IsNull())
return {};

return QtGuiUtils::toQColor(m_doc->xcaf().shapeColor(label));
}

QVariant JsDocument::treeNode(unsigned int treeNodeId) const
{
return QVariant::fromValue(ScriptTreeNode(m_doc, treeNodeId));
}

void JsDocument::traverseTreeNodeShape(unsigned treeNodeId, unsigned shapeTypeFiler, QJSValue fn)
{
if (!m_doc)
return;

if (!fn.isCallable())
return;

const auto shape = XCaf::shape(this->treeNodeLabel(treeNodeId));
const auto shapeTypeEnum = static_cast<TopAbs_ShapeEnum>(shapeTypeFiler);
BRepUtils::forEachSubShape(shape, shapeTypeEnum, [&](const TopoDS_Shape& subShape) {
auto scriptSubShape = QVariant::fromValue(ScriptShape(subShape));
//fn.call({ QJSValue(scriptSubShape) });
});
}

JsDocument::JsDocument(const DocumentPtr& doc, JsApplication* jsApp)
: QObject(jsApp),
m_doc(doc)
{
m_sigConns
<< doc->signalNameChanged.connectSlot([=](const std::string&) { emit this->nameChanged(); })
<< doc->signalFilePathChanged.connectSlot([=](const FilePath&) { emit this->filePathChanged(); })
<< doc->signalEntityAdded.connectSlot([=](TreeNodeId) { emit this->entityCountChanged(); })
<< doc->signalEntityAboutToBeDestroyed.connectSlot([=](TreeNodeId) { emit this->entityCountChanged(); })
;
}

const TDF_Label& documentTreeNodeLabel(const DocumentPtr& doc, unsigned treeNodeId)
{
static const TDF_Label nullLabel;
return doc ? doc->modelTree().nodeData(treeNodeId) : nullLabel;
}

const TDF_Label& JsDocument::treeNodeLabel(unsigned treeNodeId) const
{
return documentTreeNodeLabel(m_doc, treeNodeId);
}

ScriptTreeNode::ScriptTreeNode(const DocumentPtr& doc, TreeNodeId nodeId)
: m_doc(doc),
m_nodeId(nodeId)
{
}

unsigned ScriptTreeNode::parentId() const
{
return to_QString(CafUtils::labelAttrStdName(this->treeNodeLabel(treeNodeId)));
return m_doc ? m_doc->modelTree().nodeParent(m_nodeId) : 0;
}

unsigned JsDocument::treeNodeParent(unsigned treeNodeId) const
QString ScriptTreeNode::tag() const
{
return m_doc ? m_doc->modelTree().nodeParent(treeNodeId) : 0;
return m_doc ? to_QString(CafUtils::labelTag(documentTreeNodeLabel(m_doc, m_nodeId))) : QString{};
}

bool JsDocument::treeNodeIsAssembly(unsigned treeNodeId) const
QString ScriptTreeNode::name() const
{
return XCaf::isShapeAssembly(this->treeNodeLabel(treeNodeId));
return m_doc ? to_QString(CafUtils::labelAttrStdName(documentTreeNodeLabel(m_doc, m_nodeId))) : QString{};
}

bool JsDocument::treeNodeIsInstance(unsigned treeNodeId) const
bool ScriptTreeNode::isAssembly() const
{
return XCaf::isShapeReference(this->treeNodeLabel(treeNodeId));
return m_doc ? XCaf::isShapeAssembly(documentTreeNodeLabel(m_doc, m_nodeId)) : false;
}

bool JsDocument::treeNodeIsProduct(unsigned treeNodeId) const
bool ScriptTreeNode::isInstance() const
{
return XCaf::isShapeSimple(this->treeNodeLabel(treeNodeId));
return m_doc ? XCaf::isShapeReference(documentTreeNodeLabel(m_doc, m_nodeId)) : false;
}

bool JsDocument::treeNodeIsComponent(unsigned treeNodeId) const
bool ScriptTreeNode::isProduct() const
{
return XCaf::isShapeComponent(this->treeNodeLabel(treeNodeId));
return m_doc ? XCaf::isShapeSimple(documentTreeNodeLabel(m_doc, m_nodeId)) : false;
}

QString JsDocument::treeNodeTag(unsigned treeNodeId) const
bool ScriptTreeNode::isComponent() const
{
return to_QString(CafUtils::labelTag(this->treeNodeLabel(treeNodeId)));
return m_doc ? XCaf::isShapeComponent(documentTreeNodeLabel(m_doc, m_nodeId)) : false;
}

bool JsDocument::treeNodeHasSubShapes(unsigned treeNodeId) const
bool ScriptTreeNode::hasSubShapes() const
{
return XCaf::hasShapeSubs(this->treeNodeLabel(treeNodeId));
return m_doc ? XCaf::hasShapeSubs(documentTreeNodeLabel(m_doc, m_nodeId)) : false;
}

QStringList JsDocument::treeNodeSubShapeTags(unsigned treeNodeId) const
QStringList ScriptTreeNode::subShapeTags() const
{
QStringList listTag;
const TDF_LabelSequence seqShapeSubLabel = XCaf::shapeSubs(this->treeNodeLabel(treeNodeId));
const TDF_LabelSequence seqShapeSubLabel = XCaf::shapeSubs(documentTreeNodeLabel(m_doc, m_nodeId));
for (const TDF_Label& label : seqShapeSubLabel)
listTag.push_back(to_QString(CafUtils::labelTag(label)));

return listTag;
}

QColor JsDocument::tagShapeColor(const QString& tag) const
QVariant ScriptTreeNode::shape() const
{
if (!m_doc)
return {};

TDF_Label label;
TDF_Tool::Label(m_doc->GetData(), to_OccAsciiString(tag), label);
if (label.IsNull())
return {};

return QtGuiUtils::toQColor(m_doc->xcaf().shapeColor(label));
const TopoDS_Shape shape = XCaf::shape(documentTreeNodeLabel(m_doc, m_nodeId));
return QVariant::fromValue(ScriptShape(shape));
}

JsDocument::JsDocument(const DocumentPtr& doc, JsApplication* jsApp)
: QObject(jsApp),
m_doc(doc)
bool ScriptShape::hasTransformation() const
{
m_sigConns
<< doc->signalNameChanged.connectSlot([=](const std::string&) { emit this->nameChanged(); })
<< doc->signalFilePathChanged.connectSlot([=](const FilePath&) { emit this->filePathChanged(); })
<< doc->signalEntityAdded.connectSlot([=](TreeNodeId) { emit this->entityCountChanged(); })
<< doc->signalEntityAboutToBeDestroyed.connectSlot([=](TreeNodeId) { emit this->entityCountChanged(); })
;
return !m_shape.Location().IsIdentity();
}

const TDF_Label& JsDocument::treeNodeLabel(unsigned treeNodeId) const
QVariantList ScriptShape::transformation() const
{
static const TDF_Label nullLabel;
return m_doc ? m_doc->modelTree().nodeData(treeNodeId) : nullLabel;
const gp_Trsf& trsf = m_shape.Location().Transformation();
QVariantList mat;
for (int row = 1; row <= 3; ++row) {
for (int col = 1; col <= 4; ++col)
mat.push_back(trsf.Value(row, col));
}

mat.push_back(0.);
mat.push_back(0.);
mat.push_back(0.);
mat.push_back(1.);
return mat;
}

} // namespace Mayo
74 changes: 64 additions & 10 deletions src/qtscripting/js_document.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
#include "../base/signal.h"

#include <TDF_Label.hxx>
#include <TopoDS_Shape.hxx>

#include <QtCore/QObject>
#include <QtCore/QVariant>
#include <QtQml/QJSValue>

// Notes
Expand Down Expand Up @@ -47,10 +49,65 @@
// JsDocument::hasShapeColor(string tags) -> bool
// JsDocument::shapeColor(string tags) -> string("#RRGGBBAA")

namespace Mayo {

class ScriptShape {
Q_GADGET
Q_PROPERTY(unsigned type READ type)
Q_PROPERTY(unsigned orientation READ orientation)
Q_PROPERTY(bool hasTransformation READ hasTransformation)
Q_PROPERTY(QVariantList transformation READ transformation)
public:
ScriptShape() = default;
ScriptShape(const TopoDS_Shape& shape) : m_shape(shape) {}

unsigned type() const { return m_shape.ShapeType(); }
unsigned orientation() const { return m_shape.Orientation(); }

namespace Mayo {
bool hasTransformation() const;
QVariantList transformation() const;

private:
TopoDS_Shape m_shape;
};

class ScriptTreeNode {
Q_GADGET
Q_PROPERTY(unsigned id READ id)
Q_PROPERTY(unsigned parentId READ parentId)
Q_PROPERTY(QString tag READ tag)
Q_PROPERTY(QString name READ name)
Q_PROPERTY(bool isAssembly READ isAssembly)
Q_PROPERTY(bool isInstance READ isInstance)
Q_PROPERTY(bool isProduct READ isProduct)
Q_PROPERTY(bool isComponent READ isComponent)
Q_PROPERTY(bool hasSubShapes READ hasSubShapes)
Q_PROPERTY(QStringList subShapeTags READ subShapeTags)
Q_PROPERTY(QVariant shape READ shape)
public:
ScriptTreeNode() = default;
ScriptTreeNode(const DocumentPtr& doc, TreeNodeId nodeId);

unsigned id() const { return m_nodeId; }
unsigned parentId() const;

QString tag() const; // TODO Could be TDF_Label wrapped in QVariant
QString name() const;

bool isAssembly() const;
bool isInstance() const;
bool isProduct() const;
bool isComponent() const;
bool hasSubShapes() const;

QStringList subShapeTags() const;

QVariant shape() const;

private:
DocumentPtr m_doc;
TreeNodeId m_nodeId = 0;
};

class JsApplication;

Expand All @@ -70,18 +127,12 @@ class JsDocument : public QObject {

int entityCount() const;
Q_INVOKABLE void traverseModelTree(QJSValue fn);
Q_INVOKABLE QString treeNodeName(unsigned treeNodeId) const;
Q_INVOKABLE unsigned treeNodeParent(unsigned treeNodeId) const;
Q_INVOKABLE bool treeNodeIsAssembly(unsigned treeNodeId) const;
Q_INVOKABLE bool treeNodeIsInstance(unsigned treeNodeId) const;
Q_INVOKABLE bool treeNodeIsProduct(unsigned treeNodeId) const;
Q_INVOKABLE bool treeNodeIsComponent(unsigned treeNodeId) const;
Q_INVOKABLE QString treeNodeTag(unsigned treeNodeId) const;
Q_INVOKABLE bool treeNodeHasSubShapes(unsigned treeNodeId) const;
Q_INVOKABLE QStringList treeNodeSubShapeTags(unsigned treeNodeId) const;
Q_INVOKABLE QVariant treeNode(unsigned treeNodeId) const;
// Q_INVOKABLE bool tagHasShapeColor(const QString& tag) const;
Q_INVOKABLE QColor tagShapeColor(const QString& tag) const;

Q_INVOKABLE void traverseTreeNodeShape(unsigned treeNodeId, unsigned shapeTypeFiler, QJSValue fn);

signals:
void nameChanged();
void filePathChanged();
Expand All @@ -100,3 +151,6 @@ class JsDocument : public QObject {
};

} // namespace Mayo

Q_DECLARE_METATYPE(Mayo::ScriptTreeNode)
Q_DECLARE_METATYPE(Mayo::ScriptShape)

0 comments on commit 58220ec

Please sign in to comment.