Added support for notch data type dependency.

This commit is contained in:
Roman Telezhynskyi 2023-11-20 15:15:51 +02:00
parent 348b7c4e8a
commit 6041dd52b6
7 changed files with 275 additions and 81 deletions

View file

@ -52,6 +52,9 @@ void dx_iface::writeEntity(DRW_Entity *e)
case DRW::ASTMNOTCH:
dxfW->writeASTMNotch(static_cast<DRW_ASTMNotch *>(e));
break;
case DRW::ATTDEF:
dxfW->writeATTDEF(static_cast<DRW_ATTDEF *>(e));
break;
case DRW::LINE:
dxfW->writeLine(static_cast<DRW_Line *>(e));
break;

View file

@ -1359,3 +1359,31 @@ auto DRW_Viewport::parseCode(int code, const std::unique_ptr<dxfReader> &reader)
return true;
}
auto DRW_ATTDEF::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{
switch (code)
{
case 40:
height = reader->getDouble();
break;
case 1:
text = reader->getString();
break;
case 2:
name = reader->getString();
break;
case 3:
promptString = reader->getString();
break;
case 70:
flags = reader->getInt32();
break;
case 73:
horizontalAdjustment = reader->getInt32();
break;
default:
return DRW_Point::parseCode(code, reader);
}
return true;
}

View file

