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