]> Shamusworld >> Repos - architektonas/blob - src/base/rs_dimlinear.cpp
Fixed problem with dimensions not showing up.
[architektonas] / src / base / rs_dimlinear.cpp
1 // rs_dimlinear.cpp
2 //
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
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -----------------------------------------------------------
12 // JLH  05/28/2010  Added this text. :-)
13 //
14
15 #include "rs_dimlinear.h"
16
17 #include "rs_constructionline.h"
18 #include "rs_text.h"
19 #include "rs_solid.h"
20 #include "drawing.h"
21 #include "rs_units.h"
22
23 /**
24  * Constructor.
25  *
26  * @para parent Parent Entity Container.
27  * @para d Common dimension geometrical data.
28  * @para ed Extended geometrical data for linear dimension.
29  */
30 RS_DimLinear::RS_DimLinear(RS_EntityContainer * parent, const RS_DimensionData & d,
31         const RS_DimLinearData & ed): RS_Dimension(parent, d), edata(ed)
32 {
33     calculateBorders();
34 }
35
36 /*virtual*/ RS_DimLinear::~RS_DimLinear()
37 {
38 }
39
40 /*virtual*/ RS_Entity * RS_DimLinear::clone()
41 {
42         RS_DimLinear * d = new RS_DimLinear(*this);
43 #warning "!!! Need to deal with setAutoDelete() Qt3->Qt4 !!!"
44 //      d->entities.setAutoDelete(entities.autoDelete());
45         d->initId();
46         d->detach();
47
48         return d;
49 }
50
51 /**     @return RS2::EntityDimLinear */
52 /*virtual*/ RS2::EntityType RS_DimLinear::rtti() const
53 {
54         return RS2::EntityDimLinear;
55 }
56
57 /**
58  * @return Copy of data that defines the linear dimension.
59  * @see getData()
60  */
61 RS_DimLinearData RS_DimLinear::getEData() const
62 {
63         return edata;
64 }
65
66 VectorSolutions RS_DimLinear::getRefPoints()
67 {
68         VectorSolutions ret(edata.extensionPoint1, edata.extensionPoint2,
69                 data.definitionPoint, data.middleOfText);
70
71         return ret;
72 }
73
74 /**
75  * @return Automatically created label for the default
76  * measurement of this dimension.
77  */
78 QString RS_DimLinear::getMeasuredLabel()
79 {
80         // direction of dimension line
81         Vector dirDim;
82         dirDim.setPolar(100.0, edata.angle);
83
84         // construction line for dimension line
85         RS_ConstructionLine dimLine(NULL, RS_ConstructionLineData(data.definitionPoint,
86                 data.definitionPoint + dirDim));
87
88         Vector dimP1 = dimLine.getNearestPointOnEntity(edata.extensionPoint1);
89         Vector dimP2 = dimLine.getNearestPointOnEntity(edata.extensionPoint2);
90
91         // Definitive dimension line:
92         double dist = dimP1.distanceTo(dimP2);
93
94         Drawing * graphic = getGraphic();
95
96         QString ret;
97
98         if (graphic)
99                 ret = RS_Units::formatLinear(dist, graphic->getUnit(),
100                         graphic->getLinearFormat(), graphic->getLinearPrecision());
101         else
102                 ret = QString("%1").arg(dist);
103 //It's properly creating the label...
104 //printf("RS_DimLinear::getMeasuredLabel: label=\"%s\"\n", ret.toAscii().data());
105
106         return ret;
107 }
108
109 bool RS_DimLinear::hasEndpointsWithinWindow(Vector v1, Vector v2)
110 {
111         return (edata.extensionPoint1.isInWindow(v1, v2)
112                 || edata.extensionPoint2.isInWindow(v1, v2));
113 }
114
115 /**
116  * Updates the sub entities of this dimension. Called when the
117  * text or the position, alignment, .. changes.
118  *
119  * @param autoText Automatically reposition the text label
120  */
121 void RS_DimLinear::update(bool autoText)
122 {
123         RS_DEBUG->print("RS_DimLinear::update");
124
125         clear();
126
127         if (isUndone())
128                 return;
129
130         // distance from entities (DIMEXO)
131         double dimexo = getExtensionLineOffset();
132         // extension line extension (DIMEXE)
133         double dimexe = getExtensionLineExtension();
134
135         RS_LineData ld;
136         double extAngle = edata.angle + (M_PI / 2.0);
137
138         // direction of dimension line
139         Vector dirDim;
140         dirDim.setPolar(100.0, edata.angle);
141         // direction of extension lines
142         Vector dirExt;
143         dirExt.setPolar(100.0, extAngle);
144
145         // construction line for dimension line
146         RS_ConstructionLine dimLine(NULL, RS_ConstructionLineData(data.definitionPoint,
147                 data.definitionPoint + dirDim));
148
149         Vector dimP1 = dimLine.getNearestPointOnEntity(edata.extensionPoint1);
150         Vector dimP2 = dimLine.getNearestPointOnEntity(edata.extensionPoint2);
151
152         // Definitive dimension line:
153         updateCreateDimensionLine(dimP1, dimP2, true, true, autoText);
154         /*
155         ld = RS_LineData(data.definitionPoint, dimP1);
156         RS_Line* dimensionLine = new RS_Line(this, ld);
157                 addEntity(dimensionLine);
158         */
159         Vector vDimexo1, vDimexe1, vDimexo2, vDimexe2;
160         vDimexe1.setPolar(dimexe, edata.extensionPoint1.angleTo(dimP1));
161         vDimexo1.setPolar(dimexo, edata.extensionPoint1.angleTo(dimP1));
162
163         vDimexe2.setPolar(dimexe, edata.extensionPoint2.angleTo(dimP2));
164         vDimexo2.setPolar(dimexo, edata.extensionPoint2.angleTo(dimP2));
165
166         if ((edata.extensionPoint1 - dimP1).magnitude() < 1e-6)
167         {
168                 vDimexe1.setPolar(dimexe, data.definitionPoint.angleTo(dimP1) - M_PI / 2.0);
169                 vDimexo1.setPolar(dimexo, data.definitionPoint.angleTo(dimP1) - M_PI / 2.0);
170         }
171
172         if ((edata.extensionPoint2 - dimP2).magnitude() < 1e-6)
173         {
174                 vDimexe2.setPolar(dimexe, data.definitionPoint.angleTo(dimP2) - M_PI / 2.0);
175                 vDimexo2.setPolar(dimexo, data.definitionPoint.angleTo(dimP2) - M_PI / 2.0);
176         }
177
178         // extension lines:
179         ld = RS_LineData(edata.extensionPoint1 + vDimexo1, dimP1 + vDimexe1);
180         RS_Line * line = new RS_Line(this, ld);
181         line->setPen(RS_Pen(RS2::FlagInvalid));
182         line->setLayer(NULL);
183         addEntity(line);
184
185         ld = RS_LineData(edata.extensionPoint2 + vDimexo2, dimP2 + vDimexe2);
186         //data.definitionPoint+vDimexe2);
187         line = new RS_Line(this, ld);
188         line->setPen(RS_Pen(RS2::FlagInvalid));
189         line->setLayer(NULL);
190         addEntity(line);
191
192         calculateBorders();
193 }
194
195 Vector RS_DimLinear::getExtensionPoint1()
196 {
197         return edata.extensionPoint1;
198 }
199
200 Vector RS_DimLinear::getExtensionPoint2()
201 {
202         return edata.extensionPoint2;
203 }
204
205 double RS_DimLinear::getAngle()
206 {
207         return edata.angle;
208 }
209
210 void RS_DimLinear::setAngle(double a)
211 {
212         edata.angle = RS_Math::correctAngle(a);
213 }
214
215 double RS_DimLinear::getOblique()
216 {
217         return edata.oblique;
218 }
219
220 void RS_DimLinear::move(Vector offset)
221 {
222         RS_Dimension::move(offset);
223
224         edata.extensionPoint1.move(offset);
225         edata.extensionPoint2.move(offset);
226         update();
227 }
228
229 void RS_DimLinear::rotate(Vector center, double angle)
230 {
231         RS_Dimension::rotate(center, angle);
232
233         edata.extensionPoint1.rotate(center, angle);
234         edata.extensionPoint2.rotate(center, angle);
235         edata.angle = RS_Math::correctAngle(edata.angle+angle);
236         update();
237 }
238
239 void RS_DimLinear::scale(Vector center, Vector factor)
240 {
241         RS_Dimension::scale(center, factor);
242
243         edata.extensionPoint1.scale(center, factor);
244         edata.extensionPoint2.scale(center, factor);
245         update();
246 }
247
248 void RS_DimLinear::mirror(Vector axisPoint1, Vector axisPoint2)
249 {
250         RS_Dimension::mirror(axisPoint1, axisPoint2);
251
252         edata.extensionPoint1.mirror(axisPoint1, axisPoint2);
253         edata.extensionPoint2.mirror(axisPoint1, axisPoint2);
254
255         Vector vec;
256         vec.setPolar(1.0, edata.angle);
257         vec.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
258         edata.angle = vec.angle();
259
260         update();
261 }
262
263 void RS_DimLinear::stretch(Vector firstCorner, Vector secondCorner, Vector offset)
264 {
265         //e->calculateBorders();
266         if (getMin().isInWindow(firstCorner, secondCorner)
267                 && getMax().isInWindow(firstCorner, secondCorner))
268         {
269                 move(offset);
270         }
271         else
272         {
273                 //Vector v = data.definitionPoint - edata.extensionPoint2;
274                 //double len = edata.extensionPoint2.distanceTo(data.definitionPoint);
275                 //double ang1 = edata.extensionPoint1.angleTo(edata.extensionPoint2)
276                 //              + M_PI/2;
277
278                 if (edata.extensionPoint1.isInWindow(firstCorner, secondCorner))
279                         edata.extensionPoint1.move(offset);
280
281                 if (edata.extensionPoint2.isInWindow(firstCorner, secondCorner))
282                         edata.extensionPoint2.move(offset);
283
284                 /*
285                 double ang2 = edata.extensionPoint1.angleTo(edata.extensionPoint2)
286                                                 + M_PI/2;
287
288                 double diff = RS_Math::getAngleDifference(ang1, ang2);
289                 if (diff>M_PI) {
290                         diff-=2*M_PI;
291                 }
292
293                 if (fabs(diff)>M_PI/2) {
294                         ang2 = RS_Math::correctAngle(ang2+M_PI);
295                 }
296
297                 Vector v;
298                 v.setPolar(len, ang2);
299                 data.definitionPoint = edata.extensionPoint2 + v;
300                 */
301         }
302
303         update(true);
304 }
305
306 void RS_DimLinear::moveRef(const Vector & ref, const Vector & offset)
307 {
308         if (ref.distanceTo(data.definitionPoint) < 1.0e-4)
309         {
310                 data.definitionPoint += offset;
311                 update(true);
312         }
313         else if (ref.distanceTo(data.middleOfText) < 1.0e-4)
314         {
315                 data.middleOfText += offset;
316                 update(false);
317         }
318         else if (ref.distanceTo(edata.extensionPoint1) < 1.0e-4)
319         {
320                 edata.extensionPoint1 += offset;
321                 update(true);
322         }
323         else if (ref.distanceTo(edata.extensionPoint2) < 1.0e-4)
324         {
325                 edata.extensionPoint2 += offset;
326                 update(true);
327         }
328 }
329
330 /**
331  * Dumps the point's data to stdout.
332  */
333 std::ostream & operator<<(std::ostream & os, const RS_DimLinear & d)
334 {
335     os << " DimLinear: " << d.getData() << "\n" << d.getEData() << "\n";
336     return os;
337 }