/////////////////////////////////////////////////////////////////////////////// // 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 "DgExport.h" #include "RxDictionary.h" #include "DgMatrixTransform3d.h" #include "RxMember.h" #include "RxProperty.h" #include "RxValueTypeUtil.h" #include "RxAttribute.h" //================================================================================================== // Implementation of OdDgMatrixTransform3d class //================================================================================================== OdDgMatrixTransform3d::OdDgMatrixTransform3d() { m_dXAngle = 0.0; m_dYAngle = 0.0; m_dZAngle = 0.0; m_dXScale = 1.0; m_dYScale = 1.0; m_dZScale = 1.0; } //================================================================================================== OdDgMatrixTransform3d::OdDgMatrixTransform3d(double dXAngle, double dYAngle, double dZAngle, double dXScale, double dYScale, double dZScale) { m_dXAngle = dXAngle; m_dYAngle = dYAngle; m_dZAngle = dZAngle; m_dXScale = dXScale; m_dYScale = dYScale; m_dZScale = dZScale; } //================================================================================================== OdDgMatrixTransform3d::OdDgMatrixTransform3d(const OdGeMatrix3d& matTransform) { setMatrix(matTransform); } //================================================================================================== double OdDgMatrixTransform3d::getXAngle() const { return m_dXAngle; } //================================================================================================== double OdDgMatrixTransform3d::getYAngle() const { return m_dYAngle; } //================================================================================================== double OdDgMatrixTransform3d::getZAngle() const { return m_dZAngle; } //================================================================================================== void OdDgMatrixTransform3d::setXAngle(double dAngle) { m_dXAngle = dAngle; } //================================================================================================== void OdDgMatrixTransform3d::setYAngle(double dAngle) { m_dYAngle = dAngle; } //================================================================================================== void OdDgMatrixTransform3d::setZAngle(double dAngle) { m_dZAngle = dAngle; } //================================================================================================== double OdDgMatrixTransform3d::getXScale() const { return m_dXScale; } //================================================================================================== double OdDgMatrixTransform3d::getYScale() const { return m_dYScale; } //================================================================================================== double OdDgMatrixTransform3d::getZScale() const { return m_dZScale; } //================================================================================================== void OdDgMatrixTransform3d::setXScale(double dScale) { m_dXScale = dScale; } //================================================================================================== void OdDgMatrixTransform3d::setYScale(double dScale) { m_dYScale = dScale; } //================================================================================================== void OdDgMatrixTransform3d::setZScale(double dScale) { m_dZScale = dScale; } //================================================================================================== OdGeMatrix3d OdDgMatrixTransform3d::getMatrix() const { OdGeMatrix3d matTransform = OdGeMatrix3d::rotation(m_dXAngle, OdGeVector3d::kXAxis) * OdGeMatrix3d::rotation(m_dYAngle, OdGeVector3d::kYAxis) * OdGeMatrix3d::rotation(m_dZAngle, OdGeVector3d::kZAxis); matTransform = OdGeMatrix3d::scaling(OdGeScale3d(m_dXScale, m_dYScale, m_dZScale))*matTransform; return matTransform; } //================================================================================================== void OdDgMatrixTransform3d::setMatrix(const OdGeMatrix3d& matTransform) { OdGeMatrix3d matRotation = matTransform; OdGeVector3d vrXAxis = OdGeVector3d::kXAxis; OdGeVector3d vrYAxis = OdGeVector3d::kYAxis; OdGeVector3d vrZAxis = OdGeVector3d::kZAxis; vrXAxis.transformBy(matRotation); vrYAxis.transformBy(matRotation); vrZAxis.transformBy(matRotation); m_dXScale = vrXAxis.length(); m_dYScale = vrYAxis.length(); m_dZScale = vrZAxis.length(); vrXAxis.normalize(); vrYAxis.normalize(); vrZAxis.normalize(); if (vrZAxis.x > 1) vrZAxis.x = 1.0; if (vrZAxis.x < -1) vrZAxis.x = -1.0; double dXAngle = 0; double dYAngle = 0; double dZAngle = 0; double dXAngle1 = 0; double dXAngle2 = 0; double dYAngle1 = OD_ASIN(vrZAxis.x); double dYAngle2 = dYAngle1 + OdaPI; double dZAngle1 = 0; double dZAngle2 = 0; if (!OdZero(cos(dYAngle1), 1e-6)) { double dSin1X = -1.0 * vrZAxis.y / cos(dYAngle1); double dSin2X = -1.0 * vrZAxis.y / cos(dYAngle2); double dCos1X = vrZAxis.z / cos(dYAngle1); double dCos2X = vrZAxis.z / cos(dYAngle2); if (dCos1X > 1) dCos1X = 1; if (dCos1X < -1) dCos1X = -1; if (dCos2X > 1) dCos2X = 1; if (dCos2X < -1) dCos2X = -1; dXAngle1 = OD_ACOS(dCos1X); dXAngle2 = OD_ACOS(dCos2X); if (((dXAngle1 > 0 || dZAngle1 < OdaPI) && (dSin1X < 0)) || ((dXAngle1 > OdaPI || dZAngle1 < 0) && (dSin1X > 0)) ) { dXAngle1 = -dXAngle1; } if (((dXAngle2 > 0 || dXAngle2 < OdaPI) && (dSin2X < 0)) || ((dXAngle2 > OdaPI || dXAngle2 < 0) && (dSin2X > 0)) ) { dXAngle2 = -dXAngle2; } double dSin1Z = -1.0 * vrYAxis.x / cos(dYAngle1); double dSin2Z = -1.0 * vrYAxis.x / cos(dYAngle2); double dCos1Z = vrXAxis.x / cos(dYAngle1); double dCos2Z = vrXAxis.x / cos(dYAngle2); if (dCos1Z > 1) dCos1Z = 1; if (dCos1Z < -1) dCos1Z = -1; if (dCos2Z > 1) dCos2Z = 1; if (dCos2Z < -1) dCos2Z = -1; dZAngle1 = OD_ACOS(dCos1Z); dZAngle2 = OD_ACOS(dCos2Z); if (((dZAngle1 > 0 || dZAngle1 < OdaPI) && (dSin1Z < 0)) || ((dZAngle1 > OdaPI || dZAngle1 < 0) && (dSin1Z > 0)) ) { dZAngle1 = -dZAngle1; } if (((dZAngle2 > 0 || dZAngle2 < OdaPI) && (dSin2Z < 0)) || ((dZAngle2 > OdaPI || dZAngle2 < 0) && (dSin2Z > 0)) ) { dZAngle2 = -dZAngle2; } } else { dYAngle2 = dYAngle1; dXAngle1 = OdGeVector3d::kZAxis.angleTo(vrXAxis, OdGeVector3d::kXAxis); dXAngle2 = dXAngle1; dZAngle1 = OdaPI; dZAngle2 = 0; } double dYy1 = cos(dXAngle1)*cos(dZAngle1) - sin(dXAngle1)*sin(dYAngle1)*sin(dZAngle1); double dYz1 = sin(dXAngle1)*cos(dZAngle1) + cos(dXAngle1)*sin(dYAngle1)*sin(dZAngle1); double dXy1 = cos(dXAngle1)*sin(dZAngle1) + sin(dXAngle1)*sin(dYAngle1)*cos(dZAngle1); double dXz1 = sin(dXAngle1)*sin(dZAngle1) - cos(dXAngle1)*sin(dYAngle1)*cos(dZAngle1); if (OdZero(dYy1 - vrYAxis.y, 1e-6) && OdZero(dYz1 - vrYAxis.z, 1e-6) && OdZero(dXy1 - vrXAxis.y, 1e-6) && OdZero(dXz1 - vrXAxis.z, 1e-6) ) { dXAngle = dXAngle1; dYAngle = dYAngle1; dZAngle = dZAngle1; } else { dXAngle = dXAngle2; dYAngle = dYAngle2; dZAngle = dZAngle2; } m_dXAngle = dXAngle; m_dYAngle = dYAngle; m_dZAngle = dZAngle; } //================================================================================================== // OdDgMatrixTransform3d CDA property value type registration //================================================================================================== ODRX_DECLARE_RX_PROPERTY(OdDgMatrixTransform3d, RotationX, double); ODRX_DECLARE_RX_PROPERTY(OdDgMatrixTransform3d, RotationY, double); ODRX_DECLARE_RX_PROPERTY(OdDgMatrixTransform3d, RotationZ, double); ODRX_DECLARE_RX_PROPERTY(OdDgMatrixTransform3d, ScaleX, double); ODRX_DECLARE_RX_PROPERTY(OdDgMatrixTransform3d, ScaleY, double); ODRX_DECLARE_RX_PROPERTY(OdDgMatrixTransform3d, ScaleZ, double); //================================================================================================== OdResult OdDgMatrixTransform3dRotationXProperty::subGetValue(const OdRxObject* pO, OdRxValue& value) const { const OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; const OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; value = matData->getXAngle(); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dRotationXProperty::subSetValue(OdRxObject* pO, const OdRxValue& value) const { if (!pO) return eNotApplicable; OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; const double* pValue = rxvalue_cast(&value); if (!pValue) return eNotThatKindOfClass; matData->setXAngle(*pValue); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dRotationYProperty::subGetValue(const OdRxObject* pO, OdRxValue& value) const { const OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; const OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; value = matData->getYAngle(); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dRotationYProperty::subSetValue(OdRxObject* pO, const OdRxValue& value) const { if (!pO) return eNotApplicable; OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; const double* pValue = rxvalue_cast(&value); if (!pValue) return eNotThatKindOfClass; matData->setYAngle(*pValue); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dRotationZProperty::subGetValue(const OdRxObject* pO, OdRxValue& value) const { const OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; const OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; value = matData->getZAngle(); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dRotationZProperty::subSetValue(OdRxObject* pO, const OdRxValue& value) const { if (!pO) return eNotApplicable; OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; const double* pValue = rxvalue_cast(&value); if (!pValue) return eNotThatKindOfClass; matData->setZAngle(*pValue); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dScaleXProperty::subGetValue(const OdRxObject* pO, OdRxValue& value) const { const OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; const OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; value = matData->getXScale(); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dScaleXProperty::subSetValue(OdRxObject* pO, const OdRxValue& value) const { if (!pO) return eNotApplicable; OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; const double* pValue = rxvalue_cast(&value); if (!pValue) return eNotThatKindOfClass; matData->setXScale(*pValue); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dScaleYProperty::subGetValue(const OdRxObject* pO, OdRxValue& value) const { const OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; const OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; value = matData->getYScale(); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dScaleYProperty::subSetValue(OdRxObject* pO, const OdRxValue& value) const { if (!pO) return eNotApplicable; OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; const double* pValue = rxvalue_cast(&value); if (!pValue) return eNotThatKindOfClass; matData->setYScale(*pValue); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dScaleZProperty::subGetValue(const OdRxObject* pO, OdRxValue& value) const { const OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; const OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; value = matData->getZScale(); return eOk; } //================================================================================================== OdResult OdDgMatrixTransform3dScaleZProperty::subSetValue(OdRxObject* pO, const OdRxValue& value) const { if (!pO) return eNotApplicable; OdRxValue* v = OdRxValue::unbox(pO); if (!v) return eNotApplicable; OdDgMatrixTransform3d* matData = rxvalue_cast(v); if (!matData) return eNotApplicable; const double* pValue = rxvalue_cast(&value); if (!pValue) return eNotThatKindOfClass; matData->setZScale(*pValue); return eOk; } //================================================================================================== void createOdDgMatrixTransform3dTypeProperties(OdRxMemberCollectionBuilder& b, void*) { b.add(OdDgMatrixTransform3dRotationXProperty::createObject(b.owner())); b.add(OdDgMatrixTransform3dRotationYProperty::createObject(b.owner())); b.add(OdDgMatrixTransform3dRotationZProperty::createObject(b.owner())); b.add(OdDgMatrixTransform3dScaleXProperty::createObject(b.owner())); b.add(OdDgMatrixTransform3dScaleYProperty::createObject(b.owner())); b.add(OdDgMatrixTransform3dScaleZProperty::createObject(b.owner())); } //================================================================================================== static OdRxValueTypePOD* m_gOdOdDgMatrixTransform3dType = 0; //================================================================================================== DGENT_EXPORT const OdRxValueType& OdRxValueType::Desc::value() throw() { if (m_gOdOdDgMatrixTransform3dType == 0) { m_gOdOdDgMatrixTransform3dType = new OdRxValueTypePOD(L"OdDgMatrixTransform3d", createOdDgMatrixTransform3dTypeProperties); m_gOdOdDgMatrixTransform3dType->attributes().add(OdRxTypePromotionAttribute::createObject(L"RotationX;RotationY;RotationZ;ScaleX;ScaleY;ScaleZ")); } return *m_gOdOdDgMatrixTransform3dType; } //================================================================================================== DGENT_EXPORT void OdRxValueType::Desc::del() { if (m_gOdOdDgMatrixTransform3dType) { ::odrxClassDictionary()->remove(L"OdDgMatrixTransform3d"); delete m_gOdOdDgMatrixTransform3dType; m_gOdOdDgMatrixTransform3dType = 0; } } //================================================================================================== template<> DGENT_EXPORT bool OdRxValueTypePOD::subEqualTo(const void* a, const void* b) const { OdDgMatrixTransform3d* pMat1 = (OdDgMatrixTransform3d*)a; OdDgMatrixTransform3d* pMat2 = (OdDgMatrixTransform3d*)b; if (!OdEqual(pMat1->getXAngle(), pMat2->getXAngle())) return false; if (!OdEqual(pMat1->getYAngle(), pMat2->getYAngle())) return false; if (!OdEqual(pMat1->getZAngle(), pMat2->getZAngle())) return false; if (!OdEqual(pMat1->getXScale(), pMat2->getXScale())) return false; if (!OdEqual(pMat1->getYScale(), pMat2->getYScale())) return false; if (!OdEqual(pMat1->getZScale(), pMat2->getZScale())) return false; return true; } //================================================================================================== template<> DGENT_EXPORT OdRxValue::OdRxValue(const OdDgMatrixTransform3d & val) throw() : m_type(OdRxValueType::Desc::value()) { initBlittable(&val, sizeof(OdDgMatrixTransform3d)); } template<> DGENT_EXPORT OdString OdRxValueTypePOD::subToString(const void* instance, OdRxValueType::StringFormat) const { if (!instance) throw OdError(L"Empty value instance"); OdDgMatrixTransform3d* pMat = (OdDgMatrixTransform3d*)instance; return OdString().format(L"Rotation - ( X = %g, Y = %g, Z = %g), Scale - ( X = %g, Y = %g, Z = %g)", pMat->getXAngle(), pMat->getYAngle(), pMat->getZAngle(), pMat->getXScale(), pMat->getYScale(), pMat->getZScale()); } //==================================================================================================