@ -35,7 +35,7 @@ enum ETYPE
// E3DSOLID, //encripted propietry data
// ACAD_PROXY_ENTITY,
ARC,
// ATTDEF,
ATTDEF,
// ATTRIB,
BLOCK, // and ENDBLK
// BODY, //encripted propietry data
@ -274,6 +274,26 @@ public:
double angle{0}; /*!< angle, code 50 */
};
class DRW_ATTDEF : public DRW_Point
{
SETENTFRIENDS
public:
DRW_ATTDEF() { eType = DRW::ATTDEF; }
protected:
auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public:
DRW_Coord adjustmentPoint{}; /*!< alignment point, code 11, 21 & 31 */
double height{0}; /*!< height text, code 40 */
UTF8STRING text{}; /*!< text string, code 1 */
UTF8STRING name{}; /*!< name, code 2 */
UTF8STRING promptString{}; /*!< prompt string, code 3 */
int flags{0}; /*!< flags, code 70 */
int horizontalAdjustment{0}; /*!< Horizontal text justification, code 72, default 0 */
};
//! Class to handle line entity
/*!
* Class to handle line entity

View file

@ -732,6 +732,45 @@ auto dxfRW::writeASTMNotch(DRW_ASTMNotch *ent) -> bool
return true;
}
auto dxfRW::writeATTDEF(DRW_ATTDEF *ent) -> bool
{
writer->writeString(0, "ATTDEF");
writeEntity(ent);
if (version > DRW::AC1009)
{
writer->writeString(100, "AcDbText");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
if (not qFuzzyIsNull(ent->basePoint.z))
{
writer->writeDouble(30, ent->basePoint.z);
}
writer->writeDouble(11, ent->adjustmentPoint.x);
writer->writeDouble(21, ent->adjustmentPoint.y);
if (not qFuzzyIsNull(ent->adjustmentPoint.z))
{
writer->writeDouble(31, ent->adjustmentPoint.z);
}
writer->writeDouble(40, ent->height);
writer->writeString(1, ent->text);
UTF8STRING name = ent->name;
std::replace(name.begin(), name.end(), ' ', '_');
writer->writeString(2, name);
writer->writeString(3, ent->promptString);
writer->writeInt16(70, ent->flags);
writer->writeInt16(73, ent->horizontalAdjustment);
return true;
}
auto dxfRW::writeLine(DRW_Line *ent) -> bool
{
writer->writeString(0, "LINE");

View file

@ -56,6 +56,7 @@ public:
auto writeAppId(DRW_AppId *ent) -> bool;
auto writePoint(DRW_Point *ent) -> bool;
auto writeASTMNotch(DRW_ASTMNotch *ent) -> bool;
auto writeATTDEF(DRW_ATTDEF *ent) -> bool;
auto writeLine(DRW_Line *ent) -> bool;
auto writeRay(DRW_Ray *ent) -> bool;
auto writeXline(DRW_Xline *ent) -> bool;

View file

@ -27,7 +27,6 @@
*************************************************************************/
#include "vdxfengine.h"
#include <QLineF>
#include <QByteArray>
#include <QColor>
@ -59,6 +58,7 @@
#include "../vlayout/vlayoutpoint.h"
#include "../vmisc/def.h"
#include "dxiface.h"
#include "libdxfrw/drw_entities.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
#include "../vmisc/compatibility.h"
@ -976,7 +976,7 @@ auto VDxfEngine::ExportToASTM(const QVector<VLayoutPiece> &details) -> bool
ExportASTMSewLine(detailBlock, detail);
ExportASTMInternalLine(detailBlock, detail);
ExportASTMInternalCutout(detailBlock, detail);
ExportASTMNotch(detailBlock, detail);
ExportASTMNotches(detailBlock, detail);
ExportAAMAGrainline(detailBlock, detail);
ExportPieceText(detailBlock, detail);
ExportASTMDrill(detailBlock, detail);
@ -1152,90 +1152,135 @@ void VDxfEngine::ExportASTMDrill(const QSharedPointer<dx_ifaceBlock> &detailBloc
}
//---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportASTMNotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
void VDxfEngine::ExportASTMNotches(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{
if (detail.IsSeamAllowance())
if (!detail.IsSeamAllowance())
{
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
for (const auto &passmark : passmarks)
return;
}
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
for (const auto &passmark : passmarks)
{
DRW_ASTMNotch *notch = ExportASTMNotch(passmark);
DRW_ATTDEF *attdef = ExportASTMNotchDataDependecy(passmark, notch->layer, detail);
detailBlock->ent.push_back(notch);
if (attdef)
{
auto *notch = new DRW_ASTMNotch();
const QPointF center = passmark.baseLine.p1();
notch->basePoint = DRW_Coord(FromPixel(center.x(), m_varInsunits),
FromPixel(GetSize().height() - center.y(), m_varInsunits),
FromPixel(passmark.baseLine.length(), m_varInsunits));
notch->angle = passmark.baseLine.angle();
switch (passmark.type)
{
case PassmarkLineType::OneLine:
case PassmarkLineType::TwoLines:
case PassmarkLineType::ThreeLines:
// Slit notch
notch->layer = *layer4;
break;
case PassmarkLineType::ExternalVMark:
case PassmarkLineType::InternalVMark:
{ // V-Notch
QLineF boundaryLine(passmark.lines.constFirst().p1(), passmark.lines.constLast().p2());
notch->thickness = FromPixel(boundaryLine.length(), m_varInsunits); // width
notch->layer = *layer4;
break;
}
case PassmarkLineType::TMark:
// T-Notch
notch->thickness = FromPixel(passmark.lines.constLast().length(), m_varInsunits); // width
notch->layer = *layer80;
break;
case PassmarkLineType::BoxMark:
{ // Castle Notch
QPointF start = passmark.lines.constFirst().p1();
QPointF end = passmark.lines.constLast().p2();
notch->layer = *layer81;
notch->thickness = FromPixel(QLineF(start, end).length(), m_varInsunits); // width
break;
}
case PassmarkLineType::UMark:
{ // U-Notch
QPointF start = passmark.lines.constFirst().p1();
QPointF end = passmark.lines.constLast().p2();
notch->thickness = FromPixel(QLineF(start, end).length(), m_varInsunits); // width
notch->layer = *layer83;
break;
}
case PassmarkLineType::CheckMark:
{ // Check Notch
const QLineF &line1 = passmark.lines.constFirst();
const QLineF &line2 = passmark.lines.constLast();
qreal width = QLineF(line1.p1(), line2.p2()).length();
if (not passmark.isClockwiseOpening)
{ // a counter clockwise opening
width *= -1;
}
notch->thickness = FromPixel(width, m_varInsunits); // width
notch->layer = *layer82;
break;
}
case PassmarkLineType::LAST_ONE_DO_NOT_USE:
Q_UNREACHABLE();
break;
default:
break;
};
detailBlock->ent.push_back(notch);
detailBlock->ent.push_back(attdef);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::ExportASTMNotch(const VLayoutPassmark &passmark) -> DRW_ASTMNotch *
{
auto *notch = new DRW_ASTMNotch();
const QPointF center = passmark.baseLine.p1();
notch->basePoint =
DRW_Coord(FromPixel(center.x(), m_varInsunits), FromPixel(GetSize().height() - center.y(), m_varInsunits),
FromPixel(passmark.baseLine.length(), m_varInsunits));
notch->angle = passmark.baseLine.angle();
switch (passmark.type)
{
case PassmarkLineType::OneLine:
case PassmarkLineType::TwoLines:
case PassmarkLineType::ThreeLines:
// Slit notch
notch->layer = *layer4;
break;
case PassmarkLineType::ExternalVMark:
case PassmarkLineType::InternalVMark:
{ // V-Notch
QLineF boundaryLine(passmark.lines.constFirst().p1(), passmark.lines.constLast().p2());
notch->thickness = FromPixel(boundaryLine.length(), m_varInsunits); // width
notch->layer = *layer4;
break;
}
case PassmarkLineType::TMark:
// T-Notch
notch->thickness = FromPixel(passmark.lines.constLast().length(), m_varInsunits); // width
notch->layer = *layer80;
break;
case PassmarkLineType::BoxMark:
{ // Castle Notch
QPointF start = passmark.lines.constFirst().p1();
QPointF end = passmark.lines.constLast().p2();
notch->layer = *layer81;
notch->thickness = FromPixel(QLineF(start, end).length(), m_varInsunits); // width
break;
}
case PassmarkLineType::UMark:
{ // U-Notch
QPointF start = passmark.lines.constFirst().p1();
QPointF end = passmark.lines.constLast().p2();
notch->thickness = FromPixel(QLineF(start, end).length(), m_varInsunits); // width
notch->layer = *layer83;
break;
}
case PassmarkLineType::CheckMark:
{ // Check Notch
const QLineF &line1 = passmark.lines.constFirst();
const QLineF &line2 = passmark.lines.constLast();
qreal width = QLineF(line1.p1(), line2.p2()).length();
if (not passmark.isClockwiseOpening)
{ // a counter clockwise opening
width *= -1;
}
notch->thickness = FromPixel(width, m_varInsunits); // width
notch->layer = *layer82;
break;
}
case PassmarkLineType::LAST_ONE_DO_NOT_USE:
Q_UNREACHABLE();
break;
default:
break;
};
return notch;
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::ExportASTMNotchDataDependecy(const VLayoutPassmark &passmark, const UTF8STRING &notchLayer,
const VLayoutPiece &detail) -> DRW_ATTDEF *
{
QVector<VLayoutPoint> boundary = not detail.IsSeamAllowanceBuiltIn() && !passmark.isBuiltIn
? detail.GetMappedSeamAllowancePoints()
: detail.GetMappedContourPoints();
const QPointF center = passmark.baseLine.p1();
QPointF referencePoint;
if (not NotchPrecedingPoint(boundary, center, referencePoint))
{
return nullptr;
}
auto *attdef = new DRW_ATTDEF();
attdef->layer = not detail.IsSeamAllowanceBuiltIn() && !passmark.isBuiltIn ? *layer1 : *layer14;
attdef->basePoint = DRW_Coord(FromPixel(referencePoint.x(), m_varInsunits),
FromPixel(GetSize().height() - referencePoint.y(), m_varInsunits), 0);
attdef->adjustmentPoint =
DRW_Coord(FromPixel(center.x(), m_varInsunits), FromPixel(GetSize().height() - center.y(), m_varInsunits), 0);
attdef->height = 3.0;
attdef->text = "Link:" + notchLayer;
attdef->name = "Dependency";
attdef->flags = 2; // this is a constant attribute
attdef->horizontalAdjustment = 3; // aligned (if vertical alignment = 0)
return attdef;
}
//---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportTurnPoints(const QSharedPointer<dx_ifaceBlock> &detailBlock,
const QVector<VLayoutPoint> &points) const
@ -1335,6 +1380,55 @@ auto VDxfEngine::GetFileNameForLocale() const -> std::string
#endif
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::NotchPrecedingPoint(const QVector<VLayoutPoint> &boundary, QPointF notchBase, QPointF &point) -> bool
{
if (boundary.count() < 2)
{
return false;
}
if (VFuzzyComparePoints(boundary.constFirst(), notchBase))
{
point = boundary.constFirst();
return true;
}
if (VFuzzyComparePoints(boundary.constLast(), notchBase))
{
point = boundary.constLast();
return true;
}
QPointF candidatePoint;
qreal bestDistance = INT_MAX;
bool found = false;
for (qint32 i = 0; i < boundary.count() - 1; ++i)
{
const QPointF cPoint = VGObject::ClosestPoint(QLineF(boundary.at(i), boundary.at(i + 1)), notchBase);
if (VGObject::IsPointOnLineSegment(cPoint, boundary.at(i), boundary.at(i + 1)))
{
const qreal length = QLineF(notchBase, cPoint).length();
if (length < bestDistance)
{
candidatePoint = boundary.at(i);
bestDistance = length;
found = true;
}
}
}
if (found)
{
point = candidatePoint;
return true;
}
return found;
}
//---------------------------------------------------------------------------------------------------------------------
template <class P, class V, class C>
auto VDxfEngine::CreateAAMAPolygon(const QVector<C> &polygon, const UTF8STRING &layer, bool forceClosed) -> P *

View file

@ -50,6 +50,9 @@ class DRW_Entity;
class dx_ifaceBlock;
class VLayoutPoint;
class DRW_Point;
class DRW_ASTMNotch;
struct VLayoutPassmark;
class DRW_ATTDEF;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
class VTextCodec;
@ -148,7 +151,11 @@ private:
void ExportASTMInternalCutout(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMAnnotationText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMDrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMNotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMNotches(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
Q_REQUIRED_RESULT auto ExportASTMNotch(const VLayoutPassmark &passmark) -> DRW_ASTMNotch *;
Q_REQUIRED_RESULT auto ExportASTMNotchDataDependecy(const VLayoutPassmark &passmark, const UTF8STRING &notchLayer,
const VLayoutPiece &detail) -> DRW_ATTDEF *;
void ExportTurnPoints(const QSharedPointer<dx_ifaceBlock> &detailBlock, const QVector<VLayoutPoint> &points) const;
void ExportCurvePoints(const QSharedPointer<dx_ifaceBlock> &detailBlock, const QVector<VLayoutPoint> &points) const;
@ -165,6 +172,8 @@ private:
static auto FromUnicodeToCodec(const QString &str, VTextCodec *codec) -> std::string;
auto GetFileNameForLocale() const -> std::string;
static auto NotchPrecedingPoint(const QVector<VLayoutPoint> &boundary, QPointF notchBase, QPointF &point) -> bool;
};
#endif // VDXFENGINE_H