/////////////////////////////////////////////////////////////////////////////// // 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 "StdAfx.h" #include "DgAutoplantConeImpl.h" #include "DgAutoplantCone.h" #include "DgFiler.h" #include "Dg3DObject.h" #include "DgEllipse.h" #include "DgLine.h" //---------------------------------------------------------- // // OdDgAutoplantConeImpl // //---------------------------------------------------------- OdDgAutoplantConeImpl::OdDgAutoplantConeImpl() { m_ptCenter1 = OdGePoint3d::kOrigin; m_ptCenter2 = OdGePoint3d::kOrigin; m_vrOffset = OdGeVector3d::kIdentity; m_dRadius1 = 1.0; m_dRadius2 = 1.0; m_dStartData = 0.0; m_uFlags = 0x0003; } //---------------------------------------------------------- OdDgAutoplantConeImpl::~OdDgAutoplantConeImpl() { m_pCacheElement = 0; m_pCapElement = 0; } //---------------------------------------------------------- OdResult OdDgAutoplantConeImpl::dgnInFields(OdDgFiler* pFiler) { m_dStartData = pFiler->rdDouble(); ODA_ASSERT_ONCE(OdZero(m_dStartData)); m_ptCenter1 = pFiler->rdPoint3d(); m_ptCenter2 = pFiler->rdPoint3d(); m_vrOffset = pFiler->rdVector3d(); m_dRadius1 = pFiler->rdDouble(); m_dRadius2 = pFiler->rdDouble(); m_uFlags = pFiler->rdInt64(); m_pCacheElement = 0; return eOk; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::dgnOutFields(OdDgFiler* pFiler) const { pFiler->wrDouble(m_dStartData); pFiler->wrPoint3d(m_ptCenter1); pFiler->wrPoint3d(m_ptCenter2); pFiler->wrVector3d(m_vrOffset); pFiler->wrDouble(m_dRadius1); pFiler->wrDouble(m_dRadius2); pFiler->wrInt64(m_uFlags); } //---------------------------------------------------------- void OdDgAutoplantConeImpl::scaleData(double dScale) { m_ptCenter1 *= dScale; m_ptCenter2 *= dScale; m_vrOffset *= dScale; m_dRadius1 *= dScale; m_dRadius2 *= dScale; if( !m_pCacheElement.isNull() ) m_pCacheElement->transformBy(OdGeMatrix3d::scaling(dScale)); if( !m_pCapElement.isNull() ) m_pCapElement->transformBy(OdGeMatrix3d::scaling(dScale)); } //---------------------------------------------------------- void OdDgAutoplantConeImpl::updateConeElement(const OdDgAutoplantCone* pElm) { if (m_pCacheElement) { m_pCacheElement = 0; m_pCapElement = 0; } if( m_vrOffset.isZeroLength() ) { OdDgConePtr pCone = OdDgCone::createObject(); pCone->setCenter1(m_ptCenter1); OdGePoint3d ptEnd = m_ptCenter2; pCone->setCenter2(ptEnd); OdGeVector3d vrZ = m_ptCenter2 - m_ptCenter1; if (vrZ.isZeroLength()) vrZ = OdGeVector3d::kZAxis; else vrZ.normalize(); OdGeVector3d vrX = vrZ.perpVector(); OdGeVector3d vrY = vrZ.crossProduct(vrX); OdGeMatrix3d matRotation; matRotation.setCoordSystem(OdGePoint3d::kOrigin, vrX, vrY, vrZ); matRotation.transposeIt(); OdGeQuaternion quatRot; quatRot.set(matRotation); pCone->setRotation(quatRot); pCone->setRadius1(m_dRadius1); pCone->setRadius2(m_dRadius2); pCone->setPropertiesFrom(pElm); pCone->setMaterial(pElm->getMaterial()); pCone->setSolid(pElm->getDrawStartCapFlag() && pElm->getDrawEndCapFlag()); m_pCacheElement = pCone; if( !pCone->isSolid() ) { if (pElm->getDrawStartCapFlag()) { m_pCapElement = OdDgEllipse3d::createObject(); m_pCapElement->setOrigin(m_ptCenter1); m_pCapElement->setRotation(quatRot); m_pCapElement->setPrimaryAxis(m_dRadius1); m_pCapElement->setSecondaryAxis(m_dRadius1); m_pCapElement->setPropertiesFrom(pElm); m_pCapElement->setMaterial(pElm->getMaterial()); } else if (pElm->getDrawEndCapFlag()) { m_pCapElement = OdDgEllipse3d::createObject(); m_pCapElement->setOrigin(m_ptCenter2); m_pCapElement->setRotation(quatRot); m_pCapElement->setPrimaryAxis(m_dRadius2); m_pCapElement->setSecondaryAxis(m_dRadius2); m_pCapElement->setPropertiesFrom(pElm); m_pCapElement->setMaterial(pElm->getMaterial()); } } } else { OdDgGraphicsElementPtr pConeElm; if( pElm->getDrawStartCapFlag() && pElm->getDrawEndCapFlag() ) { OdDgSolidPtr pCone = OdDgSolid::createObject(); pCone->setType(OdDgSolid::kSolidProjection); pConeElm = pCone; } else { OdDgSurfacePtr pCone = OdDgSurface::createObject(); pCone->setType(OdDgSurface::kSurfaceProjection); pConeElm = pCone; } OdDg3dObjectHelper helper(pConeElm); OdGeVector3d vrZ = m_ptCenter2 - m_ptCenter1; if (vrZ.isZeroLength()) vrZ = OdGeVector3d::kZAxis; else vrZ.normalize(); OdGeVector3d vrX = vrZ.perpVector(); OdGeVector3d vrY = vrZ.crossProduct(vrX); OdGeMatrix3d matRotation; matRotation.setCoordSystem(OdGePoint3d::kOrigin, vrX, vrY, vrZ); matRotation.transposeIt(); OdGeQuaternion quatRot; quatRot.set(matRotation); OdDgEllipse3dPtr pBaseEllipse = OdDgEllipse3d::createObject(); pBaseEllipse->setOrigin(m_ptCenter1); pBaseEllipse->setRotation(quatRot); pBaseEllipse->setPrimaryAxis(m_dRadius1); pBaseEllipse->setSecondaryAxis(m_dRadius1); pBaseEllipse->setClass(pElm->getClass()); helper.addToBoundary(pBaseEllipse); OdDgEllipse3dPtr pTopEllipse = OdDgEllipse3d::createObject(); pTopEllipse->setOrigin(m_ptCenter2 + m_vrOffset); pTopEllipse->setRotation(quatRot); pTopEllipse->setPrimaryAxis(m_dRadius2); pTopEllipse->setSecondaryAxis(m_dRadius2); pTopEllipse->setClass(pElm->getClass()); helper.addToBoundary(pTopEllipse); OdGeVector3d vrXRefBase = vrZ.perpVector() * m_dRadius1; OdGeVector3d vrXRefTop = vrZ.perpVector() * m_dRadius2; for (OdUInt32 i = 0; i < 6; i++) { OdGePoint3d ptLineStart = m_ptCenter1 + vrXRefBase; OdGePoint3d ptLineEnd = m_ptCenter2 + m_vrOffset + vrXRefTop; OdDgLine3dPtr pLineRule = OdDgLine3d::createObject(); pLineRule->setStartPoint(ptLineStart); pLineRule->setEndPoint(ptLineEnd); pLineRule->setClass(pElm->getClass() == OdDgGraphicsElement::kClassPrimary ? OdDgGraphicsElement::kClassPrimaryRule : OdDgGraphicsElement::kClassConstructionRule); helper.addToRule(pLineRule); vrXRefBase.rotateBy(OdaPI/3.0, vrZ); vrXRefTop.rotateBy(OdaPI/3.0, vrZ); } pConeElm->setPropertiesFrom(pElm, true); pConeElm->setMaterial(pElm->getMaterial()); m_pCacheElement = pConeElm; if( m_pCacheElement->isKindOf(OdDgSurface::desc()) ) { if (pElm->getDrawStartCapFlag()) { m_pCapElement = OdDgEllipse3d::createObject(); m_pCapElement->setOrigin(m_ptCenter1); m_pCapElement->setRotation(quatRot); m_pCapElement->setPrimaryAxis(m_dRadius1); m_pCapElement->setSecondaryAxis(m_dRadius1); m_pCapElement->setPropertiesFrom(pElm); m_pCapElement->setMaterial(pElm->getMaterial()); } else if (pElm->getDrawEndCapFlag()) { m_pCapElement = OdDgEllipse3d::createObject(); m_pCapElement->setOrigin(m_ptCenter2); m_pCapElement->setRotation(quatRot); m_pCapElement->setPrimaryAxis(m_dRadius2); m_pCapElement->setSecondaryAxis(m_dRadius2); m_pCapElement->setPropertiesFrom(pElm); m_pCapElement->setMaterial(pElm->getMaterial()); } } } } //---------------------------------------------------------- const OdDgGraphicsElement* OdDgAutoplantConeImpl::getConeElement(const OdDgAutoplantCone* pElm) const { if (m_pCacheElement.isNull()) { OdDgAutoplantConeImpl* pThis = const_cast(this); pThis->updateConeElement(pElm); } return m_pCacheElement.get(); } //---------------------------------------------------------- bool OdDgAutoplantConeImpl::subWorldDraw(OdGiWorldDraw* pWd, const OdDgAutoplantCone* pElm) const { const OdDgGraphicsElement* pCone = getConeElement(pElm); if (pCone) { if( !m_pCapElement.isNull() ) m_pCapElement->subWorldDraw(pWd); return pCone->subWorldDraw(pWd); } return true; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::subViewportDraw(OdGiViewportDraw *pVd, const OdDgAutoplantCone* pElm) const { const OdDgGraphicsElement* pCone = getConeElement(pElm); if (pCone) { if (!m_pCapElement.isNull()) m_pCapElement->subViewportDraw(pVd); pCone->subViewportDraw(pVd); } } //---------------------------------------------------------- OdResult OdDgAutoplantConeImpl::subGetGeomExtents(OdGeExtents3d& extents, const OdDgAutoplantCone* pElm) const { const OdDgGraphicsElement* pCone = getConeElement(pElm); if( pCone ) return pCone->subGetGeomExtents(extents); return eOk; } //---------------------------------------------------------- OdResult OdDgAutoplantConeImpl::subGetGeomExtents(const OdDgElementId& idView, OdGeExtents3d& extents, const OdDgAutoplantCone* pElm) const { const OdDgGraphicsElement* pCone = getConeElement(pElm); if (pCone) return pCone->subGetGeomExtents(idView, extents); return eOk; } //---------------------------------------------------------- OdResult OdDgAutoplantConeImpl::subExplode(OdRxObjectPtrArray& entitySet, const OdDgAutoplantCone* pElm) const { const OdDgGraphicsElement* pCone = getConeElement(pElm); if( pCone ) entitySet.append(pCone->clone()); if( !m_pCapElement.isNull() ) entitySet.append(m_pCapElement->clone()); return eOk; } //---------------------------------------------------------- OdResult OdDgAutoplantConeImpl::transformBy(const OdGeMatrix3d& xfm) { OdGeVector3d vrZ = m_ptCenter2 - m_ptCenter1; if (vrZ.isZeroLength()) vrZ = OdGeVector3d::kZAxis; else vrZ.normalize(); OdGePoint3d ptBaseRadius = m_ptCenter1 + vrZ.perpVector() * m_dRadius1; OdGePoint3d ptTopRadius = m_ptCenter2 + m_vrOffset + vrZ.perpVector() * m_dRadius2; m_ptCenter1.transformBy(xfm); m_ptCenter2.transformBy(xfm); ptBaseRadius.transformBy(xfm); ptTopRadius.transformBy(xfm); m_dRadius1 = ptBaseRadius.distanceTo(m_ptCenter1); m_dRadius2 = ptTopRadius.distanceTo(m_ptCenter2 + m_vrOffset); m_pCacheElement = 0; m_pCapElement = 0; return eOk; } //---------------------------------------------------------- OdGePoint3d OdDgAutoplantConeImpl::getCenter1() const { return m_ptCenter1; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::setCenter1(const OdGePoint3d& ptCenter) { m_ptCenter1 = ptCenter; m_pCacheElement = 0; m_pCapElement = 0; } //---------------------------------------------------------- OdGePoint3d OdDgAutoplantConeImpl::getCenter2() const { return m_ptCenter2; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::setCenter2(const OdGePoint3d& ptCenter) { m_ptCenter2 = ptCenter; m_pCacheElement = 0; m_pCapElement = 0; } //---------------------------------------------------------- OdGeVector3d OdDgAutoplantConeImpl::getCenter2Offset() const { return m_vrOffset; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::setCenter2Offset(const OdGeVector3d& vrOffset) { m_vrOffset = vrOffset; m_pCacheElement = 0; m_pCapElement = 0; } //---------------------------------------------------------- double OdDgAutoplantConeImpl::getRadius1() const { return m_dRadius1; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::setRadius1(double dRadius) { m_dRadius1 = dRadius; m_pCacheElement = 0; m_pCapElement = 0; } //---------------------------------------------------------- double OdDgAutoplantConeImpl::getRadius2() const { return m_dRadius2; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::setRadius2(double dRadius) { m_dRadius2 = dRadius; m_pCacheElement = 0; m_pCapElement = 0; } //---------------------------------------------------------- bool OdDgAutoplantConeImpl::getDrawStartCapFlag() const { return (m_uFlags & 0x1) ? true : false; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::setDrawStartCapFlag(bool bSet) { OdUInt64 uFlagMask = 0x1; if (!bSet) m_uFlags &= ~uFlagMask; else m_uFlags |= uFlagMask; m_pCacheElement = 0; m_pCapElement = 0; } //---------------------------------------------------------- bool OdDgAutoplantConeImpl::getDrawEndCapFlag() const { return (m_uFlags & 0x2) ? true : false; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::setDrawEndCapFlag(bool bSet) { OdUInt64 uFlagMask = 0x2; if (!bSet) m_uFlags &= ~uFlagMask; else m_uFlags |= uFlagMask; m_pCacheElement = 0; m_pCapElement = 0; } //---------------------------------------------------------- OdUInt64 OdDgAutoplantConeImpl::getFlags() const { return m_uFlags; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::setFlags(OdUInt64 uFlags) { m_uFlags = uFlags; } //---------------------------------------------------------- double OdDgAutoplantConeImpl::getStartData() const { return m_dStartData; } //---------------------------------------------------------- void OdDgAutoplantConeImpl::setStartData(double dStartData) { m_dStartData = dStartData; } //----------------------------------------------------------