| File: | librecad/src/actions/drawing/draw/dimensions/lc_actiondrawdimbaseline.cpp |
| Warning: | line 299, column 13 Value stored to 'dimAngle' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /******************************************************************************* |
| 2 | * |
| 3 | This file is part of the LibreCAD project, a 2D CAD program |
| 4 | |
| 5 | Copyright (C) 2024 LibreCAD.org |
| 6 | Copyright (C) 2024 sand1024 |
| 7 | |
| 8 | This program is free software; you can redistribute it and/or |
| 9 | modify it under the terms of the GNU General Public License |
| 10 | as published by the Free Software Foundation; either version 2 |
| 11 | of the License, or (at your option) any later version. |
| 12 | |
| 13 | This program is distributed in the hope that it will be useful, |
| 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | GNU General Public License for more details. |
| 17 | |
| 18 | You should have received a copy of the GNU General Public License |
| 19 | along with this program; if not, write to the Free Software |
| 20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 21 | ******************************************************************************/ |
| 22 | |
| 23 | #include "lc_actiondrawdimbaseline.h" |
| 24 | |
| 25 | #include "qg_dimoptions.h" |
| 26 | #include "rs_constructionline.h" |
| 27 | #include "rs_dimaligned.h" |
| 28 | #include "rs_dimlinear.h" |
| 29 | #include "rs_polyline.h" |
| 30 | #include "rs_preview.h" |
| 31 | |
| 32 | |
| 33 | // some functions are duplicated with DimLiner action, however, that's intentional as later we can support angular dimensions in additional to linear ones |
| 34 | LC_ActionDrawDimBaseline::LC_ActionDrawDimBaseline(LC_ActionContext *actionContext, const RS2::ActionType type) |
| 35 | :LC_ActionDimLinearBase(type == RS2::ActionDimBaseline? "Draw Dim Baseline": "Draw Dim Continue", actionContext, RS2::EntityUnknown, type), |
| 36 | m_edata(std::make_unique<RS_DimLinearData>(RS_Vector(0., 0.), RS_Vector(0., 0.), 0, 0.)){ |
| 37 | } |
| 38 | |
| 39 | namespace { |
| 40 | //list of dimensions supported by current action - linear, aligned |
| 41 | // fixme - sand - add support for angular dimensions |
| 42 | // fixme - sand - add support of copying style of original dimension, |
| 43 | // fixme - sand - add support for distance for baseline obtained from the style |
| 44 | const auto DIM_ENTITY_TYPES = EntityTypeList{RS2::EntityDimLinear, RS2::EntityDimAligned}; |
| 45 | } |
| 46 | |
| 47 | void LC_ActionDrawDimBaseline::reset(){ |
| 48 | RS_ActionDimension::reset(); |
| 49 | const double oldAngle = m_edata->angle; // keep selected angle |
| 50 | *m_edata = RS_DimLinearData({}, {}, oldAngle, 0.); |
| 51 | } |
| 52 | |
| 53 | void LC_ActionDrawDimBaseline::doInitWithContextEntity(RS_Entity* contextEntity, const RS_Vector& clickPos) { |
| 54 | const RS2::EntityType rtti = contextEntity->rtti(); |
| 55 | if (DIM_ENTITY_TYPES.contains(rtti)) { |
| 56 | pickOriginalEntity(contextEntity, clickPos); |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | RS_Entity* LC_ActionDrawDimBaseline::doTriggerCreateEntity() { |
| 61 | preparePreview(m_alternateDimDirection); |
| 62 | auto *dim = createDim(m_document); |
| 63 | dim->update(); |
| 64 | |
| 65 | const bool baseline = isBaseline(); |
| 66 | |
| 67 | if (baseline){ |
| 68 | moveRelativeZero(m_edata->extensionPoint1); |
| 69 | } |
| 70 | else{ |
| 71 | moveRelativeZero(m_edata->extensionPoint2); |
| 72 | } |
| 73 | |
| 74 | if (baseline) { |
| 75 | m_prevExtensionPointEnd = m_edata->extensionPoint2; |
| 76 | // test is just in case |
| 77 | const auto* dimLinear = dynamic_cast<RS_DimLinear*>(dim); |
| 78 | if (dimLinear != nullptr) { // fixme - sand - suspicious check , review |
| 79 | m_baseDefPoint = dimLinear->getDefinitionPoint(); |
| 80 | } |
| 81 | } |
| 82 | else{ |
| 83 | m_edata->extensionPoint1 = m_edata->extensionPoint2; |
| 84 | m_prevExtensionPointEnd = m_edata->extensionPoint1; // todo - check whether this is necessary. Potentially - for ordnance continued |
| 85 | } |
| 86 | m_baseDefPoint = m_dimensionData->definitionPoint; |
| 87 | return dim; |
| 88 | } |
| 89 | |
| 90 | RS_Entity *LC_ActionDrawDimBaseline::createDim(RS_EntityContainer* parent){ |
| 91 | auto *dim = new RS_DimLinear(parent, *m_dimensionData, *m_edata); |
| 92 | return dim; |
| 93 | } |
| 94 | |
| 95 | bool LC_ActionDrawDimBaseline::isBaseline() const { |
| 96 | return m_actionType == RS2::ActionDimBaseline; |
| 97 | } |
| 98 | |
| 99 | void LC_ActionDrawDimBaseline::onMouseMoveEvent(const int status, const LC_MouseEvent* e) { |
| 100 | RS_Vector mouse = e->snapPoint; // snap on entity? |
| 101 | switch (status){ |
| 102 | case SetExtPoint1: { |
| 103 | auto dimCandidate = catchEntity(mouse, DIM_ENTITY_TYPES, RS2::ResolveNone); |
| 104 | if (dimCandidate != nullptr) { |
| 105 | highlightHover(dimCandidate); |
| 106 | |
| 107 | RS_Vector extPoint1; |
| 108 | RS_Vector extPoint2; |
| 109 | RS_Vector dim1; |
| 110 | RS_Vector dim2; |
| 111 | |
| 112 | int rtti = dimCandidate->rtti(); |
| 113 | switch (rtti){ |
| 114 | case RS2::EntityDimLinear:{ |
| 115 | auto dimLinear = static_cast<RS_DimLinear *>(dimCandidate); |
| 116 | extPoint1 = dimLinear->getExtensionPoint1(); |
| 117 | extPoint2 = dimLinear->getExtensionPoint2(); |
| 118 | dimLinear->getDimPoints(dim1, dim2); |
| 119 | m_dimTypeToCreate = RS2::EntityDimLinear; // fixme - pick dimension styles from start entity!!! |
| 120 | break; |
| 121 | } |
| 122 | case RS2::EntityDimAligned:{ |
| 123 | auto dimAligned = static_cast<RS_DimAligned *>(dimCandidate); |
| 124 | extPoint1 = dimAligned->getExtensionPoint1(); |
| 125 | extPoint2 = dimAligned->getExtensionPoint2(); |
| 126 | dimAligned->getDimPoints(dim1, dim2); |
| 127 | m_dimTypeToCreate = RS2::EntityDimAligned; // fixme - pick dimension styles from start entity!!! |
| 128 | break; |
| 129 | } |
| 130 | default: |
| 131 | break; |
| 132 | } |
| 133 | // we define which dim point is closer to mouse - based on this, extension 1 or extension 2 point will be selected as start extension point |
| 134 | double dist1 = mouse.distanceTo(dim1); |
| 135 | double dist2 = mouse.distanceTo(dim2); |
| 136 | |
| 137 | bool dim1CloserToMouse = dist1 < dist2; |
| 138 | if (e->isControl){ |
| 139 | dim1CloserToMouse = !dim1CloserToMouse; |
| 140 | } |
| 141 | if (dim1CloserToMouse){ |
| 142 | previewRefSelectablePoint(extPoint1); |
| 143 | } |
| 144 | else { |
| 145 | previewRefSelectablePoint(extPoint2); |
| 146 | } |
| 147 | } |
| 148 | break; |
| 149 | } |
| 150 | case SetExtPoint2:{ |
| 151 | const RS_Vector &extPoint1 = getExtensionPoint1(); |
| 152 | if (extPoint1.valid){ |
| 153 | mouse = getSnapAngleAwarePoint(e, extPoint1, mouse, true); |
| 154 | |
| 155 | // make a projection for new def point |
| 156 | // vector in direction controlled by angle of dimension |
| 157 | const RS_Vector &dimVector = RS_Vector::polar(100.0, m_edata->angle); |
| 158 | // infinite line from extPoint1 to angle direction |
| 159 | RS_ConstructionLine dimLine(nullptr, RS_ConstructionLineData(extPoint1, extPoint1 + dimVector)); |
| 160 | // projection of mouse on infinite line |
| 161 | RS_Vector ext2Candidate = dimLine.getNearestPointOnEntity(mouse, false); |
| 162 | // projection of previous definition point on infinite line |
| 163 | RS_Vector originalDefPointProjection = dimLine.getNearestPointOnEntity(m_baseDefPoint, false); |
| 164 | // distance vector between projection of old definition point projection and mouse projections |
| 165 | RS_Vector defPointsDistance = m_baseDefPoint - originalDefPointProjection; |
| 166 | // coordinate of definition point on base dimension line |
| 167 | RS_Vector newDefPointInline = ext2Candidate + defPointsDistance; |
| 168 | RS_Vector newDefPoint; |
| 169 | |
| 170 | // complete calculation of new definition point for dimension |
| 171 | if (isBaseline()) { |
| 172 | // for base line, we need to offset definition point on infinite line that corresponds old dim line to specified distance |
| 173 | double dimAngle = m_dimDirectionAngle; // angle we use for offset vector - it's the same as angle from base dimension |
| 174 | if (e->isControl) { // swap direction of the offset, if needed, so we'll offset in opposite direction |
| 175 | dimAngle = M_PI3.14159265358979323846 + dimAngle; |
| 176 | } |
| 177 | double previewDistance = m_baselineDistance; |
| 178 | if (m_freeBaselineDistance){ |
| 179 | previewDistance = 16; // of it's better to use zero there? Just a placeholder for preview |
| 180 | } |
| 181 | // find new definition point for this dimension |
| 182 | newDefPoint = newDefPointInline + RS_Vector::polar(previewDistance, dimAngle); |
| 183 | } else { |
| 184 | // for continue mode, new definition point will be on the same line as previous definition point |
| 185 | newDefPoint = newDefPointInline; |
| 186 | } |
| 187 | |
| 188 | setExtensionPoint2(mouse); |
| 189 | m_dimensionData->definitionPoint = newDefPoint; |
| 190 | |
| 191 | if (m_previewShowsFullDimension) { |
| 192 | auto dim = static_cast<RS_DimLinear *>(createDim(m_preview.get())); |
| 193 | dim->update(); |
| 194 | previewEntity(dim); |
| 195 | } |
| 196 | |
| 197 | if (m_showRefEntitiesOnPreview) { |
| 198 | previewRefPoint(extPoint1); |
| 199 | previewRefSelectablePoint(newDefPoint); |
| 200 | previewRefLine(extPoint1, mouse); |
| 201 | previewRefPoint(newDefPoint); |
| 202 | } |
| 203 | else{ |
| 204 | previewLine(extPoint1, mouse); |
| 205 | } |
| 206 | } |
| 207 | break; |
| 208 | } |
| 209 | case SetDefPoint:{ |
| 210 | const RS_Vector &extPoint1 = getExtensionPoint1(); |
| 211 | const RS_Vector &extPoint2 = getExtensionPoint2(); |
| 212 | if (extPoint1.valid && extPoint2.valid){ |
| 213 | // less restrictive snap |
| 214 | mouse = getFreeSnapAwarePoint(e, mouse); |
| 215 | mouse = adjustByAdjacentDim(mouse, true, false); |
| 216 | |
| 217 | const RS_Vector &dimVector = RS_Vector::polar(100.0, m_dimDirectionAngle); |
| 218 | // infinite line in normal direction to dimension angle |
| 219 | RS_ConstructionLine dimLine(nullptr, RS_ConstructionLineData(extPoint1, extPoint1 + dimVector)); |
| 220 | |
| 221 | // projection of old definition point on infinite line |
| 222 | RS_Vector originalDefPointProjection = dimLine.getNearestPointOnEntity(m_baseDefPoint, false); |
| 223 | // projection of mouse on infinite line |
| 224 | RS_Vector newDefPointProjection = dimLine.getNearestPointOnEntity(mouse, false); |
| 225 | |
| 226 | // distance between projections of old definition point and new one |
| 227 | m_currentDistance = originalDefPointProjection.distanceTo(newDefPointProjection); |
| 228 | updateOptionsUI(QG_DimOptions::UI_UPDATE_BASELINE_DISTANCE); |
| 229 | |
| 230 | m_dimensionData->definitionPoint = mouse; |
| 231 | preparePreview(false); |
| 232 | previewRefSelectablePoint(m_dimensionData->definitionPoint); |
| 233 | previewRefPoint(extPoint1); |
| 234 | previewRefPoint(extPoint2); |
| 235 | RS_Entity* dim = createDim(m_preview.get()); |
| 236 | previewEntity(dim); |
| 237 | dim->update(); |
| 238 | break; |
| 239 | } |
| 240 | break; |
| 241 | } |
| 242 | default: |
| 243 | break; |
| 244 | |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | void LC_ActionDrawDimBaseline::onMouseLeftButtonRelease(const int status, const LC_MouseEvent* e) { |
| 249 | RS_Vector snap = e->snapPoint; |
| 250 | switch (status){ |
| 251 | case SetExtPoint1: |
| 252 | case SetExtPoint2:{ |
| 253 | m_alternateMode = e->isControl; |
| 254 | break; |
| 255 | } |
| 256 | case SetDefPoint: { |
| 257 | snap = getFreeSnapAwarePoint(e, snap); |
| 258 | snap = adjustByAdjacentDim(snap, false, false); |
| 259 | break; |
| 260 | } |
| 261 | default: |
| 262 | break; |
| 263 | } |
| 264 | fireCoordinateEvent(snap); |
| 265 | } |
| 266 | |
| 267 | void LC_ActionDrawDimBaseline::pickOriginalEntity(RS_Entity* dimCandidate, const RS_Vector& mouse) { |
| 268 | RS_Vector extPoint1; |
| 269 | RS_Vector extPoint2; |
| 270 | RS_Vector dim1; |
| 271 | RS_Vector dim2; |
| 272 | double dimAngle; |
| 273 | |
| 274 | const int rtti = dimCandidate->rtti(); |
| 275 | switch (rtti){ |
| 276 | case RS2::EntityDimLinear:{ |
| 277 | const auto dimLinear = static_cast<RS_DimLinear *>(dimCandidate); |
| 278 | extPoint1 = dimLinear->getExtensionPoint1(); |
| 279 | extPoint2 = dimLinear->getExtensionPoint2(); |
| 280 | dimLinear->getDimPoints(dim1, dim2); |
| 281 | m_baseDefPoint = dimLinear->getDefinitionPoint(); |
| 282 | dimAngle = dimLinear->getAngle(); |
| 283 | m_dimDirectionAngle = extPoint1.angleTo(dim1); |
| 284 | break; |
| 285 | } |
| 286 | case RS2::EntityDimAligned:{ |
| 287 | const auto dimAligned = static_cast<RS_DimAligned *>(dimCandidate); |
| 288 | extPoint1 = dimAligned->getExtensionPoint1(); |
| 289 | extPoint2 = dimAligned->getExtensionPoint2(); |
| 290 | dimAligned->getDimPoints(dim1, dim2); |
| 291 | m_baseDefPoint = dimAligned->getDefinitionPoint(); |
| 292 | dimAngle = extPoint1.angleTo(extPoint2); |
| 293 | m_dimDirectionAngle = extPoint2.angleTo(dim2); |
| 294 | break; |
| 295 | } |
| 296 | case RS2::EntityDimAngular: |
| 297 | [[fallthrough]]; |
| 298 | default: |
| 299 | dimAngle = 0.0; // just to avoid warning |
Value stored to 'dimAngle' is never read | |
| 300 | return; |
| 301 | } |
| 302 | |
| 303 | const double dist1 = mouse.distanceTo(dim1); |
| 304 | const double dist2 = mouse.distanceTo(dim2); |
| 305 | |
| 306 | bool dim1CloserToMouse = dist1 < dist2; |
| 307 | if (m_alternateMode){ |
| 308 | dim1CloserToMouse = !dim1CloserToMouse; |
| 309 | } |
| 310 | if (dim1CloserToMouse){ |
| 311 | m_edata->extensionPoint1 = extPoint1; |
| 312 | m_prevExtensionPointEnd = extPoint2; |
| 313 | } else { |
| 314 | m_edata->extensionPoint1 = extPoint2; |
| 315 | m_prevExtensionPointEnd = extPoint1; |
| 316 | } |
| 317 | |
| 318 | m_edata->angle = dimAngle; |
| 319 | moveRelativeZero(m_edata->extensionPoint1); |
| 320 | setStatus(SetExtPoint2); |
| 321 | } |
| 322 | |
| 323 | void LC_ActionDrawDimBaseline::onCoordinateEvent(const int status, [[maybe_unused]] bool isZero, const RS_Vector &coord) { |
| 324 | switch (status){ |
| 325 | case SetExtPoint1: { |
| 326 | const auto dimCandidate = catchEntity(coord, DIM_ENTITY_TYPES, RS2::ResolveNone); |
| 327 | if (dimCandidate != nullptr) { |
| 328 | pickOriginalEntity(dimCandidate, coord); |
| 329 | } |
| 330 | break; |
| 331 | } |
| 332 | case SetExtPoint2:{ |
| 333 | const RS_Vector &extPoint1 = getExtensionPoint1(); |
| 334 | const RS_Vector &dimVector = RS_Vector::polar(100.0, m_edata->angle); |
| 335 | const RS_ConstructionLine dimLine(nullptr, RS_ConstructionLineData(extPoint1, extPoint1 + dimVector)); |
| 336 | const RS_Vector ext2Candidate = dimLine.getNearestPointOnEntity(coord, false); |
| 337 | const RS_Vector originalDefPointProjection = dimLine.getNearestPointOnEntity(m_baseDefPoint, false); |
| 338 | const RS_Vector defPointsDistance = m_baseDefPoint - originalDefPointProjection; |
| 339 | |
| 340 | RS_Vector newDefPoint = ext2Candidate + defPointsDistance; |
| 341 | if (isBaseline()) { |
| 342 | double dimAngle = m_dimDirectionAngle; |
| 343 | |
| 344 | if (m_alternateMode){ |
| 345 | dimAngle = M_PI3.14159265358979323846+dimAngle; |
| 346 | } |
| 347 | newDefPoint = newDefPoint +RS_Vector::polar(m_baselineDistance, dimAngle); |
| 348 | } |
| 349 | m_dimensionData->definitionPoint = newDefPoint; |
| 350 | |
| 351 | if (m_freeBaselineDistance && isBaseline()){ |
| 352 | m_currentDistance = 0.0; |
| 353 | setStatus(SetDefPoint); |
| 354 | } |
| 355 | else{ |
| 356 | trigger(); |
| 357 | setStatus(SetExtPoint2); |
| 358 | } |
| 359 | break; |
| 360 | } |
| 361 | case SetDefPoint:{ |
| 362 | m_dimensionData->definitionPoint = coord; |
| 363 | trigger(); |
| 364 | setStatus(SetExtPoint2); |
| 365 | break; |
| 366 | } |
| 367 | default: |
| 368 | break; |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | bool LC_ActionDrawDimBaseline::doProcessCommand(const int status, const QString &command) { |
| 373 | bool accept = false; |
| 374 | switch (status) { |
| 375 | case SetText: { |
| 376 | setText(command); |
| 377 | updateOptions(); |
| 378 | enableCoordinateInput(); |
| 379 | setStatus(m_lastStatus); |
| 380 | accept = true; |
| 381 | break; |
| 382 | } |
| 383 | default: |
| 384 | m_lastStatus = static_cast<Status>(getStatus()); |
| 385 | deletePreview(); |
| 386 | if (checkCommand("text", command)) { |
| 387 | disableCoordinateInput(); |
| 388 | setStatus(SetText); |
| 389 | accept = true; |
| 390 | } |
| 391 | break; |
| 392 | } |
| 393 | return accept; |
| 394 | } |
| 395 | |
| 396 | QStringList LC_ActionDrawDimBaseline::getAvailableCommands() { |
| 397 | QStringList cmd; |
| 398 | |
| 399 | switch (getStatus()) { |
| 400 | case SetExtPoint1: |
| 401 | case SetExtPoint2: |
| 402 | case SetDefPoint: { |
| 403 | cmd += command("text"); |
| 404 | break; |
| 405 | } |
| 406 | default: |
| 407 | break; |
| 408 | } |
| 409 | return cmd; |
| 410 | } |
| 411 | |
| 412 | void LC_ActionDrawDimBaseline::updateActionPrompt() { |
| 413 | const int status = getStatus(); |
| 414 | switch (status) { |
| 415 | case SetExtPoint1: |
| 416 | updatePromptTRCancel(tr("Select base linear/aligned dimension"), MOD_CTRL(tr("Select distant extension point"))LC_ModifiersInfo::CTRL(tr("Select distant extension point"))); |
| 417 | break; |
| 418 | case SetExtPoint2: |
| 419 | updatePromptTRBack(tr("Specify second extension line origin"), isBaseline() && !m_freeBaselineDistance ? MOD_CTRL(tr("Mirror offset direction"))LC_ModifiersInfo::CTRL(tr("Mirror offset direction")): MOD_NONELC_ModifiersInfo::NONE()); |
| 420 | break; |
| 421 | case SetDefPoint: |
| 422 | updatePromptTRBack(tr("Specify dimension line location"), MOD_SHIFT_LC(tr("Snap to Adjacent Dim"))LC_ModifiersInfo::SHIFT(tr("Snap to Adjacent Dim"))); |
| 423 | break; |
| 424 | case SetText: |
| 425 | updatePrompt(tr("Enter dimension text:")); |
| 426 | break; |
| 427 | default: |
| 428 | updatePrompt(); |
| 429 | break; |
| 430 | } |
| 431 | } |
| 432 | |
| 433 | bool LC_ActionDrawDimBaseline::isFreeBaselineDistance() const { |
| 434 | return m_freeBaselineDistance; |
| 435 | } |
| 436 | |
| 437 | void LC_ActionDrawDimBaseline::setFreeBaselineDistance(const bool freeDistance) { |
| 438 | m_freeBaselineDistance = freeDistance; |
| 439 | if (!m_freeBaselineDistance && getStatus() == SetDefPoint){ |
| 440 | setStatus(SetExtPoint2); |
| 441 | } |
| 442 | } |
| 443 | |
| 444 | double LC_ActionDrawDimBaseline::getBaselineDistance() const { |
| 445 | return m_baselineDistance; |
| 446 | } |
| 447 | |
| 448 | void LC_ActionDrawDimBaseline::setBaselineDistance(const double distance) { |
| 449 | m_baselineDistance = distance; |
| 450 | } |
| 451 | |
| 452 | double LC_ActionDrawDimBaseline::getCurrentBaselineDistance() const { |
| 453 | return m_currentDistance; |
| 454 | } |
| 455 | |
| 456 | RS_Vector LC_ActionDrawDimBaseline::getExtensionPoint1(){ |
| 457 | return m_edata->extensionPoint1; |
| 458 | } |
| 459 | |
| 460 | RS_Vector LC_ActionDrawDimBaseline::getExtensionPoint2(){ |
| 461 | return m_edata->extensionPoint2; |
| 462 | } |
| 463 | |
| 464 | double LC_ActionDrawDimBaseline::getDimAngle([[maybe_unused]] bool alternateMode){ |
| 465 | return m_edata->angle; |
| 466 | } |
| 467 | |
| 468 | void LC_ActionDrawDimBaseline::setExtensionPoint1(const RS_Vector& p){ |
| 469 | m_edata->extensionPoint1 = p; |
| 470 | } |
| 471 | |
| 472 | void LC_ActionDrawDimBaseline::setExtensionPoint2(const RS_Vector& p){ |
| 473 | m_edata->extensionPoint2 = p; |
| 474 | } |
| 475 | |
| 476 | void LC_ActionDrawDimBaseline::preparePreview([[maybe_unused]]bool alternativeMode) { |
| 477 | const RS_Vector dirV = RS_Vector::polar(100., m_edata->angle + M_PI_21.57079632679489661923); |
| 478 | const RS_ConstructionLine cl(nullptr,RS_ConstructionLineData(m_edata->extensionPoint2,m_edata->extensionPoint2 + dirV)); |
| 479 | m_dimensionData->definitionPoint = cl.getNearestPointOnEntity(m_dimensionData->definitionPoint); |
| 480 | } |