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 // (C) 2010 Underground Software
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/28/2010 Added this text. :-)
15 #include "rs_dimension.h"
24 RS_Dimension::RS_Dimension(RS_EntityContainer * parent, const RS_DimensionData & d):
25 RS_EntityContainer(parent), data(d)
29 /*virtual*/ RS_Dimension::~RS_Dimension()
33 /** @return Copy of data that defines the dimension. */
34 RS_DimensionData RS_Dimension::getData() const
39 Vector RS_Dimension::getNearestRef(const Vector & coord, double * dist)
41 return RS_Entity::getNearestRef(coord, dist);
44 Vector RS_Dimension::getNearestSelectedRef(const Vector & coord, double * dist)
46 return RS_Entity::getNearestSelectedRef(coord, dist);
50 * @return Dimension text. Either a text the user defined or
53 * @param resolve false: return plain value. true: return measured
54 * label if appropriate.
55 * @see getMeasuredLabel
57 QString RS_Dimension::getLabel(bool resolve)
65 // One space suppresses the text:
70 // No text prints actual measurement:
71 else if (data.text=="") {
72 ret = getMeasuredLabel();
75 // Others print the text (<> is replaced by the measurement)
78 ret = ret.replace(QString("<>"), getMeasuredLabel());
85 * Sets a new text for the label.
87 void RS_Dimension::setLabel(const QString & l)
93 * Creates a dimensioning line (line with one, two or no arrows and a text).
95 * @param forceAutoText Automatically reposition the text label.
97 void RS_Dimension::updateCreateDimensionLine(const Vector& p1,
98 const Vector& p2, bool arrow1, bool arrow2, bool forceAutoText)
100 // text height (DIMTXT)
101 double dimtxt = getTextHeight();
102 // text distance to line (DIMGAP)
103 double dimgap = getDimensionLineGap();
105 // length of dimension line:
106 double distance = p1.distanceTo(p2);
108 // do we have to put the arrows outside of the line?
109 bool outsideArrows = (distance<getArrowSize()*2.5);
112 double arrowAngle1, arrowAngle2;
114 // Create dimension line:
115 RS_Line* dimensionLine = new RS_Line(this, RS_LineData(p1, p2));
116 dimensionLine->setPen(RS_Pen(RS2::FlagInvalid));
117 dimensionLine->setLayer(NULL);
118 addEntity(dimensionLine);
120 if (outsideArrows==false) {
121 arrowAngle1 = dimensionLine->getAngle2();
122 arrowAngle2 = dimensionLine->getAngle1();
124 arrowAngle1 = dimensionLine->getAngle1();
125 arrowAngle2 = dimensionLine->getAngle2();
127 // extend dimension line outside arrows
129 dir.setPolar(getArrowSize()*2, arrowAngle2);
130 dimensionLine->setStartpoint(p1 + dir);
131 dimensionLine->setEndpoint(p2 - dir);
140 arrow = new RS_Solid(this, sd);
141 arrow->shapeArrow(p1,
144 arrow->setPen(RS_Pen(RS2::FlagInvalid));
145 arrow->setLayer(NULL);
151 arrow = new RS_Solid(this, sd);
152 arrow->shapeArrow(p2,
155 arrow->setPen(RS_Pen(RS2::FlagInvalid));
156 arrow->setLayer(NULL);
161 RS_TextData textData;
164 double dimAngle1 = dimensionLine->getAngle1();
166 bool corrected=false;
167 textAngle = RS_Math::makeAngleReadable(dimAngle1, true, &corrected);
169 if (data.middleOfText.valid && !forceAutoText) {
170 textPos = data.middleOfText;
172 textPos = dimensionLine->getMiddlepoint();
176 // rotate text so it's readable from the bottom or right (ISO)
179 distV.setPolar(dimgap + dimtxt/2.0, dimAngle1-M_PI/2.0);
181 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 = RS_TextData(textPos,
202 RS_Text* text = new RS_Text(this, textData);
204 // move text to the side:
206 if (text->getUsedTextWidth()>distance) {
207 distH.setPolar(text->getUsedTextWidth()/2.0
208 +distance/2.0+dimgap, textAngle);
211 text->setPen(RS_Pen(RS2::FlagInvalid));
212 text->setLayer(NULL);
216 Vector RS_Dimension::getDefinitionPoint()
218 return data.definitionPoint;
221 Vector RS_Dimension::getMiddleOfText()
223 return data.middleOfText;
226 RS2::VAlign RS_Dimension::getVAlign()
231 RS2::HAlign RS_Dimension::getHAlign()
236 RS2::TextLineSpacingStyle RS_Dimension::getLineSpacingStyle()
238 return data.lineSpacingStyle;
241 double RS_Dimension::getLineSpacingFactor()
243 return data.lineSpacingFactor;
246 QString RS_Dimension::getText()
251 QString RS_Dimension::getStyle()
256 double RS_Dimension::getAngle()
262 * @return arrow size in drawing units.
264 double RS_Dimension::getArrowSize()
266 return getGraphicVariable("$DIMASZ", 2.5, 40);
270 * @return extension line overlength in drawing units.
272 double RS_Dimension::getExtensionLineExtension()
274 return getGraphicVariable("$DIMEXE", 1.25, 40);
278 * @return extension line offset from entities in drawing units.
280 double RS_Dimension::getExtensionLineOffset()
282 return getGraphicVariable("$DIMEXO", 0.625, 40);
286 * @return extension line gap to text in drawing units.
288 double RS_Dimension::getDimensionLineGap()
290 return getGraphicVariable("$DIMGAP", 0.625, 40);
294 * @return Dimension lables text height.
296 double RS_Dimension::getTextHeight()
298 return getGraphicVariable("$DIMTXT", 2.5, 40);
302 * @return the given graphic variable or the default value given in mm
303 * converted to the graphic unit.
304 * If the variable is not found it is added with the given default
305 * value converted to the local unit.
307 double RS_Dimension::getGraphicVariable(const QString & key, double defMM, int code)
309 double v = getGraphicVariableDouble(key, RS_MINDOUBLE);
311 if (v <= RS_MINDOUBLE)
313 addGraphicVariable(key, RS_Units::convert(defMM, RS2::Millimeter, getGraphicUnit()),
315 v = getGraphicVariableDouble(key, 1.0);
321 /*virtual*/ double RS_Dimension::getLength()
326 void RS_Dimension::move(Vector offset)
328 data.definitionPoint.move(offset);
329 data.middleOfText.move(offset);
332 void RS_Dimension::rotate(Vector center, double angle)
334 data.definitionPoint.rotate(center, angle);
335 data.middleOfText.rotate(center, angle);
336 data.angle = RS_Math::correctAngle(data.angle+angle);
339 void RS_Dimension::scale(Vector center, Vector factor)
341 data.definitionPoint.scale(center, factor);
342 data.middleOfText.scale(center, factor);
345 void RS_Dimension::mirror(Vector axisPoint1, Vector axisPoint2)
347 data.definitionPoint.mirror(axisPoint1, axisPoint2);
348 data.middleOfText.mirror(axisPoint1, axisPoint2);