/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #include "OdaCommon.h" #include "DWGAssocActionUtils.h" #include "DWGAssocActionPE.h" #include "CsMoveUnderConstraints.h" #include "OdImplicitConstr.h" void convertMatrixGe2Cs(const OdGeMatrix3d& mat, OdGeMatrix2d& csMat) { csMat(0, 0) = mat(0, 0); csMat(0, 1) = mat(0, 1); csMat(1, 1) = mat(1, 1); csMat(1, 0) = mat(1, 0); csMat(0, 2) = mat(0, 3); csMat(1, 2) = mat(1, 3); csMat(2, 2) = mat(3, 3); csMat(2, 0) = 0.0; csMat(2, 1) = 0.0; } bool checkMoveBoundedLineVertex(const OdConstrainedBoundedLine* pLine, OdConstrainedImplicitPoint*& movePt, OdConstrainedImplicitPoint::ImplicitPointType& moveType, OdConstrainedImplicitPoint::ImplicitPointType& fixType, OdGeVector3d& moveVec) { movePt = nullptr; if (pLine->isRay()) { OdGeRay3d line = pLine->getOdGeRay3d(); OdGeRay3d origLine = pLine->getOriginalOdGeRay3d(); if (line.pointOnLine() == origLine.pointOnLine() && line.direction() != origLine.direction()) { ODA_ASSERT_ONCE(0); return false; } else if (line.pointOnLine() != origLine.pointOnLine() && line.direction() == origLine.direction()) { moveType = OdConstrainedImplicitPoint::kStartImplicit; moveVec = line.pointOnLine() - origLine.pointOnLine(); } else return false; } else { OdGeLineSeg3d line = pLine->getOdGeLineSeg3d(); OdGeLineSeg3d origLine = pLine->getOriginalOdGeLineSeg3d(); if (line.startPoint() == origLine.startPoint() && line.endPoint() != origLine.endPoint()) { moveType = OdConstrainedImplicitPoint::kEndImplicit; fixType = OdConstrainedImplicitPoint::kStartImplicit; moveVec = line.endPoint() - origLine.endPoint(); } else if (line.startPoint() != origLine.startPoint() && line.endPoint() == origLine.endPoint()) { moveType = OdConstrainedImplicitPoint::kStartImplicit; fixType = OdConstrainedImplicitPoint::kEndImplicit; moveVec = line.startPoint() - origLine.startPoint(); } else return false; } OdArray aPoints; pLine->getConstrainedImplicitPoints(aPoints); unsigned int i, size = aPoints.length(); for (i = 0; i < size; i++) { if (aPoints[i]->pointType() == moveType) { movePt = aPoints[i]; break; } } return true; } bool checkMoveCircleArcVertex(const OdConstrainedArc* pCircleArc, OdConstrainedImplicitPoint*& movePt, OdConstrainedImplicitPoint::ImplicitPointType& moveType, OdConstrainedImplicitPoint::ImplicitPointType& fixType1, OdConstrainedImplicitPoint::ImplicitPointType& fixType2, OdGeVector3d& moveVec) { OdGeCircArc3d arc = pCircleArc->getOdGeCircArc3d(); OdGeCircArc3d origArc = pCircleArc->getOriginalOdGeCircArc3d(); bool startPointsEq = arc.startPoint() == origArc.startPoint(); bool endPointsEq = arc.endPoint() == origArc.endPoint(); if (startPointsEq && !endPointsEq) { moveType = OdConstrainedImplicitPoint::kEndImplicit; fixType1 = OdConstrainedImplicitPoint::kStartImplicit; fixType2 = OdConstrainedImplicitPoint::kDefineImplicit; moveVec = arc.endPoint() - origArc.endPoint(); } else if (!startPointsEq && endPointsEq) { moveType = OdConstrainedImplicitPoint::kStartImplicit; fixType1 = OdConstrainedImplicitPoint::kEndImplicit; fixType2 = OdConstrainedImplicitPoint::kDefineImplicit; moveVec = arc.startPoint() - origArc.startPoint(); } else if (startPointsEq && endPointsEq) { moveType = OdConstrainedImplicitPoint::kMidImplicit; fixType1 = OdConstrainedImplicitPoint::kStartImplicit; fixType2 = OdConstrainedImplicitPoint::kEndImplicit; OdGeInterval interval; origArc.getInterval(interval); OdGePoint3d origMidpoint = origArc.evalPoint((interval.lowerBound() + interval.upperBound()) / 2.0); arc.getInterval(interval); OdGePoint3d midpoint = arc.evalPoint((interval.lowerBound() + interval.upperBound()) / 2.0); moveVec = midpoint - origMidpoint; } else return false; OdArray aPoints; pCircleArc->getConstrainedImplicitPoints(aPoints); unsigned int i, size = aPoints.length(); for (i = 0; i < size; i++) { if (aPoints[i]->pointType() == moveType) { movePt = aPoints[i]; break; } } return true; } bool checkMoveEllipseVertex(const OdConstrainedEllipse* pEllipse, OdConstrainedImplicitPoint*& /*movePt*/, OdConstrainedImplicitPoint::ImplicitPointType& /*moveType*/, OdConstrainedImplicitPoint::ImplicitPointType& /*fixType1*/, OdConstrainedImplicitPoint::ImplicitPointType& /*fixType2*/, OdGeVector3d& /*moveVec*/) { OdArray aImplicitPoints; pEllipse->getConstrainedImplicitPoints(aImplicitPoints); OdGeEllipArc3d arc = pEllipse->getOdGeEllipArc3d(); OdGeEllipArc3d origArc = pEllipse->getOriginalOdGeEllipArc3d(); /*OdCsGeometryPtr solverArc = FindSolverObject(pEllipse->nodeId()); if (!solverArc) return false; // Add radii implicit fixations double majorRadius = arc.majorRadius(); double originalMajorRadius = origArc.majorRadius(); if (OdEqual(majorRadius, originalMajorRadius)) _ctx.constraints().append(OdCsRadiusFixation::create(solverArc, majorRadius, OdCsConstraint::MajorRadius)); double minorRadius = arc.minorRadius(); double originalMinorRadius = origArc.minorRadius(); if (OdEqual(minorRadius, originalMinorRadius)) _ctx.constraints().append(OdCsRadiusFixation::create(solverArc, minorRadius, OdCsConstraint::MinorRadius)); OdCsMoveUnderConstraintsOptions options; // Center point OdGePoint3d centerPoint = arc.center(); OdGePoint3d originalCenterPoint = origArc.center(); OdConstrainedImplicitPoint* centerPointConstrained = DWGConstraintUtils::selectPoint(aImplicitPoints, OdConstrainedImplicitPoint::kCenterImplicit); OdCsGeometryPtr centerPointId = (centerPointConstrained != nullptr) ? FindSolverObject(centerPointConstrained->nodeId()) : OdCsGeometryPtr(OdCsPoint::create(centerPoint.convert2d())); if (centerPoint == originalCenterPoint) fixatePointPosition(centerPointId); else addPointMovement(options, centerPointId, originalCenterPoint, centerPoint); // Middle point OdGePoint3d middlePoint = arc.midPoint(); OdGePoint3d originalMiddlePoint = origArc.midPoint(); OdConstrainedImplicitPoint* middlePointConstrained = DWGConstraintUtils::selectPoint(aImplicitPoints, OdConstrainedImplicitPoint::kMidImplicit); OdCsGeometryPtr middlePointId = (middlePointConstrained != nullptr) ? FindSolverObject(middlePointConstrained->nodeId()) : OdCsGeometryPtr(OdCsPoint::create(middlePoint.convert2d())); lockPointOnCurve(solverArc, middlePointId, arc.paramOf(middlePoint)); if (middlePoint == originalMiddlePoint) fixatePointPosition(middlePointId); else addPointMovement(options, middlePointId, originalMiddlePoint, middlePoint); // Start point OdGePoint3d startPoint = arc.startPoint(); OdGePoint3d originalStartPoint = origArc.startPoint(); OdConstrainedImplicitPoint* startPointConstrained = DWGConstraintUtils::selectPoint(aImplicitPoints, OdConstrainedImplicitPoint::kStartImplicit); OdCsGeometryPtr startPointId = (startPointConstrained != nullptr) ? FindSolverObject(startPointConstrained->nodeId()) : OdCsGeometryPtr(OdCsPoint::create(startPoint.convert2d())); lockPointOnCurve(solverArc, startPointId, arc.paramOf(startPoint)); if (startPoint == originalStartPoint) fixatePointPosition(startPointId); else addPointMovement(options, startPointId, originalStartPoint, startPoint); // End point OdGePoint3d endPoint = arc.endPoint(); OdGePoint3d originalEndPoint = origArc.endPoint(); OdConstrainedImplicitPoint* endPointConstrained = DWGConstraintUtils::selectPoint(aImplicitPoints, OdConstrainedImplicitPoint::kEndImplicit); OdCsGeometryPtr endPointId = (endPointConstrained != nullptr) ? FindSolverObject(endPointConstrained->nodeId()) : OdCsGeometryPtr(OdCsPoint::create(endPoint.convert2d())); lockPointOnCurve(solverArc, endPointId, arc.paramOf(endPoint)); if (endPoint == originalEndPoint) fixatePointPosition(endPointId); else addPointMovement(options, endPointId, originalEndPoint, endPoint);*/ return false; } bool checkMoveVertex(const OdConstrainedGeometry* geom, OdConstrainedImplicitPoint*& movePt, OdGePoint2d& movePtCordinate) { movePt = nullptr; OdConstrainedImplicitPoint::ImplicitPointType moveType, fixType, fixType2; OdGeVector3d moveVec; if (geom->isKindOf(OdConstrainedArc::desc())) // arc { OdConstrainedArc* pArc = OdConstrainedArc::cast(geom); if (!checkMoveCircleArcVertex(pArc, movePt, moveType, fixType2, fixType, moveVec)) return false; if (movePt == nullptr) { ODA_ASSERT_ONCE(moveType == OdConstrainedImplicitPoint::kMidImplicit); // point doesn't exist yet in solver OdGeCircArc3d origArc = pArc->getOriginalOdGeCircArc3d(); OdGeInterval interval; origArc.getInterval(interval); OdGePoint3d midpoint = origArc.evalPoint((interval.lowerBound() + interval.upperBound()) / 2.0); movePtCordinate = midpoint.convert2d(); } return true; } if (geom->isKindOf(OdConstrainedBoundedEllipse::desc())) // elliptic arc { //OdConstrainedBoundedEllipse* pArc = OdConstrainedBoundedEllipse::cast(geom); //return checkMoveEllipseVertex(pArc, movePt, moveType, fixType2, fixType, moveVec); return false; } if (geom->isKindOf(OdConstrainedBoundedLine::desc())) // line { OdConstrainedBoundedLine* pLine = OdConstrainedBoundedLine::cast(geom); return checkMoveBoundedLineVertex(pLine, movePt, moveType, fixType, moveVec); } if (geom->isKindOf(OdConstrainedSpline::desc())) // spline { //OdConstrainedSpline* pSpline = OdConstrainedSpline::cast(geom); return false; } if (geom->isKindOf(OdConstrainedCircle::desc())) // circle { //OdConstrainedCircle* pCircle = OdConstrainedCircle::cast(geom); return false; } if (geom->isKindOf(OdConstrainedEllipse::desc())) // ellipse { //OdConstrainedEllipse* pEllipse = OdConstrainedEllipse::cast(geom); return false; } ODA_FAIL_ONCE(); return false; } bool tryMoveBoundedLineVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrainedBoundedLine* pLine) { OdConstrainedImplicitPoint* movePt; OdConstrainedImplicitPoint::ImplicitPointType moveType, fixType; OdGeVector3d moveVec; bool res = checkMoveBoundedLineVertex(pLine, movePt, moveType, fixType, moveVec); ODA_VERIFY_ONCE(res); OdArray aPoints; pLine->getConstrainedImplicitPoints(aPoints); OdCsGeometryPtr moveObjectId; OdCsGeometryPtr fix1ObjectId; unsigned int i, size = aPoints.length(); for (i = 0; i < size; ++i) { if (aPoints[i]->pointType() == moveType) { moveObjectId = pPE->FindSolverObject(aPoints[i]->nodeId()); } else if (!pLine->isRay() && aPoints[i]->pointType() == fixType) { fix1ObjectId = pPE->FindSolverObject(aPoints[i]->nodeId()); } } if (moveObjectId == NULL) { ODA_FAIL(); return false; } if (fix1ObjectId != NULL) { pPE->_auxiliaryConstraintHelper.addAuxiliaryConstraint(OdCsFixation::create(fix1ObjectId)); } if (!moveVec.isZeroLength()) { options.translate(moveObjectId, moveVec.convert2d()); } return true; } bool tryMoveCircleArcVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrainedArc* pCircleArc) { OdConstrainedImplicitPoint* movePt; OdGeVector3d moveVec; OdConstrainedImplicitPoint::ImplicitPointType moveType, fixType1, fixType2; bool res = checkMoveCircleArcVertex(pCircleArc, movePt, moveType, fixType1, fixType2, moveVec); ODA_VERIFY_ONCE(res); OdArray aPoints; pCircleArc->getConstrainedImplicitPoints(aPoints); OdCsGeometryPtr moveObjectId = NULL; OdCsGeometryPtr fix1ObjectId = NULL; OdCsGeometryPtr fix2ObjectId = NULL; unsigned int i, size = aPoints.length(); for (i = 0; i < size; i++) { if (aPoints[i]->pointType() == moveType) { moveObjectId = pPE->FindSolverObject(aPoints[i]->nodeId()); } else if (aPoints[i]->pointType() == fixType1) { fix1ObjectId = pPE->FindSolverObject(aPoints[i]->nodeId()); } else if (aPoints[i]->pointType() == fixType2) { fix2ObjectId = pPE->FindSolverObject(aPoints[i]->nodeId()); } } if (fix1ObjectId != NULL) { pPE->_auxiliaryConstraintHelper.addAuxiliaryConstraint(OdCsFixation::create(fix1ObjectId)); } if (fix2ObjectId != NULL) { pPE->_auxiliaryConstraintHelper.addAuxiliaryConstraint(OdCsFixation::create(fix2ObjectId)); } { OdGeCircArc3d origArc = pCircleArc->getOriginalOdGeCircArc3d(); const OdGePoint3d midpoint = origArc.midPoint(); OdCsGeometryPtr midPointId = OdCsPoint::create(midpoint.convert2d()); OdCsGeometryPtr solverArc = pPE->FindSolverObject(pCircleArc->nodeId()); if (solverArc == NULL) { ODA_FAIL_ONCE(); return false; } pPE->_ctx.geometries().append(midPointId); OdCsConstraintPtr id = OdCsCoincidence::create(solverArc, midPointId); pPE->_ctx.constraints().append(id); if (moveType != OdConstrainedImplicitPoint::kMidImplicit) { id = OdCsFixation::create(midPointId); pPE->_auxiliaryConstraintHelper.addAuxiliaryConstraint(id); } else { moveObjectId = midPointId; } } if (!moveVec.isZeroLength()) { options.translate(moveObjectId, moveVec.convert2d()); } return true; } bool tryMoveVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrainedGeometry* geom) { if (geom->isKindOf(OdConstrainedArc::desc())) // arc { OdConstrainedArc* pArc = OdConstrainedArc::cast(geom); return tryMoveCircleArcVertex(pPE, options, pArc); } if (geom->isKindOf(OdConstrainedBoundedEllipse::desc())) // elliptic arc { //OdConstrainedBoundedEllipse* pEllipse = OdConstrainedBoundedEllipse::cast(geom); return false; } if (geom->isKindOf(OdConstrainedBoundedLine::desc())) // line { OdConstrainedBoundedLine* pLine = OdConstrainedBoundedLine::cast(geom); return tryMoveBoundedLineVertex(pPE, options, pLine); } if (geom->isKindOf(OdConstrainedSpline::desc())) // spline { //OdConstrainedSpline* pSpline = OdConstrainedSpline::cast(geom); return false; } if (geom->isKindOf(OdConstrainedCircle::desc())) // circle { //OdConstrainedCircle* pCircle = OdConstrainedCircle::cast(geom); return false; } if (geom->isKindOf(OdConstrainedEllipse::desc())) // ellipse { //OdConstrainedEllipse* pEllipse = OdConstrainedEllipse::cast(geom); return false; } ODA_FAIL_ONCE(); return false; } bool complicatedMoveBoundedLineVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrainedBoundedLine* pLine) { #ifdef _DEBUG //OdConstrainedImplicitPoint* movePt = nullptr; //OdGePoint2d movePtCordinate; //ODA_ASSERT_ONCE(!checkMoveVertex(pLine, movePt, movePtCordinate)); #endif if (pLine->isRay()) { ODA_ASSERT_ONCE(0); return false; } else { OdArray aPoints; pLine->getConstrainedImplicitPoints(aPoints); OdCsGeometryPtr moveObjectIdStart, moveObjectIdEnd; for (unsigned int i = 0; i < aPoints.length(); ++i) { if (aPoints[i]->pointType() == OdConstrainedImplicitPoint::kStartImplicit) { moveObjectIdStart = pPE->FindSolverObject(aPoints[i]->nodeId()); } else if (aPoints[i]->pointType() == OdConstrainedImplicitPoint::kEndImplicit) { moveObjectIdEnd = pPE->FindSolverObject(aPoints[i]->nodeId()); } } OdGeLineSeg3d line = pLine->getOdGeLineSeg3d(); OdGeLineSeg3d origLine = pLine->getOriginalOdGeLineSeg3d(); OdGeVector2d vMove = (line.startPoint() - origLine.startPoint()).convert2d(); if (!vMove.isZeroLength()) { options.translate(moveObjectIdStart, vMove); } vMove = (line.endPoint() - origLine.endPoint()).convert2d(); if (!vMove.isZeroLength()) { options.translate(moveObjectIdEnd, vMove); } } return true; } bool complicatedMoveSplineVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrainedSpline* pSpline) { OdArray aPoints; pSpline->getConstrainedImplicitPoints(aPoints); OdGeNurbCurve3d nurbCurve = pSpline->nurbSpline(); OdGeNurbCurve3d origNurbCurve = pSpline->originalNurbSpline(); OdCsGeometryPtr csGeom = pPE->FindSolverObject(pSpline->nodeId()); ODA_ASSERT_ONCE(csGeom->type() == OdCs::kSpline); OdCsSplinePtr csSpline = csGeom.staticCast(); if(csSpline.isNull()) return false; OdVector controlPoints = csSpline->controlPoints(); for (int i = 0; i < nurbCurve.numControlPoints(); i++) { OdGePoint3d controlPoint = nurbCurve.controlPointAt(i); OdGePoint3d origControlPoint = origNurbCurve.controlPointAt(i); OdGeVector3d moveVector = controlPoint - origControlPoint; if (moveVector.isZeroLength()) continue; OdCsGeometryPtr csPoint = controlPoints[i]; ODA_ASSERT_ONCE(csPoint); if(csPoint) options.translate(csPoint, moveVector.convert2d()); } return true; } /*static OdCsCoincidencePtr findPtCoincidence(const OdConstrainedImplicitPoint* impPt, const OdConstrainedCurve* curve, const DWGAssocActionPE::Solver2Constraint& map) { OdArray apConstraints; impPt->getConnectedConstraints(apConstraints); for (OdGeomConstraint* constraint : apConstraints) { if (!constraint->isKindOf(OdPointCurveConstraint::desc())) { continue; } OdArray connectedGeoms; constraint->getConnectedGeometries(connectedGeoms); if (connectedGeoms.logicalLength() == 2) { if ((connectedGeoms[0] == impPt && connectedGeoms[1] == curve) || (connectedGeoms[1] == impPt && connectedGeoms[0] == curve)) { auto it = map.find(constraint->nodeId()); if (it == map.end()) { return nullptr; } return it->second.dynamicCast(); } } else ODA_FAIL_ONCE(); } return nullptr; }*/ bool complicatedMoveCircleArcVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrainedArc* pArc) { #ifdef _DEBUG OdConstrainedImplicitPoint* movePt = nullptr; OdGePoint2d movePtCoordinate; ODA_ASSERT_ONCE(!checkMoveVertex(pArc, movePt, movePtCoordinate)); #endif OdGeCircArc3d arc = pArc->getOdGeCircArc3d(); OdGeCircArc3d origArc = pArc->getOriginalOdGeCircArc3d(); OdArray aPoints; pArc->getConstrainedImplicitPoints(aPoints); for (OdConstrainedImplicitPoint* impPt : aPoints) { if (impPt->pointType() == OdConstrainedImplicitPoint::kStartImplicit) { OdCsGeometryPtr moveObjectId = pPE->FindSolverObject(impPt->nodeId()); const OdGeVector2d moveVec = (arc.startPoint() - origArc.startPoint()).convert2d(); if (!moveVec.isZeroLength()) { options.translate(moveObjectId, moveVec); } } else if (impPt->pointType() == OdConstrainedImplicitPoint::kEndImplicit) { OdCsGeometryPtr moveObjectId = pPE->FindSolverObject(impPt->nodeId()); const OdGeVector2d moveVec = (arc.endPoint() - origArc.endPoint()).convert2d(); if (!moveVec.isZeroLength()) { options.translate(moveObjectId, moveVec); } } else if (impPt->pointType() == OdConstrainedImplicitPoint::kCenterImplicit) { OdCsGeometryPtr moveObjectId = pPE->FindSolverObject(impPt->nodeId()); const OdGeVector2d moveVec = (arc.center() - origArc.center()).convert2d(); if (!moveVec.isZeroLength()) { options.translate(moveObjectId, moveVec); } } } /*OdCsGeometryPtr arcId = pPE->FindSolverObject(pArc->nodeId()); OdCsRadiusFixationPtr radFix = OdCsRadiusFixation::create(arcId, arc.radius()); pPE->_ctx.constraints().append(radFix);*/ //options.changeRadius(arcId, arc.radius()); return true; } bool complicatedMoveEllipArcVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrainedBoundedEllipse* pArc) { #ifdef _DEBUG OdConstrainedImplicitPoint* movePt = nullptr; OdGePoint2d movePtCordinate; ODA_ASSERT_ONCE(!checkMoveVertex(pArc, movePt, movePtCordinate)); #endif OdGeEllipArc3d arc = pArc->getOdGeEllipArc3d(); OdGeEllipArc3d origArc = pArc->getOriginalOdGeEllipArc3d(); OdArray aPoints; pArc->getConstrainedImplicitPoints(aPoints); for (OdConstrainedImplicitPoint* impPt : aPoints) { if (impPt->pointType() == OdConstrainedImplicitPoint::kStartImplicit) { OdCsGeometryPtr moveObjectId = pPE->FindSolverObject(impPt->nodeId()); const OdGeVector2d moveVec = (arc.startPoint() - origArc.startPoint()).convert2d(); if (!moveVec.isZeroLength()) { options.translate(moveObjectId, moveVec); } } else if (impPt->pointType() == OdConstrainedImplicitPoint::kEndImplicit) { OdCsGeometryPtr moveObjectId = pPE->FindSolverObject(impPt->nodeId()); const OdGeVector2d moveVec = (arc.endPoint() - origArc.endPoint()).convert2d(); if (!moveVec.isZeroLength()) { options.translate(moveObjectId, moveVec); } } else if (impPt->pointType() == OdConstrainedImplicitPoint::kCenterImplicit) { OdCsGeometryPtr moveObjectId = pPE->FindSolverObject(impPt->nodeId()); const OdGeVector2d moveVec = (arc.center() - origArc.center()).convert2d(); if (!moveVec.isZeroLength()) { options.translate(moveObjectId, moveVec); } } } OdCsGeometryPtr solverArc = pPE->FindSolverObject(pArc->nodeId()); const double majorRadius = arc.majorRadius(); const double originalMajorRadius = origArc.majorRadius(); if (!OdEqual(majorRadius, originalMajorRadius)) { options.changeRadius(solverArc, majorRadius, OdCsConstraint::MajorRadius); } else { //pPE->_ctx.constraints().append(OdCsRadiusFixation::create(solverArc, majorRadius, OdCsConstraint::MajorRadius)); } const double minorRadius = arc.minorRadius(); const double originalMinorRadius = origArc.minorRadius(); if (!OdEqual(minorRadius, originalMinorRadius)) { options.changeRadius(solverArc, minorRadius, OdCsConstraint::MinorRadius); } else { //pPE->_ctx.constraints().append(OdCsRadiusFixation::create(solverArc, minorRadius, OdCsConstraint::MinorRadius)); } return true; } bool complicatedMoveCircleVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrainedCircle* pArc) { #ifdef _DEBUG OdConstrainedImplicitPoint* movePt = nullptr; OdGePoint2d movePtCordinate; ODA_ASSERT_ONCE(!checkMoveVertex(pArc, movePt, movePtCordinate)); #endif OdGeCircArc3d arc = pArc->getOdGeCircArc3d(); OdGeCircArc3d origArc = pArc->getOriginalOdGeCircArc3d(); OdArray aPoints; pArc->getConstrainedImplicitPoints(aPoints); for (OdConstrainedImplicitPoint* impPt : aPoints) { if (impPt->pointType() == OdConstrainedImplicitPoint::kCenterImplicit) { OdCsGeometryPtr moveObjectId = pPE->FindSolverObject(impPt->nodeId()); const OdGeVector3d moveVec = arc.center() - origArc.center(); if (!moveVec.isZeroLength()) { options.translate(moveObjectId, moveVec.convert2d()); } } } OdCsGeometryPtr solverArc = pPE->FindSolverObject(pArc->nodeId()); const double r = arc.radius(); const double originalR = origArc.radius(); if (!OdEqual(r, originalR)) { options.changeRadius(solverArc, r, OdCsConstraint::CircleRadius); } else { //pPE->_ctx.constraints().append(OdCsRadiusFixation::create(solverArc, r, OdCsConstraint::CircleRadius)); } return true; } bool complicatedMoveEllipseVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrainedEllipse* pArc) { #ifdef _DEBUG OdConstrainedImplicitPoint* movePt = nullptr; OdGePoint2d movePtCordinate; ODA_ASSERT_ONCE(!checkMoveVertex(pArc, movePt, movePtCordinate)); #endif OdGeEllipArc3d arc = pArc->getOdGeEllipArc3d(); OdGeEllipArc3d origArc = pArc->getOriginalOdGeEllipArc3d(); OdGeVector3d majorOrig = origArc.majorAxis(); OdGeVector3d major = arc.majorAxis(); OdCsGeometryPtr solverArc = pPE->FindSolverObject(pArc->nodeId()); SolverTransfTyper transTyper = pPE->getTransformation(origArc.center() + majorOrig, origArc.center(), arc.center() + major, arc.center()); if (transTyper.getType() != SolverTransfTyper::TransTypeNo) { ODA_ASSERT_ONCE(transTyper.isSimpleTypeTransformation()); const OdGeMatrix3d& trans = transTyper.m_matr; OdGeMatrix2d csTrans; convertMatrixGe2Cs(trans, csTrans); options.transform(solverArc, csTrans); } const double majorRadius = arc.majorRadius(); const double originalMajorRadius = origArc.majorRadius(); if (!OdEqual(majorRadius, originalMajorRadius)) { options.changeRadius(solverArc, majorRadius, OdCsConstraint::MajorRadius); } else { //pPE->_ctx.constraints().append(OdCsRadiusFixation::create(solverArc, majorRadius, OdCsConstraint::MajorRadius)); } const double minorRadius = arc.minorRadius(); const double originalMinorRadius = origArc.minorRadius(); if (!OdEqual(minorRadius, originalMinorRadius)) { options.changeRadius(solverArc, minorRadius, OdCsConstraint::MinorRadius); } else { //pPE->_ctx.constraints().append(OdCsRadiusFixation::create(solverArc, minorRadius, OdCsConstraint::MinorRadius)); } return true; } bool complicatedMove2PointsConstructionLineVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrained2PointsConstructionLine* pLine) { OdCsGeometryPtr solverLine = pPE->FindSolverObject(pLine->nodeId()); if (!solverLine) return false; OdGeLine3d line = pLine->getOdGeLine3d(); OdGeLine3d origLine = pLine->getOriginalOdGeLine3d(); OdGePoint3d startPoint = line.evalPoint(0); OdGePoint3d endPoint = startPoint + line.direction(); OdGePoint3d origStartPoint = origLine.evalPoint(0); OdGePoint3d origEndPoint = origStartPoint + origLine.direction(); SolverTransfTyper transTyper = pPE->getTransformation(origStartPoint, origEndPoint, startPoint, endPoint); if (transTyper.getType() != SolverTransfTyper::TransTypeNo) { const OdGeMatrix3d& trans = transTyper.m_matr; OdGeMatrix2d csTrans; convertMatrixGe2Cs(trans, csTrans); options.transform(solverLine, csTrans); } return true; } bool complicatedMoveVertex(DWGAssocActionPE* pPE, OdCsMoveUnderConstraintsOptions& options, OdConstrainedGeometry* geom) { if (geom->isKindOf(OdConstrainedArc::desc())) // arc { OdConstrainedArc* pArc = OdConstrainedArc::cast(geom); return complicatedMoveCircleArcVertex(pPE, options, pArc); } if (geom->isKindOf(OdConstrainedBoundedEllipse::desc())) // elliptic arc { OdConstrainedBoundedEllipse* pArc = OdConstrainedBoundedEllipse::cast(geom); return complicatedMoveEllipArcVertex(pPE, options, pArc);; } if (geom->isKindOf(OdConstrainedBoundedLine::desc())) // line { OdConstrainedBoundedLine* pLine = OdConstrainedBoundedLine::cast(geom); return complicatedMoveBoundedLineVertex(pPE, options, pLine); } if (geom->isKindOf(OdConstrainedSpline::desc())) // spline { OdConstrainedSpline* pSpline = OdConstrainedSpline::cast(geom); return complicatedMoveSplineVertex(pPE, options, pSpline); } if (geom->isKindOf(OdConstrainedCircle::desc())) // circle { OdConstrainedCircle* pCircle = OdConstrainedCircle::cast(geom); return complicatedMoveCircleVertex(pPE, options, pCircle); } if (geom->isKindOf(OdConstrainedEllipse::desc())) // ellipse { OdConstrainedEllipse* pEllipse = OdConstrainedEllipse::cast(geom); return complicatedMoveEllipseVertex(pPE, options, pEllipse); } if(geom->isKindOf(OdConstrained2PointsConstructionLine::desc())) { OdConstrained2PointsConstructionLine* pLine = OdConstrained2PointsConstructionLine::cast(geom); return complicatedMove2PointsConstructionLineVertex(pPE, options, pLine); } ODA_FAIL_ONCE(); return false; } bool isImplicitPointFixated(const OdConstrainedImplicitPoint* point) { OdArray connectedConstraints; point->getConnectedConstraints(connectedConstraints); bool result = false; for (const OdGeomConstraint* connectedConstraint : connectedConstraints) { if (connectedConstraint->isKindOf(OdFixedConstraint::desc())) { result = true; break; } } return result; }