| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | #include<iostream> |
| | #include "lc_tolerance.h" |
| |
|
| | #include <QRegularExpression> |
| |
|
| | #include "rs_color.h" |
| | #include "rs_debug.h" |
| | #include "rs_document.h" |
| | #include "rs_filterdxfrw.h" |
| | #include "rs_line.h" |
| | #include "rs_text.h" |
| | #include "rs_units.h" |
| |
|
| | LC_ToleranceData::~LC_ToleranceData() = default; |
| |
|
| | LC_Tolerance::LC_Tolerance(RS_EntityContainer* parent, const LC_ToleranceData& d) |
| | :RS_EntityContainer(parent), m_toleranceData(d){ |
| | RS_EntityContainer::calculateBorders(); |
| | } |
| |
|
| | RS_Entity* LC_Tolerance::clone() const { |
| | auto* d = new LC_Tolerance(*this); |
| | d->setOwner(isOwner()); |
| | d->detach(); |
| | return d; |
| | } |
| |
|
| | void LC_Tolerance::update() { |
| | clear(); |
| | if (isUndone()) { |
| | return; |
| | } |
| |
|
| | doUpdateDim(); |
| |
|
| | calculateBorders(); |
| | } |
| |
|
| | RS_VectorSolutions LC_Tolerance::getRefPoints() const { |
| | return {m_toleranceData.m_insertionPoint}; |
| | } |
| |
|
| | void LC_Tolerance::move(const RS_Vector& offset) { |
| | m_toleranceData.m_insertionPoint.move(offset); |
| | update(); |
| | } |
| |
|
| | void LC_Tolerance::rotate(const RS_Vector& center, double angle) { |
| | m_toleranceData.m_insertionPoint.rotate(center, angle); |
| | update(); |
| | } |
| |
|
| | void LC_Tolerance::rotate(const RS_Vector& center, const RS_Vector& angleVector) { |
| | m_toleranceData.m_insertionPoint.rotate(center, angleVector); |
| | update(); |
| | } |
| |
|
| | void LC_Tolerance::scale(const RS_Vector& center, const RS_Vector& factor) { |
| | m_toleranceData.m_insertionPoint.scale(center, factor); |
| | update(); |
| | } |
| |
|
| | void LC_Tolerance::mirror(const RS_Vector& axisPoint1, const RS_Vector& axisPoint2) { |
| | m_toleranceData.m_insertionPoint.mirror(axisPoint1, axisPoint2); |
| | update(); |
| | } |
| |
|
| | void LC_Tolerance::moveRef(const RS_Vector& ref, const RS_Vector& offset) { |
| | if (ref.distanceTo(m_toleranceData.m_insertionPoint)<1.0e-4) { |
| | m_toleranceData.m_insertionPoint += offset; |
| | update(); |
| | } |
| | } |
| |
|
| | std::ostream& operator<<(std::ostream& os, const LC_ToleranceData& td) { |
| | os << "(" |
| | << td.m_insertionPoint << ',' |
| | << td.m_directionVector << ',' |
| | << td.m_dimStyleName.toLatin1().data() << ',' |
| | << td.m_textCode.toLatin1().data() << ")"; |
| | return os; |
| | } |
| |
|
| | std::ostream& operator<<(std::ostream& os, const LC_Tolerance& d) { |
| | os << " Tolerance: " << d.getData() << "\n"; |
| | return os; |
| | } |
| |
|
| | void LC_Tolerance::doUpdate() { |
| |
|
| | } |
| |
|
| | QList<QStringList> LC_Tolerance::getFields() const { |
| | |
| | QList<QStringList> ret; |
| |
|
| | QStringList lines = m_toleranceData.m_textCode.split("^J"); |
| | for (int k=0; k<lines.length(); k++) { |
| | QString line = lines[k]; |
| | |
| |
|
| | QStringList lineFields = line.split("%%v"); |
| | ret.append(lineFields); |
| | } |
| |
|
| | return ret; |
| | } |
| |
|
| | double LC_Tolerance::getTextHeight() { |
| | return getGraphicVariable("$DIMTXT", 2.5, 40); |
| | } |
| |
|
| | |
| | double LC_Tolerance::getGraphicVariable(const QString& key, double defMM, int code) { |
| | double v = getGraphicVariableDouble(key, RS_MINDOUBLE); |
| | if (v <= RS_MINDOUBLE) { |
| | addGraphicVariable(key, RS_Units::convert(defMM, RS2::Millimeter, getGraphicUnit()), code); |
| | v = getGraphicVariableDouble(key, 1.0); |
| | } |
| | return v; |
| | } |
| |
|
| | double LC_Tolerance::getDimtxt(bool scale) { |
| | double v = 2.5; |
| |
|
| | |
| | if (dimtxt>0.0) { |
| | v = dimtxt; |
| | } |
| | else { |
| | v = getTextHeight(); |
| | } |
| |
|
| | if (scale) { |
| | v *= getDimscale(); |
| | } |
| |
|
| | return v; |
| | } |
| | void LC_Tolerance::setDimtxt(double f) { |
| | dimtxt = f; |
| | update(); |
| | } |
| |
|
| | double LC_Tolerance::getGeneralScale() { |
| | return getGraphicVariable("$DIMSCALE", 1.0, 40); |
| | } |
| |
|
| | double LC_Tolerance::getDimscale() { |
| | |
| | if (dimscale>0.0) { |
| | return dimscale; |
| | } |
| |
|
| | double v = getGeneralScale(); |
| | return v; |
| | } |
| |
|
| | QString LC_Tolerance::getTextStyle() { |
| | return getGraphicVariableString("$DIMTXSTY", "standard"); |
| | } |
| |
|
| | RS_Color LC_Tolerance::getTextColor() { |
| | return RS_FilterDXFRW::numberToColor(getGraphicVariableInt("$DIMCLRT", 0)); |
| | } |
| |
|
| | RS_Pen LC_Tolerance::getPenForText() { |
| | RS_Pen result(getTextColor(), RS2::WidthByBlock, RS2::SolidLine); |
| | return result; |
| | } |
| |
|
| | RS_Color LC_Tolerance::getDimensionLineColor() { |
| | return RS_FilterDXFRW::numberToColor(getGraphicVariableInt("$DIMCLRD", 0)); |
| | } |
| |
|
| | RS_Pen LC_Tolerance::getPenForLines() { |
| | |
| | RS_Pen result(getDimensionLineColor(), RS2::WidthByBlock, RS2::SolidLine); |
| | return result; |
| | } |
| |
|
| | void LC_Tolerance::doUpdateDim(){ |
| | QList<QList<double>> divisionPoints; |
| |
|
| | createTextLabels(divisionPoints); |
| | createFrameLines(divisionPoints); |
| |
|
| | divisionPoints.clear(); |
| | } |
| |
|
| |
|
| | void LC_Tolerance::createTextLabels(QList<QList<double>> &divisions) { |
| | double dimtxt = getDimtxt(); |
| | |
| |
|
| | QList<QStringList> fields = getFields(); |
| | joinFirstField = false; |
| |
|
| | |
| | if (fields.length()>1 && fields[0].length()>0 && fields[1].length()>0) { |
| | QString field1 = fields[0][0]; |
| | QString field2 = fields[1][0]; |
| | QRegularExpression reg = QRegularExpression("\\\\F[gG][dD][tT];", QRegularExpression::CaseInsensitiveOption); |
| | field1.replace(reg, "\\Fgdt;"); |
| | field2.replace(reg, "\\Fgdt;"); |
| | if (!field1.isEmpty()) { |
| | joinFirstField = (field1==field2); |
| | } |
| | } |
| |
|
| | double cursorY = 0; |
| |
|
| | double angle = m_toleranceData.m_directionVector.angle(); |
| | double textAngle = 0.0; |
| |
|
| | RS_Pen textPen = getPenForText(); |
| |
|
| | for (int k=0; k<fields.length(); k++) { |
| | QStringList fieldsOfLine = fields[k]; |
| | double cursorX = dimtxt/2.0; |
| |
|
| | QList<double> row; |
| | row << 0.0; |
| | divisions.append(row); |
| |
|
| | |
| | for (int i=0; i<fieldsOfLine.length(); i++) { |
| | QString field = fieldsOfLine[i]; |
| | LC_ERR << "field:" << field; |
| | if (field.isEmpty()) { |
| | continue; |
| | } |
| |
|
| | RS_MTextData textData = RS_MTextData({cursorX, cursorY}, |
| | dimtxt, 30.0, |
| | RS_MTextData::VAMiddle, |
| | RS_MTextData::HALeft, |
| | RS_MTextData::LeftToRight, |
| | RS_MTextData::Exact, |
| | 1.0, |
| | field, |
| | getTextStyle(), |
| | textAngle); |
| |
|
| | auto text = new RS_MText(this, textData); |
| | addDimComponentEntity(text, textPen); |
| |
|
| | |
| | if (k==0 && i==0 && joinFirstField) { |
| | text->move({0, -dimtxt}); |
| | } |
| |
|
| | cursorX += text->getUsedTextWidth(); |
| | cursorX += dimtxt; |
| | divisions.last().push_back(cursorX - dimtxt/2); |
| |
|
| | if (k==1 && i==0 && joinFirstField) { |
| | |
| | continue; |
| | } |
| | text->rotate({0,0},angle); |
| | text->move(m_toleranceData.m_insertionPoint); |
| |
|
| | } |
| |
|
| | if (!divisions.isEmpty() && divisions.last().length() ==1) { |
| | |
| | divisions.removeLast(); |
| | } |
| | else { |
| | cursorY -= dimtxt * 2; |
| | } |
| | } |
| | } |
| | void LC_Tolerance::createFrameLines(QList<QList<double>> &divisions) { |
| | QList<RS_Line> ret; |
| |
|
| | double dimtxt = getDimtxt(); |
| | double offsetY = 0.0; |
| |
|
| | RS_Vector location = m_toleranceData.m_insertionPoint; |
| | double angle = m_toleranceData.m_directionVector.angle(); |
| |
|
| | RS_Pen linesPen = getPenForLines(); |
| |
|
| | for (int i = 0; i < divisions.length(); i++) { |
| | |
| |
|
| | auto current = divisions[i]; |
| | qsizetype currentLength = current.length(); |
| | |
| | if (currentLength > 1) { |
| | for (int k = 0; k < currentLength; k++) { |
| | double division = current.at(k); |
| | RS_Line* line = addDimComponentLine({division, -dimtxt + offsetY}, {division, dimtxt + offsetY}, linesPen); |
| | line->rotate(angle); |
| | line->move(location); |
| | } |
| |
|
| | { |
| | |
| | double startX = current.first(); |
| | if (joinFirstField && i == 1 && currentLength > 1) { |
| | startX = current[1]; |
| | } |
| | RS_Line* line = addDimComponentLine({startX, dimtxt + offsetY}, {current.last(), dimtxt + offsetY}, linesPen); |
| | line->rotate(angle); |
| | line->move(location); |
| | } |
| |
|
| | { |
| | |
| | double startX = current.first(); |
| | if (joinFirstField && i == 0 && currentLength > 1) { |
| | startX = current[1]; |
| | } |
| | RS_Line* line = addDimComponentLine({startX, -dimtxt + offsetY}, {current.last(), -dimtxt + offsetY}, linesPen); |
| | line->rotate(angle); |
| | line->move(location); |
| | } |
| | } |
| |
|
| | if (!current.isEmpty()) { |
| | offsetY -= dimtxt * 2; |
| | } |
| | } |
| | } |
| |
|
| | RS_Line* LC_Tolerance::addDimComponentLine(RS_Vector start, RS_Vector end, const RS_Pen &pen) { |
| | auto line = new RS_Line(this, {start, end}); |
| | line->setPen(pen); |
| | line->setLayer(nullptr); |
| | addEntity(line); |
| | return line; |
| | } |
| |
|
| | void LC_Tolerance::addDimComponentEntity(RS_Entity* en, const RS_Pen &pen) { |
| | en->setPen(pen); |
| | en->setLayer(nullptr); |
| | addEntity(en); |
| | } |
| |
|