/////////////////////////////////////////////////////////////////////////////// // 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 "DgAutoplantBoxImpl.h" #include "DgAutoplantBox.h" #include "DgFiler.h" #include "Dg3DObject.h" #include "DgShape.h" #include "DgLine.h" //---------------------------------------------------------- // // OdDgAutoplantBoxImpl // //---------------------------------------------------------- OdDgAutoplantBoxImpl::OdDgAutoplantBoxImpl() { m_dStartData = 0.0; m_uFlags = 0; m_dBaseWidth = 1.0; m_dBaseLength = 1.0; m_dTopWidth = 1.0; m_dTopLength = 1.0; m_vrSideDirection = OdGeVector3d::kZAxis; m_ptBase = OdGePoint3d::kOrigin; m_ptTop = OdGePoint3d(0.0,0.0,1.0); m_vrOffset = OdGeVector3d::kIdentity; } //---------------------------------------------------------- OdDgAutoplantBoxImpl::~OdDgAutoplantBoxImpl() { m_pCacheElement = 0; } //---------------------------------------------------------- OdResult OdDgAutoplantBoxImpl::dgnInFields(OdDgFiler* pFiler) { m_dStartData = pFiler->rdDouble(); ODA_ASSERT_ONCE(OdZero(m_dStartData)); m_dBaseWidth = pFiler->rdDouble(); m_dBaseLength = pFiler->rdDouble(); m_dTopWidth = pFiler->rdDouble(); m_dTopLength = pFiler->rdDouble(); m_vrSideDirection = pFiler->rdVector3d(); m_ptTop = pFiler->rdPoint3d(); m_ptBase = pFiler->rdPoint3d(); m_vrOffset = pFiler->rdVector3d(); m_uFlags = pFiler->rdInt64(); m_pCacheElement = 0; return eOk; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::dgnOutFields(OdDgFiler* pFiler) const { pFiler->wrDouble(m_dStartData); pFiler->wrDouble(m_dBaseWidth); pFiler->wrDouble(m_dBaseLength); pFiler->wrDouble(m_dTopWidth); pFiler->wrDouble(m_dTopLength); pFiler->wrVector3d(m_vrSideDirection); pFiler->wrPoint3d(m_ptTop); pFiler->wrPoint3d(m_ptBase); pFiler->wrVector3d(m_vrOffset); pFiler->wrInt64(m_uFlags); } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::scaleData(double dScale) { m_dBaseWidth *= dScale; m_dBaseLength *= dScale; m_dTopWidth *= dScale; m_dTopLength *= dScale; m_vrSideDirection *= dScale; m_ptBase *= dScale; m_ptTop *= dScale; m_vrOffset *= dScale; if( !m_pCacheElement.isNull() ) m_pCacheElement->transformBy(OdGeMatrix3d::scaling(dScale)); } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::updateCachedElement(const OdDgAutoplantBox* pElm) { if (m_pCacheElement) m_pCacheElement = 0; OdDgSolidPtr pBox = OdDgSolid::createObject(); pBox->setType(OdDgSolid::kSolidProjection); OdDg3dObjectHelper helper(pBox); OdGeVector3d vrZDir = m_ptTop - m_ptBase; if (vrZDir.isZeroLength()) vrZDir = OdGeVector3d::kZAxis; else vrZDir.normalize(); OdGeVector3d vrDir = m_vrSideDirection; if (vrDir.isZeroLength()) vrDir = OdGeVector3d::kXAxis; else vrDir.normalize(); if (vrDir.isParallelTo(vrZDir)) vrZDir = vrDir.perpVector(); OdGeVector3d vrYDir = vrZDir.crossProduct(vrDir); if (vrYDir.isZeroLength()) vrYDir = OdGeVector3d::kYAxis; else vrYDir.normalize(); OdDgShape3dPtr pBaseShape = OdDgShape3d::createObject(); pBaseShape->addVertex(m_ptBase + vrDir * m_dBaseWidth / 2.0 + vrYDir * m_dBaseLength / 2.0); pBaseShape->addVertex(m_ptBase + vrDir * m_dBaseWidth / 2.0 - vrYDir * m_dBaseLength / 2.0); pBaseShape->addVertex(m_ptBase - vrDir * m_dBaseWidth / 2.0 - vrYDir * m_dBaseLength / 2.0); pBaseShape->addVertex(m_ptBase - vrDir * m_dBaseWidth / 2.0 + vrYDir * m_dBaseLength / 2.0); pBaseShape->addVertex(m_ptBase + vrDir * m_dBaseWidth / 2.0 + vrYDir * m_dBaseLength / 2.0); pBaseShape->setClass(pElm->getClass()); helper.addToBoundary(pBaseShape); OdDgShape3dPtr pTopShape = OdDgShape3d::createObject(); pTopShape->addVertex(m_ptTop + m_vrOffset + vrDir * m_dTopWidth / 2.0 + vrYDir * m_dTopLength / 2.0); pTopShape->addVertex(m_ptTop + m_vrOffset + vrDir * m_dTopWidth / 2.0 - vrYDir * m_dTopLength / 2.0); pTopShape->addVertex(m_ptTop + m_vrOffset - vrDir * m_dTopWidth / 2.0 - vrYDir * m_dTopLength / 2.0); pTopShape->addVertex(m_ptTop + m_vrOffset - vrDir * m_dTopWidth / 2.0 + vrYDir * m_dTopLength / 2.0); pTopShape->addVertex(m_ptTop + m_vrOffset + vrDir * m_dTopWidth / 2.0 + vrYDir * m_dTopLength / 2.0); pTopShape->setClass(pElm->getClass()); helper.addToBoundary(pTopShape); for (OdUInt32 i = 0; i < 4; i++) { OdGePoint3d ptLineStart = pBaseShape->getVertexAt(i); OdGePoint3d ptLineEnd = pTopShape->getVertexAt(i); OdDgLine3dPtr pLineRule = OdDgLine3d::createObject(); pLineRule->setStartPoint(ptLineStart); pLineRule->setEndPoint(ptLineEnd); pLineRule->setClass(pElm->getClass() == OdDgGraphicsElement::kClassPrimary ? OdDgGraphicsElement::kClassPrimaryRule : OdDgGraphicsElement::kClassConstructionRule); helper.addToRule(pLineRule); } pBox->setPropertiesFrom(pElm, true); pBox->setMaterial(pElm->getMaterial()); m_pCacheElement = pBox; } //---------------------------------------------------------- const OdDgGraphicsElement* OdDgAutoplantBoxImpl::getCachedElement(const OdDgAutoplantBox* pElm) const { if (m_pCacheElement.isNull()) { OdDgAutoplantBoxImpl* pThis = const_cast(this); pThis->updateCachedElement(pElm); } return m_pCacheElement.get(); } //---------------------------------------------------------- bool OdDgAutoplantBoxImpl::subWorldDraw(OdGiWorldDraw* pWd, const OdDgAutoplantBox* pElm) const { const OdDgGraphicsElement* pCache = getCachedElement(pElm); if (pCache) return pCache->subWorldDraw(pWd); return true; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::subViewportDraw(OdGiViewportDraw *pVd, const OdDgAutoplantBox* pElm) const { const OdDgGraphicsElement* pCache = getCachedElement(pElm); if(pCache) pCache->subViewportDraw(pVd); } //---------------------------------------------------------- OdResult OdDgAutoplantBoxImpl::subGetGeomExtents(OdGeExtents3d& extents, const OdDgAutoplantBox* pElm) const { const OdDgGraphicsElement* pCache = getCachedElement(pElm); if(pCache) return pCache->subGetGeomExtents(extents); return eOk; } //---------------------------------------------------------- OdResult OdDgAutoplantBoxImpl::subGetGeomExtents(const OdDgElementId& idView, OdGeExtents3d& extents, const OdDgAutoplantBox* pElm) const { const OdDgGraphicsElement* pCache = getCachedElement(pElm); if (pCache) return pCache->subGetGeomExtents(idView, extents); return eOk; } //---------------------------------------------------------- OdResult OdDgAutoplantBoxImpl::subExplode(OdRxObjectPtrArray& entitySet, const OdDgAutoplantBox* pElm) const { const OdDgGraphicsElement* pCache = getCachedElement(pElm); if(pCache) entitySet.append(pCache->clone()); return eOk; } //---------------------------------------------------------- OdResult OdDgAutoplantBoxImpl::transformBy(const OdGeMatrix3d& xfm) { OdGeVector3d vrZDir = m_ptTop - m_ptBase; if (vrZDir.isZeroLength()) vrZDir = OdGeVector3d::kZAxis; else vrZDir.normalize(); OdGeVector3d vrDir = m_vrSideDirection; if (vrDir.isZeroLength()) vrDir = OdGeVector3d::kXAxis; else vrDir.normalize(); if (vrDir.isParallelTo(vrZDir)) vrZDir = vrDir.perpVector(); OdGeVector3d vrYDir = vrZDir.crossProduct(vrDir); if (vrYDir.isZeroLength()) vrYDir = OdGeVector3d::kYAxis; else vrYDir.normalize(); OdGePoint3d ptBase = m_ptBase + vrDir * m_dBaseWidth / 2.0 + vrYDir * m_dBaseLength / 2.0; OdGePoint3d ptBaseLength = m_ptBase + vrDir * m_dBaseWidth / 2.0 - vrYDir * m_dBaseLength / 2.0; OdGePoint3d ptBaseWidth = m_ptBase - vrDir * m_dBaseWidth / 2.0 + vrYDir * m_dBaseLength / 2.0; OdGePoint3d ptTop = m_ptTop + vrDir * m_dTopWidth / 2.0 + vrYDir * m_dTopLength / 2.0; OdGePoint3d ptTopLength = m_ptTop + vrDir * m_dTopWidth / 2.0 - vrYDir * m_dTopLength / 2.0; OdGePoint3d ptTopWidth = m_ptTop - vrDir * m_dTopWidth / 2.0 + vrYDir * m_dTopLength / 2.0; m_ptBase.transformBy(xfm); m_ptTop.transformBy(xfm); m_vrSideDirection.transformBy(xfm); m_vrOffset.transformBy(xfm); ptBase.transformBy(xfm); ptBaseLength.transformBy(xfm); ptBaseWidth.transformBy(xfm); ptTop.transformBy(xfm); ptTopLength.transformBy(xfm); ptTopWidth.transformBy(xfm); m_dBaseLength = ptBase.distanceTo(ptBaseLength); m_dBaseWidth = ptBase.distanceTo(ptBaseWidth); m_dTopLength = ptTop.distanceTo(ptTopLength); m_dTopWidth = ptTop.distanceTo(ptTopWidth); m_pCacheElement = 0; return eOk; } //---------------------------------------------------------- OdGePoint3d OdDgAutoplantBoxImpl::getBaseCenter() const { return m_ptBase; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::setBaseCenter(const OdGePoint3d& ptCenter) { m_ptBase = ptCenter; m_pCacheElement = 0; } //---------------------------------------------------------- OdGePoint3d OdDgAutoplantBoxImpl::getTopCenter() const { return m_ptTop; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::setTopCenter(const OdGePoint3d& ptCenter) { m_ptTop = ptCenter; m_pCacheElement = 0; } //---------------------------------------------------------- OdGeVector3d OdDgAutoplantBoxImpl::getWidthDirection() const { return m_vrSideDirection; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::setWidthDirection(const OdGeVector3d& vrDirection) { m_vrSideDirection = vrDirection; m_pCacheElement = 0; } //---------------------------------------------------------- OdGeVector3d OdDgAutoplantBoxImpl::getTopCenterOffset() const { return m_vrOffset; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::setTopCenterOffset(const OdGeVector3d& vrOffset) { m_vrOffset = vrOffset; m_pCacheElement = 0; } //---------------------------------------------------------- double OdDgAutoplantBoxImpl::getBaseLength() const { return m_dBaseLength; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::setBaseLength(double dLength) { m_dBaseLength = dLength; m_pCacheElement = 0; } //---------------------------------------------------------- double OdDgAutoplantBoxImpl::getBaseWidth() const { return m_dBaseWidth; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::setBaseWidth(double dWidth) { m_dBaseWidth = dWidth; m_pCacheElement = 0; } //---------------------------------------------------------- double OdDgAutoplantBoxImpl::getTopLength() const { return m_dTopLength; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::setTopLength(double dLength) { m_dTopLength = dLength; m_pCacheElement = 0; } //---------------------------------------------------------- double OdDgAutoplantBoxImpl::getTopWidth() const { return m_dTopWidth; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::setTopWidth(double dWidth) { m_dTopWidth = dWidth; m_pCacheElement = 0; } //---------------------------------------------------------- OdUInt64 OdDgAutoplantBoxImpl::getFlags() const { return m_uFlags; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::setFlags(OdUInt64 uFlags) { m_uFlags = uFlags; } //---------------------------------------------------------- double OdDgAutoplantBoxImpl::getStartData() const { return m_dStartData; } //---------------------------------------------------------- void OdDgAutoplantBoxImpl::setStartData(double dStartData) { m_dStartData = dStartData; } //----------------------------------------------------------