Base: refactor InventorBuilder and add more unit tests
This commit is contained in:
@@ -89,7 +89,7 @@ std::string DrawStyle::patternAsString() const
|
||||
return str.str();
|
||||
}
|
||||
|
||||
const char* MaterialBinding::bindingAsString() const
|
||||
const char* BindingElement::bindingAsString() const
|
||||
{
|
||||
switch (value) {
|
||||
case Binding::PerPart:
|
||||
@@ -178,6 +178,25 @@ void InventorOutput::decreaseIndent()
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void NodeItem::writeField(const char* field, const std::vector<Vector3f>& vec, InventorOutput& out) const
|
||||
{
|
||||
if (vec.empty())
|
||||
return;
|
||||
|
||||
if (vec.size() == 1) {
|
||||
out.write() << field << " " << vec[0].x << " " << vec[0].y << " " << vec[0].z << '\n';
|
||||
}
|
||||
else {
|
||||
out.write() << field << " [\n";
|
||||
out.increaseIndent();
|
||||
for (auto it : vec) {
|
||||
out.write() << it.x << " " << it.y << " " << it.z << '\n';
|
||||
}
|
||||
out.decreaseIndent();
|
||||
out.write() << "]\n";
|
||||
}
|
||||
}
|
||||
|
||||
void NodeItem::writeField(const char* field, const std::vector<ColorRGB>& rgb, InventorOutput& out) const
|
||||
{
|
||||
if (rgb.empty())
|
||||
@@ -312,6 +331,56 @@ void LineItem::write(InventorOutput& out) const
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ArrowItem::ArrowItem(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& rgb)
|
||||
: line(line)
|
||||
, drawStyle(drawStyle)
|
||||
, rgb(rgb)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ArrowItem::write(InventorOutput& out) const
|
||||
{
|
||||
float length = line.Length();
|
||||
float coneLength = length / 10.0F;
|
||||
float coneRadius = coneLength / 2.0F;
|
||||
float sf1 = length - coneLength;
|
||||
float sf2 = length - coneLength/2.0F;
|
||||
|
||||
Vector3f dir = line.GetDirection();
|
||||
dir.Normalize();
|
||||
dir.Scale(sf1, sf1, sf1);
|
||||
Vector3f pt2s = line.p1 + dir;
|
||||
dir.Normalize();
|
||||
dir.Scale(sf2, sf2, sf2);
|
||||
Vector3f cpt = line.p1 + dir;
|
||||
|
||||
Vector3f rot = Vector3f(0.0f, 1.0f, 0.0f) % dir;
|
||||
rot.Normalize();
|
||||
float angle = Vector3f(0.0f, 1.0f, 0.0f).GetAngle(dir);
|
||||
|
||||
out.write() << "Separator {\n";
|
||||
out.write() << " Material { diffuseColor " << rgb.red() << " "<< rgb.green() << " "<< rgb.blue() << "}\n";
|
||||
out.write() << " DrawStyle { lineWidth " << drawStyle.lineWidth << " }\n";
|
||||
out.write() << " Coordinate3 {\n";
|
||||
out.write() << " point [ ";
|
||||
out.write() << line.p1.x << " " << line.p1.y << " " << line.p1.z << ", ";
|
||||
out.write() << pt2s.x << " " << pt2s.y << " " << pt2s.z;
|
||||
out.write() << " ]\n";
|
||||
out.write() << " }\n";
|
||||
out.write() << " LineSet { }\n";
|
||||
out.write() << " Transform { \n";
|
||||
out.write() << " translation "
|
||||
<< cpt.x << " " << cpt.y << " " << cpt.z << '\n';
|
||||
out.write() << " rotation "
|
||||
<< rot.x << " " << rot.y << " " << rot.z << " " << angle << '\n';
|
||||
out.write() << " }\n";
|
||||
out.write() << " Cone { bottomRadius " << coneRadius << " height " << coneLength << "} \n";
|
||||
out.write() << "}\n";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void MaterialItem::setAmbientColor(const std::vector<ColorRGB>& rgb)
|
||||
{
|
||||
ambientColor = rgb;
|
||||
@@ -398,15 +467,15 @@ void MaterialItem::writeTransparency(InventorOutput& out) const
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
MaterialBindingItem::MaterialBindingItem(MaterialBinding bind) : bind(bind)
|
||||
void MaterialBindingItem::setValue(BindingElement::Binding bind)
|
||||
{
|
||||
|
||||
value.value = bind;
|
||||
}
|
||||
|
||||
void MaterialBindingItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "MaterialBinding { value "
|
||||
<< bind.bindingAsString() << " } \n";
|
||||
<< value.bindingAsString() << " } \n";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -466,6 +535,95 @@ void PointSetItem::write(InventorOutput& out) const
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void NormalItem::setVector(const std::vector<Base::Vector3f>& vec)
|
||||
{
|
||||
vector = vec;
|
||||
}
|
||||
|
||||
void NormalItem::write(InventorOutput& out) const
|
||||
{
|
||||
beginNormal(out);
|
||||
writeField("vector", vector, out);
|
||||
endNormal(out);
|
||||
}
|
||||
|
||||
void NormalItem::beginNormal(InventorOutput& out) const
|
||||
{
|
||||
out.writeLine("Normal {");
|
||||
out.increaseIndent();
|
||||
}
|
||||
|
||||
void NormalItem::endNormal(InventorOutput& out) const
|
||||
{
|
||||
out.decreaseIndent();
|
||||
out.writeLine("}");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void NormalBindingItem::setValue(BindingElement::Binding bind)
|
||||
{
|
||||
value.value = bind;
|
||||
}
|
||||
|
||||
void NormalBindingItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "NormalBinding { value "
|
||||
<< value.bindingAsString() << " }\n";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void CylinderItem::setRadius(float value)
|
||||
{
|
||||
radius = value;
|
||||
}
|
||||
|
||||
void CylinderItem::setHeight(float value)
|
||||
{
|
||||
height = value;
|
||||
}
|
||||
|
||||
void CylinderItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "Cylinder {\n";
|
||||
out.write() << " radius " << radius << "\n";
|
||||
out.write() << " height " << height << "\n";
|
||||
out.write() << " parts (SIDES | TOP | BOTTOM)\n";
|
||||
out.write() << "}\n";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ConeItem::setBottomRadius(float value)
|
||||
{
|
||||
bottomRadius = value;
|
||||
}
|
||||
|
||||
void ConeItem::setHeight(float value)
|
||||
{
|
||||
height = value;
|
||||
}
|
||||
|
||||
void ConeItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "Cone { bottomRadius " << bottomRadius << " height " << height << " }\n";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void SphereItem::setRadius(float value)
|
||||
{
|
||||
radius = value;
|
||||
}
|
||||
|
||||
void SphereItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "Sphere { radius " << radius << " }\n";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
InventorBuilder::InventorBuilder(std::ostream& output)
|
||||
: result(output)
|
||||
{
|
||||
@@ -557,7 +715,7 @@ void InventorBuilder::addColor(const ColorRGB& rgb)
|
||||
result << rgb.red() << " " << rgb.green() << " " << rgb.blue() << '\n';
|
||||
}
|
||||
|
||||
void InventorBuilder::addMaterialBinding(MaterialBinding bind)
|
||||
void InventorBuilder::addMaterialBinding(BindingElement bind)
|
||||
{
|
||||
result << indent << "MaterialBinding { value "
|
||||
<< bind.bindingAsString() << " } \n";
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
unsigned short linePattern = 0xffff;
|
||||
};
|
||||
|
||||
class BaseExport MaterialBinding
|
||||
class BaseExport BindingElement
|
||||
{
|
||||
public:
|
||||
enum class Binding {
|
||||
@@ -192,6 +192,7 @@ public:
|
||||
virtual void write(InventorOutput& out) const = 0;
|
||||
|
||||
protected:
|
||||
void writeField(const char* field, const std::vector<Vector3f>& vec, InventorOutput& out) const;
|
||||
void writeField(const char* field, const std::vector<ColorRGB>& rgb, InventorOutput& out) const;
|
||||
void writeField(const char* field, const std::vector<float>& value, InventorOutput& out) const;
|
||||
};
|
||||
@@ -259,6 +260,18 @@ private:
|
||||
ColorRGB rgb;
|
||||
};
|
||||
|
||||
class BaseExport ArrowItem : public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit ArrowItem(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& rgb = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
Base::Line3f line;
|
||||
DrawStyle drawStyle;
|
||||
ColorRGB rgb;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The MaterialItem class supports the SoMaterial node.
|
||||
*/
|
||||
@@ -298,11 +311,12 @@ private:
|
||||
class BaseExport MaterialBindingItem : public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit MaterialBindingItem(MaterialBinding bind);
|
||||
MaterialBindingItem() = default;
|
||||
void setValue(BindingElement::Binding bind);
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
MaterialBinding bind;
|
||||
BindingElement value;
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -353,6 +367,79 @@ public:
|
||||
void write(InventorOutput& out) const override;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The NormalItem class supports the SoNormal node.
|
||||
*/
|
||||
class BaseExport NormalItem : public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit NormalItem() = default;
|
||||
void setVector(const std::vector<Base::Vector3f>& vec);
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
void beginNormal(InventorOutput& out) const;
|
||||
void endNormal(InventorOutput& out) const;
|
||||
std::vector<Base::Vector3f> vector;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The MaterialBindingItem class supports the SoMaterialBinding node.
|
||||
*/
|
||||
class BaseExport NormalBindingItem : public NodeItem
|
||||
{
|
||||
public:
|
||||
NormalBindingItem() = default;
|
||||
void setValue(BindingElement::Binding bind);
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
BindingElement value;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The CylinderItem class supports the SoCylinder node.
|
||||
*/
|
||||
class BaseExport CylinderItem : public NodeItem
|
||||
{
|
||||
public:
|
||||
void setRadius(float);
|
||||
void setHeight(float);
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
float radius = 2.0F;
|
||||
float height = 10.0F;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The ConeItem class supports the SoCone node.
|
||||
*/
|
||||
class BaseExport ConeItem : public NodeItem
|
||||
{
|
||||
public:
|
||||
void setBottomRadius(float);
|
||||
void setHeight(float);
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
float bottomRadius = 2.0F;
|
||||
float height = 10.0F;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The SphereItem class supports the SoSphere node.
|
||||
*/
|
||||
class BaseExport SphereItem : public NodeItem
|
||||
{
|
||||
public:
|
||||
void setRadius(float);
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
float radius = 2.0F;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class does basically the same as Builder3D except that it writes the data
|
||||
* directly into a given stream without buffering the output data in a string stream.
|
||||
@@ -423,7 +510,7 @@ public:
|
||||
* \brief Sets a material binding node.
|
||||
* \param binding - binding of the material.
|
||||
*/
|
||||
void addMaterialBinding(MaterialBinding);
|
||||
void addMaterialBinding(BindingElement);
|
||||
/*!
|
||||
* \brief Sets a draw style node.
|
||||
*/
|
||||
|
||||
@@ -73,7 +73,7 @@ private Q_SLOTS:
|
||||
{
|
||||
QFETCH(QString, result);
|
||||
|
||||
Base::MaterialBindingItem item{Base::MaterialBinding{}};
|
||||
Base::MaterialBindingItem item;
|
||||
builder.addNode(item);
|
||||
QString string = QString::fromStdString(output.str());
|
||||
|
||||
@@ -292,6 +292,29 @@ R"(PolygonOffset {
|
||||
QCOMPARE(string, result);
|
||||
}
|
||||
|
||||
void test_Normal_data()
|
||||
{
|
||||
auto result =
|
||||
R"(Normal {
|
||||
vector 1 0 0.5
|
||||
}
|
||||
)";
|
||||
QTest::addColumn<QString>("result");
|
||||
QTest::newRow("Normal") << result;
|
||||
}
|
||||
|
||||
void test_Normal()
|
||||
{
|
||||
QFETCH(QString, result);
|
||||
|
||||
Base::NormalItem item;
|
||||
item.setVector({Base::Vector3f{1,0,0.5}});
|
||||
builder.addNode(item);
|
||||
QString string = QString::fromStdString(output.str());
|
||||
|
||||
QCOMPARE(string, result);
|
||||
}
|
||||
|
||||
void test_LineItem()
|
||||
{
|
||||
Base::Line3f line;
|
||||
@@ -303,6 +326,19 @@ R"(PolygonOffset {
|
||||
QVERIFY(node != nullptr);
|
||||
}
|
||||
|
||||
void test_ArrowItem()
|
||||
{
|
||||
Base::Line3f line;
|
||||
line.p2.z = 10;
|
||||
Base::DrawStyle style;
|
||||
Base::ArrowItem item{line, style};
|
||||
builder.addNode(item);
|
||||
|
||||
qDebug() << QString::fromStdString(output.str());
|
||||
SoNode* node = loadBuffer(output.str());
|
||||
QVERIFY(node != nullptr);
|
||||
}
|
||||
|
||||
void test_PointItem()
|
||||
{
|
||||
Base::Vector3f pnt;
|
||||
@@ -314,6 +350,90 @@ R"(PolygonOffset {
|
||||
QVERIFY(node != nullptr);
|
||||
}
|
||||
|
||||
void test_NormalBinding_data()
|
||||
{
|
||||
auto result = "NormalBinding { value PER_PART }\n";
|
||||
QTest::addColumn<QString>("result");
|
||||
QTest::newRow("NormalBinding") << result;
|
||||
}
|
||||
|
||||
void test_NormalBinding()
|
||||
{
|
||||
QFETCH(QString, result);
|
||||
|
||||
Base::NormalBindingItem item;
|
||||
item.setValue(Base::BindingElement::Binding::PerPart);
|
||||
builder.addNode(item);
|
||||
QString string = QString::fromStdString(output.str());
|
||||
|
||||
QCOMPARE(string, result);
|
||||
}
|
||||
|
||||
void test_Cylinder_data()
|
||||
{
|
||||
auto result =
|
||||
R"(Cylinder {
|
||||
radius 3
|
||||
height 7
|
||||
parts (SIDES | TOP | BOTTOM)
|
||||
}
|
||||
)";
|
||||
QTest::addColumn<QString>("result");
|
||||
QTest::newRow("Cylinder") << result;
|
||||
}
|
||||
|
||||
void test_Cylinder()
|
||||
{
|
||||
QFETCH(QString, result);
|
||||
|
||||
Base::CylinderItem item;
|
||||
item.setRadius(3);
|
||||
item.setHeight(7);
|
||||
builder.addNode(item);
|
||||
QString string = QString::fromStdString(output.str());
|
||||
|
||||
QCOMPARE(string, result);
|
||||
}
|
||||
|
||||
void test_Cone_data()
|
||||
{
|
||||
auto result = "Cone { bottomRadius 2 height 10 }\n";
|
||||
QTest::addColumn<QString>("result");
|
||||
QTest::newRow("Cone") << result;
|
||||
}
|
||||
|
||||
void test_Cone()
|
||||
{
|
||||
QFETCH(QString, result);
|
||||
|
||||
Base::ConeItem item;
|
||||
item.setBottomRadius(2);
|
||||
item.setHeight(10);
|
||||
builder.addNode(item);
|
||||
QString string = QString::fromStdString(output.str());
|
||||
|
||||
QCOMPARE(string, result);
|
||||
}
|
||||
|
||||
void test_Sphere_data()
|
||||
{
|
||||
auto result = "Sphere { radius 4 }\n";
|
||||
QTest::addColumn<QString>("result");
|
||||
QTest::newRow("Sphere") << result;
|
||||
}
|
||||
|
||||
void test_Sphere()
|
||||
{
|
||||
QFETCH(QString, result);
|
||||
|
||||
Base::SphereItem item;
|
||||
item.setRadius(4);
|
||||
builder.addNode(item);
|
||||
QString string = QString::fromStdString(output.str());
|
||||
|
||||
QCOMPARE(string, result);
|
||||
}
|
||||
|
||||
private:
|
||||
std::stringstream output;
|
||||
Base::InventorBuilder builder;
|
||||
|
||||
Reference in New Issue
Block a user