3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 05/28/2010 Added this text. :-)
17 #include "dimension.h"
26 Dimension::Dimension(EntityContainer * parent, const DimensionData & d):
27 EntityContainer(parent), data(d)
31 /*virtual*/ Dimension::~Dimension()
35 /** @return Copy of data that defines the dimension. */
36 DimensionData Dimension::getData() const
41 Vector Dimension::getNearestRef(const Vector & coord, double * dist)
43 return Entity::getNearestRef(coord, dist);
46 Vector Dimension::getNearestSelectedRef(const Vector & coord, double * dist)
48 return Entity::getNearestSelectedRef(coord, dist);
52 * @return Dimension text. Either a text the user defined or
55 * @param resolve false: return plain value. true: return measured
56 * label if appropriate.
57 * @see getMeasuredLabel
59 QString Dimension::getLabel(bool resolve)
66 // One space suppresses the text:
69 // No text prints actual measurement:
70 else if (data.text == "")
71 ret = getMeasuredLabel();
72 // Others print the text (<> is replaced by the measurement)
76 ret = ret.replace(QString("<>"), getMeasuredLabel());
83 * Sets a new text for the label.
85 void Dimension::setLabel(const QString & l)
91 * Creates a dimensioning line (line with one, two or no arrows and a text).
93 * @param forceAutoText Automatically reposition the text label.
95 void Dimension::updateCreateDimensionLine(const Vector & p1,
96 const Vector & p2, bool arrow1, bool arrow2, bool forceAutoText)
99 printf("Dimension::updateCreateDimensionLine()...\n");
101 // text height (DIMTXT)
102 double dimtxt = getTextHeight();
103 // text distance to line (DIMGAP)
104 double dimgap = getDimensionLineGap();
105 // length of dimension line:
106 double distance = p1.distanceTo(p2);
107 // do we have to put the arrows outside of the line?
108 bool outsideArrows = (distance < getArrowSize() * 2.5);
110 double arrowAngle1, arrowAngle2;
112 // Create dimension line:
113 Line * dimensionLine = new Line(this, LineData(p1, p2));
114 dimensionLine->setPen(Pen(RS2::FlagInvalid));
115 dimensionLine->setLayer(NULL);
116 addEntity(dimensionLine);
120 arrowAngle1 = dimensionLine->getAngle2();
121 arrowAngle2 = dimensionLine->getAngle1();
125 arrowAngle1 = dimensionLine->getAngle1();
126 arrowAngle2 = dimensionLine->getAngle2();
128 // extend dimension line outside arrows
130 dir.setPolar(getArrowSize() * 2, arrowAngle2);
131 dimensionLine->setStartpoint(p1 + dir);
132 dimensionLine->setEndpoint(p2 - dir);
142 arrow = new Solid(this, sd);
143 arrow->shapeArrow(p1, arrowAngle1, getArrowSize());
144 arrow->setPen(Pen(RS2::FlagInvalid));
145 arrow->setLayer(NULL);
152 arrow = new Solid(this, sd);
153 arrow->shapeArrow(p2, arrowAngle2, getArrowSize());
154 arrow->setPen(Pen(RS2::FlagInvalid));
155 arrow->setLayer(NULL);
163 double dimAngle1 = dimensionLine->getAngle1();
165 bool corrected = false;
166 textAngle = Math::makeAngleReadable(dimAngle1, true, &corrected);
168 if (data.middleOfText.valid && !forceAutoText)
170 textPos = data.middleOfText;
174 textPos = dimensionLine->getMiddlepoint();
177 // rotate text so it's readable from the bottom or right (ISO)
180 distV.setPolar(dimgap + dimtxt / 2.0, dimAngle1 - M_PI / 2.0);
182 distV.setPolar(dimgap + dimtxt / 2.0, dimAngle1 + M_PI / 2.0);
184 // move text away from dimension line:
186 //// the next update should still be able to adjust this
187 //// auto text position. leave it invalid
188 data.middleOfText = textPos;
191 textData = TextData(textPos, dimtxt, 30.0, RS2::VAlignMiddle, RS2::HAlignCenter,
192 RS2::LeftToRight, RS2::Exact, 1.0, getLabel(), "standard", textAngle);
194 printf("--> %s\n", getLabel().toAscii().data());
197 Text * text = new Text(this, textData);
199 // move text to the side:
202 if (text->getUsedTextWidth() > distance)
204 distH.setPolar(text->getUsedTextWidth() / 2.0 + distance / 2.0 + dimgap, textAngle);
208 text->setPen(Pen(RS2::FlagInvalid));
209 text->setLayer(NULL);
213 Vector Dimension::getDefinitionPoint()
215 return data.definitionPoint;
218 Vector Dimension::getMiddleOfText()
220 return data.middleOfText;
223 RS2::VAlign Dimension::getVAlign()
228 RS2::HAlign Dimension::getHAlign()
233 RS2::TextLineSpacingStyle Dimension::getLineSpacingStyle()
235 return data.lineSpacingStyle;
238 double Dimension::getLineSpacingFactor()
240 return data.lineSpacingFactor;
243 QString Dimension::getText()
248 QString Dimension::getStyle()
253 double Dimension::getAngle()
259 * @return arrow size in drawing units.
261 double Dimension::getArrowSize()
263 return getGraphicVariable("$DIMASZ", 2.5, 40);
267 * @return extension line overlength in drawing units.
269 double Dimension::getExtensionLineExtension()
271 return getGraphicVariable("$DIMEXE", 1.25, 40);
275 * @return extension line offset from entities in drawing units.
277 double Dimension::getExtensionLineOffset()
279 return getGraphicVariable("$DIMEXO", 0.625, 40);
283 * @return extension line gap to text in drawing units.
285 double Dimension::getDimensionLineGap()
287 return getGraphicVariable("$DIMGAP", 0.625, 40);
291 * @return Dimension lables text height.
293 double Dimension::getTextHeight()
295 return getGraphicVariable("$DIMTXT", 2.5, 40);
299 * @return the given graphic variable or the default value given in mm
300 * converted to the graphic unit.
301 * If the variable is not found it is added with the given default
302 * value converted to the local unit.
304 double Dimension::getGraphicVariable(const QString & key, double defMM, int code)
306 double v = getGraphicVariableDouble(key, RS_MINDOUBLE);
308 if (v <= RS_MINDOUBLE)
310 addGraphicVariable(key, Units::convert(defMM, RS2::Millimeter, getGraphicUnit()),
312 v = getGraphicVariableDouble(key, 1.0);
318 /*virtual*/ double Dimension::getLength()
323 void Dimension::move(Vector offset)
325 data.definitionPoint.move(offset);
326 data.middleOfText.move(offset);
329 void Dimension::rotate(Vector center, double angle)
331 data.definitionPoint.rotate(center, angle);
332 data.middleOfText.rotate(center, angle);
333 data.angle = Math::correctAngle(data.angle+angle);
336 void Dimension::scale(Vector center, Vector factor)
338 data.definitionPoint.scale(center, factor);
339 data.middleOfText.scale(center, factor);
342 void Dimension::mirror(Vector axisPoint1, Vector axisPoint2)
344 data.definitionPoint.mirror(axisPoint1, axisPoint2);
345 data.middleOfText.mirror(axisPoint1, axisPoint2);