/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2018, 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 Teigha(R) software pursuant to a license // agreement with Open Design Alliance. // Teigha(R) Copyright (C) 2002-2018 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 "RxModelTreeBaseNode.h" #include "RxValue.h" #include "RxValueTypeUtil.h" #include "RxMember.h" #include "RxObjectImpl.h" #include "RxAttribute.h" #include "RxSysRegistry.h" #include "RxModelTreeBaseNodeImpl.h" #include "RxProperty.h" ODRX_CONS_DEFINE_MEMBERS(OdRxModelTreeBaseNode, OdRxObject, RXIMPL_CONSTR) #define _GET_IMPL_ \ \ OdRxModelTreeBaseNodeImpl* pImpl = OdRxModelTreeBaseNodeImpl::getImpl(this); \ if (NULL == pImpl)\ { \ throw OdError(::eNullObjectPointer); \ } OdRxModelTreeBaseNode::OdRxModelTreeBaseNode() :m_pImpl(new OdRxModelTreeBaseNodeImpl) { } OdRxModelTreeBaseNode::OdRxModelTreeBaseNode(OdRxModelTreeBaseNodeImpl* impl) :m_pImpl(impl) { } OdRxModelTreeBaseNode::~OdRxModelTreeBaseNode() { delete m_pImpl; } OdString OdRxModelTreeBaseNode::getNodeName() const { _GET_IMPL_ return pImpl->getNodeName(); } OdUInt64 OdRxModelTreeBaseNode::getUniqueSourceID() const { _GET_IMPL_ return pImpl->getUniqueSourceID(); } HierarchyTreeObjectType OdRxModelTreeBaseNode::getNodeType() const { _GET_IMPL_ return pImpl->getNodeType(); } void OdRxModelTreeBaseNodeImpl::setNodeName(const OdString& name) { m_Name = name; } void OdRxModelTreeBaseNodeImpl::setUniqueSourceID(const OdUInt64 id) { m_UniqueSourceID = id; } void OdRxModelTreeBaseNodeImpl::setNodeType(const HierarchyTreeObjectType type) { m_NodeType = type; } OdRxModelTreeBaseNodePtrArray OdRxModelTreeBaseNode::getParents() const { _GET_IMPL_ return pImpl->getParents(); } OdRxModelTreeBaseNodePtrArray OdRxModelTreeBaseNode::getChildren() const { _GET_IMPL_ return pImpl->getChildren(); } OdArray OdRxModelTreeBaseNode::getProperties() const { _GET_IMPL_ return pImpl->getProperties(); } bool OdRxModelTreeBaseNode::addChild(OdRxModelTreeBaseNodePtr elem) { _GET_IMPL_ return pImpl->addChild(this, elem); } void OdRxModelTreeBaseNode::outFields(OdBaseHierarchyTreeFiler* pFiler) const { _GET_IMPL_ return pImpl->outFields(pFiler); } OdResult OdRxModelTreeBaseNode::inFields(OdBaseHierarchyTreeFiler* pFiler) { _GET_IMPL_ return pImpl->inFields(pFiler); } OdRxModelTreeBaseNodeImpl::OdRxModelTreeBaseNodeImpl() : m_UniqueSourceID(0) , m_NodeType(eDatabase) { } OdRxModelTreeBaseNodeImpl::~OdRxModelTreeBaseNodeImpl() { } OdString OdRxModelTreeBaseNodeImpl::getNodeName() const { return m_Name; } OdUInt64 OdRxModelTreeBaseNodeImpl::getUniqueSourceID() const { return m_UniqueSourceID; } HierarchyTreeObjectType OdRxModelTreeBaseNodeImpl::getNodeType() const { return m_NodeType; } OdRxModelTreeBaseNodePtrArray OdRxModelTreeBaseNodeImpl::getParents() const { return m_Parents; } OdRxModelTreeBaseNodePtrArray OdRxModelTreeBaseNodeImpl::getChildren() const { return m_Children; } bool findParent(const OdRxModelTreeBaseNodePtr current, const OdRxModelTreeBaseNodePtrArray& parents) { for (OdRxModelTreeBaseNodePtrArray::const_iterator it = parents.begin(); it != parents.end(); ++it) { if (current == *it) return true; OdRxModelTreeBaseNodePtrArray new_parents = (*it)->getParents(); if (findParent(current, new_parents)) return true; } return false; } bool OdRxModelTreeBaseNodeImpl::addChild(OdRxModelTreeBaseNode* parent, OdRxModelTreeBaseNodePtr child) { if (eDatabase == child->getNodeType()) return false; OdRxModelTreeBaseNodeImpl* pImpl = OdRxModelTreeBaseNodeImpl::getImpl(child); OdRxModelTreeBaseNodePtr pParent(parent); if (findParent(pParent, pImpl->m_Parents)) return false; m_Children.append(child); pImpl->m_Parents.append(pParent); return true; } #undef TYPE_CONTAINER #define TYPE_CONTAINER \ VARTYPE(String )\ VARTYPE(Bool )\ VARTYPE(Int8 )\ VARTYPE(Int16 )\ VARTYPE(Int32 )\ VARTYPE(Int64 )\ VARTYPE(Double )\ VARTYPE(GePoint2d )\ VARTYPE(GePoint3d )\ VARTYPE(GeVector2d )\ VARTYPE(GeVector3d )\ VARTYPE(CmEntityColor )\ VARTYPE(CmTransparency ) #define ODTYPE(Type) Od##Type void OdRxModelTreeBaseNodeImpl::serializeProprties(OdBaseHierarchyTreeFiler* pFiler, const PropertyInfo& info) const { pFiler->wrString(info.name); pFiler->wrString(info.localizedName); pFiler->wrString(info.uiPlacement); pFiler->wrDouble(info.weight); pFiler->wrInt64(info.value.varType()); switch (info.value.varType()) { #undef VARTYPE #define VARTYPE(Type) \ case OdRxPropertyVariant::k##Type:\ pFiler->wr##Type(info.value.get##Type());\ break; TYPE_CONTAINER #undef VARTYPE #define VARTYPE(Type) \ case OdRxPropertyVariant::k##Type | OdVariant::kArray:\ {\ const Od##Type##Array& array = info.value.get##Type##Array();\ const OdInt64 array_size = array.size();\ pFiler->wrInt64(array_size);\ for (OdInt64 i = 0; i < array_size; ++i)\ {\ pFiler->wr##Type(array[i]);\ }\ }\ break; TYPE_CONTAINER } const OdUInt64 prop_count = info.subProperties.size(); pFiler->wrUInt64(prop_count); for (OdUInt64 i = 0; i < prop_count; ++i) { serializeProprties(pFiler, info.subProperties[i]); } } void OdRxModelTreeBaseNodeImpl::outFields(OdBaseHierarchyTreeFiler* pFiler) const { pFiler->wrUInt8((OdUInt8)eCURRENT); pFiler->wrUInt8((OdUInt8)getNodeType()); pFiler->wrInt64(getUniqueSourceID()); pFiler->wrString(getNodeName()); const OdUInt64 prop_count = m_Properties.size(); pFiler->wrUInt64(prop_count); for (OdUInt64 i = 0; i < prop_count; ++i) { serializeProprties(pFiler, m_Properties[i]); } } void OdRxModelTreeBaseNodeImpl::deserializeProprties(OdBaseHierarchyTreeFiler* pFiler, PropertyInfo& info) { info.name = pFiler->rdString(); info.localizedName = pFiler->rdString(); info.uiPlacement = pFiler->rdString(); info.weight = pFiler->rdDouble(); OdUInt64 vale_type = pFiler->rdInt64(); switch (vale_type) { #undef VARTYPE #define VARTYPE(Type) \ case OdRxPropertyVariant::k##Type:\ info.value = pFiler->rd##Type();\ break; TYPE_CONTAINER #undef VARTYPE #define VARTYPE(Type) \ case OdRxPropertyVariant::k##Type | OdVariant::kArray:\ {\ const OdInt64 array_size = pFiler->rdInt64();\ Od##Type##Array& array = info.value.as##Type##Array();\ array.resize(array_size);\ for (OdInt64 i = 0; i < array_size; ++i)\ {\ array[i] = pFiler->rd##Type();\ }\ }\ break; TYPE_CONTAINER } OdUInt64 prop_count = pFiler->rdUInt64(); info.subProperties.resize(prop_count); for (OdUInt64 i = 0; i < prop_count; ++i) { deserializeProprties(pFiler, info.subProperties[i]); } } OdResult OdRxModelTreeBaseNodeImpl::inFields(OdBaseHierarchyTreeFiler* pFiler) { HierarchyTreeVersion version = (HierarchyTreeVersion)pFiler->rdUInt8(); m_NodeType = (HierarchyTreeObjectType)pFiler->rdUInt8(); m_UniqueSourceID = pFiler->rdInt64(); m_Name = pFiler->rdString(); if (version > eHT1) { OdUInt64 prop_count = pFiler->rdUInt64(); m_Properties.resize(prop_count); for (OdUInt64 i = 0; i < prop_count; ++i) { deserializeProprties(pFiler, m_Properties[i]); } } return eOk; } OdArray OdRxModelTreeBaseNodeImpl::getProperties() const { return m_Properties; } void OdRxModelTreeBaseNodeImpl::addProperty(PropertyInfo& info) { m_Properties.append(info); }