/////////////////////////////////////////////////////////////////////////////// // 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. /////////////////////////////////////////////////////////////////////////////// // ODA Platform #include "OdaCommon.h" #include "RxDynamicModule.h" #include "RxVariantValue.h" #include "RxObject.h" #include "RxInit.h" #include "DynamicLinker.h" #include "TvFactory.h" #include "TvFilerTimer.h" #include "TvModuleNames.h" #include "TvDatabaseCleaner.h" #include "TvDatabaseUtils.h" #include "ColorMapping.h" #include "daiDeviationParams.h" #include "Qif2Visualize.h" #include "QifGiContext.h" #include "QifFile.h" #include "daiAggr/daiSet.h" #include "daiSettings.h" #include "daiError/daiErrorEvent.h" #include #include #include using namespace OdQif; using namespace QIF2Visualize; OdTv::Units getUnits(OdQifFilePtr pQifDatabase, double& addUnitCoefToMeters) { OdTv::Units tvUnits = OdTv::kMeters; addUnitCoefToMeters = 1.; OdQif::FileUnitsPtr fileUnits = pQifDatabase->fileUnits(); if (fileUnits) { OdQif::PrimaryUnitsPtr primaryUnits = fileUnits->primaryUnits(); if (primaryUnits) { OdQif::LinearUnitPtr linearUnit = primaryUnits->linearUnit(); if (linearUnit) { OdAnsiString SIUnitName = linearUnit->siUnitName(); SIUnitName.makeUpper(); OdAnsiString UnitName = linearUnit->unitName(); UnitName.makeUpper(); if (linearUnit->unitConversion()) { double factor = linearUnit->unitConversion()->factor(); double offset = linearUnit->unitConversion()->offset(); } if (UnitName == "MM") { tvUnits = OdTv::kMillimeters; } else if (UnitName == "M") { tvUnits = OdTv::kMeters; } else if (UnitName == "INCH") { tvUnits = OdTv::kInches; } else { ODA_FAIL_M_ONCE("Units not supported."); } } else { tvUnits = OdTv::kUserDefined; ODA_FAIL_M_ONCE("TODO: Other units processing."); } } } return tvUnits; } //***************************************************************************// // 'OdTvVisualizeQifFilerProperties' methods implementation //***************************************************************************// OdTvVisualizeQifFilerProperties::OdTvVisualizeQifFilerProperties() : m_flags(0) , m_pPalette(0) , m_pCallback(NULL) , m_minPerCircle(8) , m_maxPerCircle(128) , m_deviation(0.5) , m_modelerType(0) , m_brepToleranceType(0) , m_brepToleranceDynamic(0.0001) , m_brepToleranceStatic(0.01) , m_pHostAppProgressMeter(NULL) , m_customBgTypeValue(0) , m_envBackgroundParam (nullptr) , m_pInterruptCallback(0) { m_importRect.xmax = 1; m_importRect.xmin = 0; m_importRect.ymax = 0; m_importRect.ymin = 1; } OdRxDictionaryPtr OdTvVisualizeQifFilerProperties::createObject() { return OdRxObjectImpl::createObject(); } void OdTvVisualizeQifFilerProperties::setDefaultColor(OdIntPtr pDefColor) { ODCOLORREF* pColor = (ODCOLORREF*)(pDefColor); if (!pColor) { ODA_ASSERT(false); } m_defaultColor = *pColor; } OdIntPtr OdTvVisualizeQifFilerProperties::getDefaultColor() const { return (OdIntPtr)(&m_defaultColor); } void OdTvVisualizeQifFilerProperties::setPalette(OdIntPtr palette) { const ODCOLORREF* pPalette = (const ODCOLORREF*)(palette); m_pPalette = pPalette; } void OdTvVisualizeQifFilerProperties::setBgColor(OdIntPtr pDefColor) { ODCOLORREF* pColor = (ODCOLORREF*)(pDefColor); if (!pColor) { ODA_ASSERT(false); } m_bgColor = *pColor; } OdIntPtr OdTvVisualizeQifFilerProperties::getBgColor() const { return (OdIntPtr)(&m_bgColor); } OdIntPtr OdTvVisualizeQifFilerProperties::getPalette() const { return (OdIntPtr)(m_pPalette); } void OdTvVisualizeQifFilerProperties::setDeviation(double deviation) { m_deviation = deviation; } double OdTvVisualizeQifFilerProperties::getDeviation() const { return m_deviation; } void OdTvVisualizeQifFilerProperties::setMinPerCircle(OdUInt16 minPerCircle) { m_minPerCircle = minPerCircle; } OdUInt16 OdTvVisualizeQifFilerProperties::getMinPerCircle() const { return m_minPerCircle; } void OdTvVisualizeQifFilerProperties::setMaxPerCircle(OdUInt16 maxPerCircle) { m_maxPerCircle = maxPerCircle; } OdUInt16 OdTvVisualizeQifFilerProperties::getMaxPerCircle() const { return m_maxPerCircle; } OdUInt8 OdTvVisualizeQifFilerProperties::getModelerType() const { return m_modelerType; } void OdTvVisualizeQifFilerProperties::setModelerType(OdUInt8 type) { m_modelerType = type; } void OdTvVisualizeQifFilerProperties::setBrepToleranceType(OdUInt8 type) { m_brepToleranceType = type; } OdUInt8 OdTvVisualizeQifFilerProperties::getBrepToleranceType() const { return m_brepToleranceType; } void OdTvVisualizeQifFilerProperties::setBrepToleranceDynamic(double coef) { m_brepToleranceDynamic = coef; } double OdTvVisualizeQifFilerProperties::getBrepToleranceDynamic() const { return m_brepToleranceDynamic; } void OdTvVisualizeQifFilerProperties::setBrepToleranceStatic(double coef) { m_brepToleranceStatic = coef; } double OdTvVisualizeQifFilerProperties::getBrepToleranceStatic() const { return m_brepToleranceStatic; } void OdTvVisualizeQifFilerProperties::setHostAppProgressMeter(OdIntPtr pProgressMeter) { m_pHostAppProgressMeter = (OdTvHostAppProgressMeter*)pProgressMeter; } OdIntPtr OdTvVisualizeQifFilerProperties::getHostAppProgressMeter() const { return (OdIntPtr)m_pHostAppProgressMeter; } void OdTvVisualizeQifFilerProperties::setCustomBgTypeValue(OdInt16 customBgValue) { m_customBgTypeValue = customBgValue; } OdInt16 OdTvVisualizeQifFilerProperties::getCustomBgTypeValue() const { return m_customBgTypeValue; } void OdTvVisualizeQifFilerProperties::setEnvBackgroundParam(OdIntPtr envParam) { OdTvEnvBackgroundImportParameters* pEnvBackgroundParam = reinterpret_cast(envParam); if (!pEnvBackgroundParam) { ODA_ASSERT(false); } m_envBackgroundParam = pEnvBackgroundParam; } OdIntPtr OdTvVisualizeQifFilerProperties::getEnvBackgroundParam() const { return reinterpret_cast(m_envBackgroundParam); } void QIF2Visualize::OdTvVisualizeQifFilerProperties::setFeatureNominalsColor(OdIntPtr pDefColor) { ODCOLORREF* pColor = (ODCOLORREF*)(pDefColor); if (!pColor) { ODA_ASSERT(false); } m_featureNominalsColor = *pColor; } OdIntPtr QIF2Visualize::OdTvVisualizeQifFilerProperties::getFeatureNominalsColor() const { return (OdIntPtr)(&m_featureNominalsColor); } OdTvVisualizeQifFilerProperties::~OdTvVisualizeQifFilerProperties() { } namespace QIF2Visualize { ODRX_DECLARE_PROPERTY(Palette) ODRX_DECLARE_PROPERTY(DCRect) ODRX_DECLARE_PROPERTY(ObjectNaming) ODRX_DECLARE_PROPERTY(StoreSourceObjects) ODRX_DECLARE_PROPERTY(ClearEmptyObjects) ODRX_DECLARE_PROPERTY(RearrangeObjects) ODRX_DECLARE_PROPERTY(AppendTransform) ODRX_DECLARE_PROPERTY(FeedbackForChooseCallback) ODRX_DECLARE_PROPERTY(DefaultEntityColor) ODRX_DECLARE_PROPERTY(Deviation) ODRX_DECLARE_PROPERTY(MinPerCircle) ODRX_DECLARE_PROPERTY(MaxPerCircle) ODRX_DECLARE_PROPERTY(NeedCDATree) ODRX_DECLARE_PROPERTY(ModelerType) ODRX_DECLARE_PROPERTY(NeedCollectPropertiesInCDA) ODRX_DECLARE_PROPERTY(UseCustomBgColor) ODRX_DECLARE_PROPERTY(BgEntityColor) ODRX_DECLARE_PROPERTY(HostAppProgressMeter) ODRX_DECLARE_PROPERTY(IsLogOn) ODRX_DECLARE_PROPERTY(CalculateIsolines) ODRX_DECLARE_PROPERTY(CustomBgTypeValue) ODRX_DECLARE_PROPERTY(EnvBackgroundParam) ODRX_DECLARE_PROPERTY(InterruptCallback) ODRX_DECLARE_PROPERTY(BrepToleranceType) ODRX_DECLARE_PROPERTY(BrepToleranceDynamic) ODRX_DECLARE_PROPERTY(BrepToleranceStatic) ODRX_DECLARE_PROPERTY(NeedCDATreeFontSymbolsConversion) ODRX_DECLARE_PROPERTY(DrawWireframeOverShells) ODRX_DECLARE_PROPERTY(GeneratePmiFromProperties) ODRX_DECLARE_PROPERTY(PmiTextScale) ODRX_DECLARE_PROPERTY(VectorizeFeatureNominals) ODRX_DECLARE_PROPERTY(FeatureNominalsColor) ODRX_BEGIN_DYNAMIC_PROPERTY_MAP(OdTvVisualizeQifFilerProperties); ODRX_GENERATE_PROPERTY(Palette) ODRX_GENERATE_PROPERTY(DCRect) ODRX_GENERATE_PROPERTY(ObjectNaming) ODRX_GENERATE_PROPERTY(StoreSourceObjects) ODRX_GENERATE_PROPERTY(ClearEmptyObjects) ODRX_GENERATE_PROPERTY(RearrangeObjects) ODRX_GENERATE_PROPERTY(AppendTransform) ODRX_GENERATE_PROPERTY(FeedbackForChooseCallback) ODRX_GENERATE_PROPERTY(DefaultEntityColor) ODRX_GENERATE_PROPERTY(Deviation) ODRX_GENERATE_PROPERTY(MinPerCircle) ODRX_GENERATE_PROPERTY(MaxPerCircle) ODRX_GENERATE_PROPERTY(NeedCDATree) ODRX_GENERATE_PROPERTY(ModelerType) ODRX_GENERATE_PROPERTY(NeedCollectPropertiesInCDA) ODRX_GENERATE_PROPERTY(UseCustomBgColor) ODRX_GENERATE_PROPERTY(BgEntityColor) ODRX_GENERATE_PROPERTY(HostAppProgressMeter) ODRX_GENERATE_PROPERTY(IsLogOn) ODRX_GENERATE_PROPERTY(CalculateIsolines) ODRX_GENERATE_PROPERTY(CustomBgTypeValue) ODRX_GENERATE_PROPERTY(EnvBackgroundParam) ODRX_GENERATE_PROPERTY(InterruptCallback) ODRX_GENERATE_PROPERTY(BrepToleranceType) ODRX_GENERATE_PROPERTY(BrepToleranceDynamic) ODRX_GENERATE_PROPERTY(BrepToleranceStatic) ODRX_GENERATE_PROPERTY(NeedCDATreeFontSymbolsConversion) ODRX_GENERATE_PROPERTY(DrawWireframeOverShells) ODRX_GENERATE_PROPERTY(GeneratePmiFromProperties) ODRX_GENERATE_PROPERTY(PmiTextScale) ODRX_GENERATE_PROPERTY(VectorizeFeatureNominals) ODRX_GENERATE_PROPERTY(FeatureNominalsColor) ODRX_END_DYNAMIC_PROPERTY_MAP(OdTvVisualizeQifFilerProperties); ODRX_DEFINE_PROPERTY_METHODS(Palette, OdTvVisualizeQifFilerProperties, getPalette, setPalette, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(DCRect, OdTvVisualizeQifFilerProperties, getDCRect, setDCRect, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(ObjectNaming, OdTvVisualizeQifFilerProperties, getObjectNaming, setObjectNaming, getBool); ODRX_DEFINE_PROPERTY_METHODS(StoreSourceObjects, OdTvVisualizeQifFilerProperties, getStoreSourceObjects, setStoreSourceObjects, getBool); ODRX_DEFINE_PROPERTY_METHODS(ClearEmptyObjects, OdTvVisualizeQifFilerProperties, getClearEmptyObjects, setClearEmptyObjects, getBool); ODRX_DEFINE_PROPERTY_METHODS(RearrangeObjects, OdTvVisualizeQifFilerProperties, getRearrangeObjects, setRearrangeObjects, getBool); ODRX_DEFINE_PROPERTY_METHODS(AppendTransform, OdTvVisualizeQifFilerProperties, getAppendTransform, setAppendTransform, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(FeedbackForChooseCallback, OdTvVisualizeQifFilerProperties, getFeedbackForChooseCallback, setFeedbackForChooseCallback, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(InterruptCallback, OdTvVisualizeQifFilerProperties, getInterruptionCallback, setInterruptionCallback, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(DefaultEntityColor, OdTvVisualizeQifFilerProperties, getDefaultColor, setDefaultColor, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(Deviation, OdTvVisualizeQifFilerProperties, getDeviation, setDeviation, getDouble); ODRX_DEFINE_PROPERTY_METHODS(MinPerCircle, OdTvVisualizeQifFilerProperties, getMinPerCircle, setMinPerCircle, getIntPtr) ODRX_DEFINE_PROPERTY_METHODS(MaxPerCircle, OdTvVisualizeQifFilerProperties, getMaxPerCircle, setMaxPerCircle, getIntPtr) ODRX_DEFINE_PROPERTY_METHODS(NeedCDATree, OdTvVisualizeQifFilerProperties, getNeedCDATree, setNeedCDATree, getBool) ODRX_DEFINE_PROPERTY_METHODS(ModelerType, OdTvVisualizeQifFilerProperties, getModelerType, setModelerType, getIntPtr) ODRX_DEFINE_PROPERTY_METHODS(NeedCollectPropertiesInCDA, OdTvVisualizeQifFilerProperties, getNeedCollectPropertiesInCDA, setNeedCollectPropertiesInCDA, getBool); ODRX_DEFINE_PROPERTY_METHODS(UseCustomBgColor, OdTvVisualizeQifFilerProperties, getUseCustomBgColor, setUseCustomBgColor, getBool); ODRX_DEFINE_PROPERTY_METHODS(BgEntityColor, OdTvVisualizeQifFilerProperties, getBgColor, setBgColor, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(HostAppProgressMeter, OdTvVisualizeQifFilerProperties, getHostAppProgressMeter, setHostAppProgressMeter, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(IsLogOn, OdTvVisualizeQifFilerProperties, getIsLogOn, setIsLogOn, getBool); ODRX_DEFINE_PROPERTY_METHODS(CalculateIsolines, OdTvVisualizeQifFilerProperties, getCalculateIsolines, setCalculateIsolines, getBool); ODRX_DEFINE_PROPERTY_METHODS(CustomBgTypeValue, OdTvVisualizeQifFilerProperties, getCustomBgTypeValue, setCustomBgTypeValue, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(EnvBackgroundParam, OdTvVisualizeQifFilerProperties, getEnvBackgroundParam, setEnvBackgroundParam, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(BrepToleranceType, OdTvVisualizeQifFilerProperties, getBrepToleranceType, setBrepToleranceType, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(BrepToleranceDynamic, OdTvVisualizeQifFilerProperties, getBrepToleranceDynamic, setBrepToleranceDynamic, getDouble); ODRX_DEFINE_PROPERTY_METHODS(BrepToleranceStatic, OdTvVisualizeQifFilerProperties, getBrepToleranceStatic, setBrepToleranceStatic, getDouble); ODRX_DEFINE_PROPERTY_METHODS(NeedCDATreeFontSymbolsConversion, OdTvVisualizeQifFilerProperties, getNeedCDATreeFontSymbolsConversion, setNeedCDATreeFontSymbolsConversion, getBool); ODRX_DEFINE_PROPERTY_METHODS(DrawWireframeOverShells, OdTvVisualizeQifFilerProperties, getDrawWireframeOverShells, setDrawWireframeOverShells, getBool); ODRX_DEFINE_PROPERTY_METHODS(GeneratePmiFromProperties, OdTvVisualizeQifFilerProperties, getGeneratePmiFromProperties, setGeneratePmiFromProperties, getBool); ODRX_DEFINE_PROPERTY_METHODS(PmiTextScale, OdTvVisualizeQifFilerProperties, getPmiTextScale, setPmiTextScale, getDouble); ODRX_DEFINE_PROPERTY_METHODS(VectorizeFeatureNominals, OdTvVisualizeQifFilerProperties, getVectorizeFeatureNominals, setVectorizeFeatureNominals, getBool); ODRX_DEFINE_PROPERTY_METHODS(FeatureNominalsColor, OdTvVisualizeQifFilerProperties, getFeatureNominalsColor, setFeatureNominalsColor, getIntPtr); } void OdTvVisualizeQifFilerProperties::setDCRect(OdIntPtr rect) { OdTvDCRect* pRect = (OdTvDCRect*)(rect); if (!pRect) { ODA_ASSERT(false); } m_importRect = *pRect; } OdIntPtr OdTvVisualizeQifFilerProperties::getDCRect() const { return (OdIntPtr)(&m_importRect); } void OdTvVisualizeQifFilerProperties::setAppendTransform(OdIntPtr pTransform) { const OdTvMatrix* pAppendTransform = (const OdTvMatrix*)(pTransform); if (pAppendTransform) { m_appendTransform = *pAppendTransform; } else { m_appendTransform = OdTvMatrix::kIdentity; } } OdIntPtr OdTvVisualizeQifFilerProperties::getAppendTransform() const { return (OdIntPtr)(&m_appendTransform); } void OdTvVisualizeQifFilerProperties::setFeedbackForChooseCallback(OdIntPtr pCallback) { m_pCallback = (OdTvFeedbackForChooseCallback)pCallback; } OdIntPtr OdTvVisualizeQifFilerProperties::getFeedbackForChooseCallback() const { return (OdIntPtr)m_pCallback; } void OdTvVisualizeQifFilerProperties::setInterruptionCallback(OdIntPtr pInterrupt) { m_pInterruptCallback = (OdDAI::InterruptCallback)pInterrupt; } OdIntPtr OdTvVisualizeQifFilerProperties::getInterruptionCallback() const { return (OdIntPtr)m_pInterruptCallback; } //***************************************************************************// // 'OdTvVisualizeQifFiler' methods implementation //***************************************************************************// namespace { OdString extractFontSymbols(const OdString& input, OdQifHostAppServices* pAppServices) { OdString convertedText; static OdString fontName = OD_T("Y14.5M-2009"); const QifSpecSymbolDictionary* symbolMapping = pAppServices ? &pAppServices->getFontSpecSymbolMapping(fontName) : nullptr; if (symbolMapping == nullptr) { //Nothing to do.. ODA_FAIL_M_ONCE("Symbol mapping table is null."); return input; } bool bracketMode = false; OdString currentFragment; for (int charIndex = 0; charIndex < input.getLength(); ++charIndex) { if (input[charIndex] == '{') { ODA_ASSERT(bracketMode == false && "bad syntax"); bracketMode = true; if (currentFragment.isEmpty() == true) { continue; } convertedText += currentFragment; currentFragment.empty(); continue; } else if (input[charIndex] == '}') { ODA_ASSERT(bracketMode == true && "bad syntax"); bracketMode = false; if (currentFragment.isEmpty() == true) { continue; } auto symbolIterator = symbolMapping->find(currentFragment); currentFragment.empty(); if (symbolIterator == symbolMapping->end()) { ODA_FAIL_M_ONCE("Can not map current fragment into a symbol."); continue; } const auto& symbol = symbolIterator->second; if (symbol == OD_T("\n")) { convertedText += "..."; continue; } convertedText += symbol; continue; } currentFragment += input[charIndex]; } if (currentFragment.isEmpty() == false) { ODA_ASSERT(bracketMode == false); convertedText += currentFragment; } return convertedText; } } OdTvVisualizeQifFiler::OdTvVisualizeQifFiler() : m_properties(OdTvVisualizeQifFilerProperties::createObject()) { } int OdTvVisualizeQifFiler::getChoosedRepresentationContexts(OdQifFilePtr pQifFile, OdTvFilerFeedbackForChooseObject & filerFeedbackForChoose, bool& bCanceled) const { m_selContexts.clear(); OdDAI::ModelPtr pModel = pQifFile->getModel(); if (pModel.isNull()) { ODA_ASSERT_ONCE(pModel.get()); return -1; } // TODO: Should we show views separately? return -1; } OdTvDatabaseId OdTvVisualizeQifFiler::loadFrom(const OdString& filePath, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdStreamBufPtr pStreamBuf = odrxSystemServices()->createFile(filePath); if (pStreamBuf.isNull()) { if (rc) *rc = tvInvalidFilePath; return OdTvDatabaseId(); } return loadFrom(pStreamBuf, pProfileRes, rc); } void OdTvVisualizeQifFiler::createCommonDataAccessTree(OdTvDatabasePtr pTvDb, OdDbBaseDatabase *pDatabase, const OdString& strTreeName, const OdTvModelId& modelId /*= OdTvModelId()*/) const { OdQifFilePtr pQifFile = OdQifFile::cast(pDatabase); if (pQifFile.isNull()) { ODA_ASSERT_ONCE("Wrong database class!"); return; } OdDAI::ModelPtr pModel = pQifFile->getModel(); if (pModel.isNull()) { ODA_ASSERT_ONCE("Can not create CDA tree for empty QifFile!"); return; } ::odrxDynamicLinker()->loadModule(L"RxProperties"); //Create CDA tree OdTvCDATreePtr pTree = OdTvCDATree::createObject(); if (m_properties->getNeedCollectPropertiesInCDA()) pTree->createDatabaseHierarchyTree(pQifFile.get(), true); else { std::set props; props.insert(OdTvCDAPropNameForGrouping); pTree->createDatabaseHierarchyTree(pQifFile.get(), &props); } //Add tree to the Tv database OdTvResult rc; OdTvCDATreeStorageId cdaTreeId = pTvDb->addCDATreeStorage(strTreeName, pTree, &rc); if (rc == tvAlreadyExistSameName) { OdUInt32 i = 1; while (rc != tvOk && i < MAX_CDATREENAME_GENERATION_ATTEMPTS) { OdString str; str.format(L"%s_%d", strTreeName.c_str(), i++); //not to fast but it is not a "bottle neck" cdaTreeId = pTvDb->addCDATreeStorage(str, pTree, &rc); } } //Add new CDA tree to the appropriate models OdTvModelId curModel = modelId; if (curModel.isNull()) { OdTvModelsIteratorPtr modelsIterPtr = pTvDb->getModelsIterator(); if (!modelsIterPtr->done()) { curModel = modelsIterPtr->getModel(); OdTvModelPtr pModel = curModel.openObject(); if (!pModel.isNull()) pModel->setCDATreeStorage(cdaTreeId); } } else { OdTvModelPtr pModel = curModel.openObject(); pModel->setCDATreeStorage(cdaTreeId); } OdTvCDATreeNodePtr pTvNode = pTree->getDatabaseNode(); if (!pTvNode.isNull()) { const OdRxModelTreeBaseNodePtrArray& nodes = pTvNode->getChildren(); for (auto it = nodes.begin(); it != nodes.end(); ++it) { OdTvCDATreeNodePtr pNode = *it; if (pNode.isNull()) continue; pNode->setTvModelId(curModel); } } // formally it is not very fast function due to string comparison. But current implementation finds ONLY first occurrence of // object with Storeys Class Name. That's why currently it is fast enough OdRxModelTreeBaseNodePtr pDbNode = pTree->getDatabaseNode(); if (!pDbNode.isNull()) processCDANode(pDbNode.get(), NULL, m_properties->getNeedCDATreeFontSymbolsConversion() ? pQifFile->getAppServices() : nullptr); } bool OdTvVisualizeQifFiler::processCDANode(OdRxModelTreeBaseNode* pNode, OdRxModelTreeBaseNode* pParentNode, OdDAIHostAppServicesBase* pAppServices) const { if (!pNode) return true; if (pNode->getParents().size() > 1 && pNode->getParents().at(0) != pParentNode) return true; /*if (pParentNode) { OdTvCDATreeNodePtr pTvNode = dynamic_cast(pNode); OdTvCDATreeNodePtr pTvParentNode = dynamic_cast(pParentNode); if (!pTvNode.isNull() && !pTvParentNode.isNull()) { OdString strClassName = getClassNameProperty(pTvNode->getProperties()); if (!strClassName.isEmpty()) { strClassName = strClassName.right(strClassName.getLength() - strClassName.find(L":") - 2); if ( !strClassName.isEmpty() ) { bool bNeedGroup = (strClassName == "..."); if (bNeedGroup) { pTvParentNode->setNeedGroup(false); return false; } } } } }*/ if (OdTvCDATreeNodePtr pTvNode = dynamic_cast(pNode)) { pTvNode->setNeedGroup(false); pTvNode->setValidWithoutTv(true); if (pAppServices && pTvNode->getFontInfo()) { OdString extractedName = ::extractFontSymbols(pTvNode->getNodeName(), OdQifHostAppServices::cast(pAppServices)); if (extractedName == pTvNode->getNodeName()) pTvNode->setFontInfo(nullptr); else pTvNode->setNodeName(extractedName); } else if (pTvNode->getFontInfo()) { pTvNode->setFontInfo(nullptr); } } const OdRxModelTreeBaseNodePtrArray& children = pNode->getChildren(); if (children.isEmpty()) return true; for (auto it = children.begin(); it != children.end(); ++it) { if (!processCDANode( const_cast(it->get()), pNode, pAppServices)) return false; } return true; } OdString OdTvVisualizeQifFiler::getClassNameProperty(const OdArray& nodeProperties) const { if (nodeProperties.size() == 0) return OdString(); for (OdUInt32 i = 0; i < nodeProperties.size(); i++) { if (nodeProperties[i].name == OdTvCDAPropNameForGrouping) return nodeProperties[i].value.getString(); } return OdString(); } int OdTvVisualizeQifFiler::odSelectRepresentationContextsByDefault(OdDAI::ModelPtr pModel) const { return -1; } OdTvGsViewId OdTvVisualizeQifFiler::getActiveTvView(OdTvGsDeviceId& tvDeviceId, int iActViewViewInd) const { OdTvGsDevicePtr pTvDevice = tvDeviceId.openObject(); if (!pTvDevice.isNull()) { return pTvDevice->viewAt(iActViewViewInd); } return OdTvGsViewId(); } OdTvGsDeviceId OdTvVisualizeQifFiler::getActiveTvDevice(OdTvDatabaseId& tvDbId, int idDevice) const { OdTvDevicesIteratorPtr pDevicesIterator = tvDbId.openObject()->getDevicesIterator(); unsigned iDeviceInd = 0; if (!pDevicesIterator.isNull() && !pDevicesIterator->done()) { if (iDeviceInd == idDevice) return pDevicesIterator->getDevice(); pDevicesIterator->step(); } return OdTvGsDeviceId(); } OdTvModelId OdTvVisualizeQifFiler::import(OdTvDatabaseId &tvDbId, OdStreamBuf* pBuffer, OdQifFilePtr pQifFile, OdTvFilerTimeProfiling* pProfileRes /*= NULL*/, OdTvResult* rc /*= NULL*/) const { if (rc) *rc = tvOk; OdTvModelId idModel; OdString fileName; if (pBuffer) fileName = OdTvDatabaseUtils::getFileNameFromPath(pBuffer->fileName()); else if (!pQifFile.isNull()) fileName = OdTvDatabaseUtils::getFileNameFromPath(pQifFile->getFileName()); if (fileName.isEmpty()) fileName = OD_T("StreamBuffData"); OdString modelName; OdTvGsDeviceId activeTvGsDeviceId; bool bIsAppend = false; if (tvDbId.isNull()) { // // Create empty TV database. // OdTvFactoryId tvFactoryId = odTvGetFactory(); tvDbId = tvFactoryId.createDatabase(); OdTvDatabasePtr pTvDb = tvDbId.openObject(OdTv::kForWrite); } else { bIsAppend = true; // // Check that we are in the real append mode // { OdTvDatabasePtr pTvDb = tvDbId.openObject(); OdTvDevicesIteratorPtr devicesIteratorPtr = pTvDb->getDevicesIterator(); while (!devicesIteratorPtr->done()) { activeTvGsDeviceId = devicesIteratorPtr->getDevice(); if (activeTvGsDeviceId.openObject()->getActive()) break; devicesIteratorPtr->step(); } } modelName = OdTvDatabaseUtils::generateModelName(tvDbId, fileName); } // // Check if time profiling is needed // bool bUseTimeProfiling = false; if (pProfileRes) bUseTimeProfiling = true; double internalTiming = 0.; double externalTiming = 0.; double fileOpenTiming = 0.; double composeTiming = 0.; double contextSelectionTiming = 0.; double CDATiming = 0.; OdStaticRxObject svcs; // // Start total timing // OdTvFilerTimer timing(bUseTimeProfiling); timing.startTotal(); bool bActivated = !pQifFile.isNull(); if(!bActivated) { odQifInitialize(true, true); if (m_properties->getIsLogOn()) { OdDAI::SessionPtr pSession = oddaiSession(); if (pSession.isNull()) pSession = oddaiCreateSession(); pSession->startEventRecording(); } } else { odQifInitModelerGeometry(); } // // Store visualize device module name // OdString moduleName; try { // // Local smart pointer pQifDatabase, so we can release it and uninitialize QIF SDK if // pQifFilePtr wasn't provided, and QIF file should be loaded into this module. // OdQifFilePtr pQifDatabase = pQifFile; if (pQifDatabase.isNull() && pBuffer) { // // No OdQifFile provided, so file should be loaded and released in this module // OdDAI::Settings &setting = OdDAI::settings(); OdDbHostAppProgressMeter* pMeter = (OdDbHostAppProgressMeter*)m_properties->getHostAppProgressMeter(); if (pMeter) svcs.setProgressMeter(pMeter); timing.startMisc(); pQifDatabase = svcs.readFile(pBuffer); timing.endMisc(); fileOpenTiming = timing.getMiscTime(); } if (!pQifDatabase.isNull()) { // // Interrupt total timing for ask what representation contexts should be drawn // timing.startMisc(); OdTvFilerFeedbackForChooseObject filerFeedbackForChooseObject(OD_T("Geometric contexts for import")); bool bCanceled = false; OdQifModelContext& qifModelContext = pQifDatabase->getContext(); qifModelContext.setDrawWireframeOverShells(m_properties->getDrawWireframeOverShells()); qifModelContext.setGeneratePmiFromProperties(m_properties->getGeneratePmiFromProperties()); qifModelContext.setPmiTextScale(m_properties->getPmiTextScale()); qifModelContext.setVectorizeFeatureNominals(m_properties->getVectorizeFeatureNominals()); ODCOLORREF* pFeatureNominalsColor = (ODCOLORREF*)m_properties->getFeatureNominalsColor(); qifModelContext.setFeatureNominalsColor(OdCmEntityColor(ODGETRED(*pFeatureNominalsColor), ODGETGREEN(*pFeatureNominalsColor), ODGETBLUE(*pFeatureNominalsColor))); int nSelContexts = getChoosedRepresentationContexts(pQifDatabase, filerFeedbackForChooseObject, bCanceled); timing.endMisc(); if (bCanceled) { if (rc) *rc = tvFilerEmptyInternalDatabase; odTvGetFactory().removeDatabase(tvDbId); tvDbId.setNull(); pQifDatabase = nullptr; if(!bActivated) { // Uninitialize QIF modules odQifUninitialize(); } // Unload everything including Visualize device odrxDynamicLinker()->unloadUnreferenced(); return idModel; } contextSelectionTiming = timing.getMiscTime(); if (1) //nSelContexts >= 0) { // // Customize Model Context // // // Deviation params from properties // OdDeviationParams deviationParams(m_properties->getDeviation(), m_properties->getMinPerCircle(), m_properties->getMaxPerCircle()); qifModelContext.setDeviationParams(deviationParams); // // Brep params from properties // qifModelContext.setBrepParams(OdBrepParams(OdBrepParams::ToleranceType(m_properties->getBrepToleranceType()), m_properties->getBrepToleranceDynamic(), m_properties->getBrepToleranceStatic())); // // Textures support // //OdQifHostAppServices* pServices = pQifDatabase->getAppServices(); //if (pServices) // pServices->setTexturesVisibility(m_properties->getTexturesVisibility()); // // Default color from properties // ODCOLORREF* pDefColor = (ODCOLORREF*)m_properties->getDefaultColor(); OdUInt8 r, g, b; r = ODGETRED(*pDefColor); g = ODGETGREEN(*pDefColor); b = ODGETBLUE(*pDefColor); OdCmEntityColor color(r, g, b); qifModelContext.setDefaultEntityColor(color); // // Get units from QIF Document // double addUnitCoefToMeters; OdTv::Units tvUnits = getUnits(pQifDatabase, addUnitCoefToMeters); // // Geometry compose // timing.startMisc(); //pQifDatabase->setContextSelection(m_selContexts); qifModelContext.setInterruptCallback((OdDAI::InterruptCallback)m_properties->getInterruptionCallback()); // pQifDatabase->composeEntities(); timing.endMisc(); composeTiming = timing.getMiscTime(); OdTvQifPartialImportNotifier notifier; OdDbHostAppProgressMeter* pMeter = (OdDbHostAppProgressMeter*)m_properties->getHostAppProgressMeter(); if (pMeter) { pMeter->start(OD_T("Import starting...")); } notifier.setProgressMeter(pMeter); const OdDAI::SetOfOdDAIObjectId* products = pQifDatabase->getModel()->getEntityExtent("producttype"); notifier.setEntitiesCount(products->getMemberCount()); // 0 or 1? // // Vectorizing // timing.startVectorizing(); OdGsModulePtr pGs = ::odrxDynamicLinker()->loadModule(OdTvVisualizeDeviceModuleName, false); if (!pGs.isNull()) { moduleName = pGs->moduleName(); // // Create vectorizer device // OdGsDevicePtr pDevice = pGs->createDevice(); OdTvQifGeomertyNotifier geometryNotifier(tvDbId.openObject()); OdGiContextForQifDatabasePtr giGontextForQifDatabase = OdGiContextForQifDatabase::createObject(); giGontextForQifDatabase->setDatabase(pQifDatabase); giGontextForQifDatabase->enableGsModel(true); OdRxDictionaryPtr pProperties = pDevice->properties(); if (pProperties.get()) { if (pProperties->has(OD_T("DisplayViaGLES2"))) pProperties->putAt(OD_T("DisplayViaGLES2"), OdRxVariantValue(false)); if (pProperties->has(OD_T("AllowNonPersistentObjects"))) pProperties->putAt(OD_T("AllowNonPersistentObjects"), OdRxVariantValue(false)); #if !defined(__APPLE__) if (pProperties->has(OD_T("EnableTiming"))) pProperties->putAt(OD_T("EnableTiming"), OdRxVariantValue(bUseTimeProfiling)); #endif if (pProperties->has(OD_T("TvDatabaseID"))) pProperties->putAt(OD_T("TvDatabaseID"), OdRxVariantValue((OdIntPtr)(&tvDbId))); if (pProperties->has(OD_T("WriteUserData"))) pProperties->putAt(OD_T("WriteUserData"), OdRxVariantValue(true /*m_properties->getStoreSourceObjects()*/)); if (pProperties->has(OD_T("GenerateEntityNames"))) pProperties->putAt(OD_T("GenerateEntityNames"), OdRxVariantValue(true /*m_properties->getObjectNaming()*/)); if (pProperties->has(OD_T("CompareUnnamedImages"))) pProperties->putAt(OD_T("CompareUnnamedImages"), OdRxVariantValue(true)); if (pProperties->has(OD_T("CompareMaterialsForUniqueness"))) pProperties->putAt(OD_T("CompareMaterialsForUniqueness"), OdRxVariantValue(false)); if (!activeTvGsDeviceId.isNull()) { if (pProperties->has(OD_T("IgnoreFlags"))) pProperties->putAt(OD_T("IgnoreFlags"), OdRxVariantValue(OdUInt16(1)/*DeviceIgnoreFlags::kIgnoreViewInfoFlags*/)); if (pProperties->has(OD_T("ModelName"))) pProperties->putAt(OD_T("ModelName"), OdRxVariantValue(modelName)); if (pProperties->has(OD_T("NamePrefix"))) pProperties->putAt(OD_T("NamePrefix"), OdRxVariantValue(modelName)); if (pProperties->has(OD_T("TvDeviceDAM"))) pProperties->putAt(OD_T("TvDeviceDAM"), OdRxVariantValue((OdIntPtr)(&activeTvGsDeviceId))); OdTvGsViewId viewId = activeTvGsDeviceId.openObject()->getActiveView(); OdString name = viewId.openObject()->getName(); if (pProperties->has(OD_T("TvViewDAM"))) pProperties->putAt(OD_T("TvViewDAM"), OdRxVariantValue((OdIntPtr)(&viewId))); } if (bIsAppend) { if (pProperties->has(OD_T("DisableSettingExtents"))) pProperties->putAt(OD_T("DisableSettingExtents"), OdRxVariantValue(true)); } // put device notifier if (pProperties->has(OD_T("DeviceNotifier"))) { pProperties->putAt(OD_T("DeviceNotifier"), OdRxVariantValue((OdIntPtr)(¬ifier))); } if (pProperties->has(OD_T("GeometryNotifier"))) { pProperties->putAt(OD_T("GeometryNotifier"), OdRxVariantValue((OdIntPtr)(&geometryNotifier))); } } // // Setup the device and view // OdGsQifLayoutHelperPtr pLayoutHelper = OdQifGsManager::setupActiveLayoutViews(pDevice.get(), giGontextForQifDatabase); if (pLayoutHelper.isNull()) { throw OdError(eNullPtr); } pLayoutHelper->activeView()->setMode(OdGsView::kGouraudShaded); // // Set the palette // const ODCOLORREF* palette = (const ODCOLORREF*)m_properties->getPalette(); bool bDefaultPalette = false; if (palette == 0) { bDefaultPalette = true; palette = odcmAcadPalette(ODRGB(255, 255, 255)); } OdArray > pPalCpy; pPalCpy.insert(pPalCpy.begin(), palette, palette + 256); pDevice->setLogicalPalette(pPalCpy.asArrayPtr(), 256); pDevice->setBackgroundColor(ODRGB(192, 192, 192)); giGontextForQifDatabase->setPaletteBackground(ODRGB(192, 192, 192)); // // Call onsize // OdTvDCRect* pRect = (OdTvDCRect*)m_properties->getDCRect(); if (pRect && (pRect->xmax > 0 || pRect->xmin > 0 || pRect->ymax > 0 || pRect->ymin > 0)) { OdGsDCRect gsRect(pRect->xmin, pRect->xmax, pRect->ymin, pRect->ymax); pDevice->onSize(gsRect); } // // Call draw to the Visualize database // pLayoutHelper->update(); if (pProperties->has(OD_T("TvDatabaseID"))) tvDbId = *(OdTvDatabaseId*)OdRxVariantValue(pProperties->getAt(OD_T("TvDatabaseID")).get())->getIntPtr(); if (bUseTimeProfiling) { #if !defined(__APPLE__) if (pProperties->has(OD_T("TvElapsedTime"))) { internalTiming = OdRxVariantValue(pProperties->getAt(OD_T("TvElapsedTime")).get())->getDouble(); } #endif } // // Setup active view // timing.startMisc(); if (tvDbId.isValid()) { OdTvDatabasePtr pTvDb = tvDbId.openObject(OdTv::kForWrite); OdTvModelId tvCreatedModelId; if (activeTvGsDeviceId.isNull()) { int iActViewViewInd = getActiveViewId(pLayoutHelper.get()); if (iActViewViewInd >= 0) { //get current tv device OdTvGsDeviceId tvDeviceId = getActiveTvDevice(tvDbId, 0); OdTvGsViewId tvViewId = getActiveTvView(tvDeviceId, iActViewViewInd); if (!tvDeviceId.isNull() && !tvViewId.isNull()) { OdTvGsViewPtr pActiveTvView = tvViewId.openObject(OdTv::kForWrite); pActiveTvView->setActive(true); // mark other views sibling OdTvGsDevicePtr pTvDevice = tvDeviceId.openObject(OdTv::kForWrite); if (!pTvDevice.isNull()) { pTvDevice->setName(OD_T("QIF Document")); for (int i = 0; i < pTvDevice->numViews(); i++) { if (i != iActViewViewInd) continue; OdTvGsViewId viewId = pTvDevice->viewAt(i); if(viewId != tvViewId) pActiveTvView->addSibling(viewId); //set background int test = m_properties->getCustomBgTypeValue(); switch(static_cast(m_properties->getCustomBgTypeValue())) { case BackgroundType::kGradient: { OdTvGsViewBackgroundId bgId = pTvDb->createBackground(OD_T("QIF2VISUALIZE"), OdTvGsViewBackgroundId::kGradient); if (!bgId.isNull()) { OdTvGsViewGradientBackgroundPtr pGradientBackground = bgId.openAsGradientBackground(OdTv::kForWrite); pGradientBackground->setColorTop(OdTvColorDef(33, 108, 170)); pGradientBackground->setColorMiddle(OdTvColorDef(109, 158, 200)); pGradientBackground->setColorBottom(OdTvColorDef(184, 208, 230)); pGradientBackground->setHeight(0.33); pGradientBackground->setHorizon(0.5); } pActiveTvView->setBackground(bgId); break; } case BackgroundType::kColor: { ODCOLORREF* pBgColor = (ODCOLORREF*)m_properties->getBgColor(); pTvDevice->setBackgroundColor(*pBgColor); break; } case BackgroundType::kEnviroment: { OdTvEnvBackgroundImportParameters* envParam = reinterpret_cast(m_properties->getEnvBackgroundParam()); OdTvDatabasePtr pDb = tvDbId.openObject(OdTv::kForWrite); OdTvGsViewBackgroundId bgId = pDb->findBackground(envParam->getEnviromentType()); OdTvGsViewEnvironmentBackgroundPtr pBg; if (bgId.isNull() || bgId.getType() != OdTvGsViewBackgroundId::kEnvironment) { bgId = pDb->createBackground(envParam->getEnviromentType(), OdTvGsViewBackgroundId::kEnvironment); pBg = bgId.openAsEnvironmentBackground(OdTv::kForWrite); if (!envParam->getCustomCubic().isNull()) { pBg->setEnvironmentImage(envParam->getCustomCubic()); } else { pBg->setEnvironmentImageFileName(envParam->getEnviromentPath()); } } if(pBg.isNull()) pBg = bgId.openAsEnvironmentBackground(OdTv::kForWrite); pBg->setLongitude(envParam->getLongitude()); pBg->setLatitude(envParam->getLatitude()); pBg->setFovOverride(envParam->getAngleStatus(), envParam->getAngle()); pActiveTvView->setBackground(bgId); break; } default: { ODA_FAIL_M_ONCE("Qif2Visualize background type not implemented"); break; } } //set more lighting pActiveTvView->setDefaultLightingIntensity(1.25); // Zoom to extents OdTvPoint minPt, maxPt; pActiveTvView->zoomExtents(minPt, maxPt); } } } } // // Store filename to database user data // OdTvDatabaseUtils::writeFileNameToTvDatabase(tvDbId, fileName); // // Rename the model (here we suppose that database contain only one model) // OdTvModelsIteratorPtr pModelsIterator = pTvDb->getModelsIterator(); if (!pModelsIterator.isNull() && !pModelsIterator->done()) { OdTvModelId modelId = pModelsIterator->getModel(); OdTvModelPtr pIvModel = modelId.openObject(OdTv::kForWrite); if (!pIvModel.isNull()) { tvCreatedModelId = modelId; pIvModel->setName(fileName); OdTvSelectabilityDef selectability; selectability.setGeometries(true); pIvModel->setSelectability(selectability, true); //set units pIvModel->setUnits(tvUnits, tvUnits == OdTv::kUserDefined ? addUnitCoefToMeters : 1.); //calculate isolines if need if (m_properties->getCalculateIsolines()) { OdTvEntitiesIteratorPtr pEntitiesIterator = pIvModel->getEntitiesIterator(); while (!pEntitiesIterator->done()) { OdTvEntityId entityId = pEntitiesIterator->getEntity(); if (entityId.getType() == OdTvEntityId::kEntity) { OdTvEntityPtr pEntity = entityId.openObject(OdTv::kForWrite); if (!pEntity.isNull()) pEntity->setCalculateIsolinesForShells(true, 89.0 * OdaPI / 180.0, false); } pEntitiesIterator->step(); } } } } if (m_properties->getNeedCDATree()) { OdPerfTimerBase* pCDATiming = OdPerfTimerBase::createTiming(); pCDATiming->start(); createCommonDataAccessTree(pTvDb, pQifDatabase, fileName + OD_T(".qif")); pCDATiming->stop(); CDATiming += pCDATiming->countedSec(); if (pProfileRes) pProfileRes->setCDATreeCreationTime(OdInt64((CDATiming) * 1000.)); delete pCDATiming; } } else { idModel = pTvDb->findModel(modelName); OdTvModelPtr pTvModel = idModel.openObject(OdTv::kForWrite); if ( !pTvModel.isNull() ) { tvCreatedModelId = idModel; OdTvSelectabilityDef selectability; selectability.setGeometries(true); pTvModel->setSelectability(selectability, true); //set units pTvModel->setUnits(tvUnits, tvUnits == OdTv::kUserDefined ? addUnitCoefToMeters : 1.); // Apply transform if needed OdTvMatrix* pTransform = (OdTvMatrix*)m_properties->getAppendTransform(); if (pTransform) pTvModel->setModelingMatrix(*pTransform); //calculate isolines if need if (m_properties->getCalculateIsolines()) { OdTvEntitiesIteratorPtr pEntitiesIterator = pTvModel->getEntitiesIterator(); while (!pEntitiesIterator->done()) { OdTvEntityId entityId = pEntitiesIterator->getEntity(); if (entityId.getType() == OdTvEntityId::kEntity) { OdTvEntityPtr pEntity = entityId.openObject(OdTv::kForWrite); if (!pEntity.isNull()) pEntity->setCalculateIsolinesForShells(true, 89.0 * OdaPI / 180.0, true); } pEntitiesIterator->step(); } } } if (m_properties->getNeedCDATree()) { OdPerfTimerBase* pCDATiming = OdPerfTimerBase::createTiming(); pCDATiming->start(); createCommonDataAccessTree(pTvDb, pQifDatabase, fileName + OD_T(".qif"), idModel); pCDATiming->stop(); CDATiming += pCDATiming->countedSec(); if (pProfileRes) pProfileRes->setCDATreeCreationTime(OdInt64((CDATiming) * 1000.)); } } //remove alone first level subentities and set shadow parameters OdTvModelPtr pTvModel = tvCreatedModelId.openObject(OdTv::kForWrite); if (!pTvModel.isNull()) { OdTvEntitiesIteratorPtr pEntitiesIterator = pTvModel->getEntitiesIterator(); while (!pEntitiesIterator->done()) { OdTvEntityId entityId = pEntitiesIterator->getEntity(); if (entityId.getType() == OdTvEntityId::kEntity) { OdTvEntityPtr pTvEntity = entityId.openObject(OdTv::kForWrite); if ( !pTvEntity.isNull() ) { pTvEntity->removeSubEntities(OdTvEntity::kRemoveAlone); pTvEntity->setShadowParameters(true, false); } } pEntitiesIterator->step(); } } } if (!bIsAppend || activeTvGsDeviceId.isNull()) { OdTvDatabaseUtils::createAndApplyPreferableVS(tvDbId, true, false); OdTvVisualStyleId visualStyleHiddenId = tvDbId.openObject(OdTv::kForWrite)->findVisualStyle(OD_T("Hidden Line Black")); if (!visualStyleHiddenId.isNull()) { OdTvVisualStylePtr pVisualStyle = visualStyleHiddenId.openObject(OdTv::kForWrite); if (!pVisualStyle.isNull()) pVisualStyle->setOption(OdTvVisualStyleOptions::kFaceColorMode, (OdInt32)OdTvVisualStyleOptions::kBackgroundTexture); } } //remove empty data if need if (tvDbId.isValid() && m_properties->getClearEmptyObjects()) OdTvDatabaseCleaner::cleanTvDatabase(tvDbId); timing.endMisc(); externalTiming += timing.getMiscTime(); } else { if (rc) *rc = tvMissingVisualizeDeviceModule; } timing.endVectorizing(); } else { if (rc) *rc = tvFilerEmptyContext; } if (m_properties->getIsLogOn()) { OdDAI::SessionPtr pSession = oddaiSession(); if (pSession->isRecordingOn()) { OdAnsiString log = getLog(pSession, pQifDatabase); if (!log.isEmpty()) { OdString logName = (pQifDatabase.isNull() ? fileName : pQifDatabase->getFileName()) + ".log"; std::ofstream file((const char*)logName); file << log; file.close(); } } } } else { // // File open error // if (rc) *rc = tvFilerEmptyInternalDatabase; } } catch (...) { if (rc) *rc = tvInternal; timing.endVectorizing(); } // Unload vectorizing device if (!moduleName.isEmpty()) odrxDynamicLinker()->unloadModule(moduleName); if (!bActivated) { // Uninitialize QIF modules odQifUninitialize(); // // Here we will unload everything including Visualize device // odrxDynamicLinker()->unloadUnreferenced(); } timing.endTotal(); if (pProfileRes) { pProfileRes->setImportTime((OdInt64)(fileOpenTiming * 1000.)); pProfileRes->setMiscTime((OdInt64)(composeTiming * 1000.)); pProfileRes->setVectorizingTime(OdInt64((timing.getVectorizingTime() - CDATiming) * 1000.)); #if !defined(__APPLE__) pProfileRes->setTvTime(OdInt64((internalTiming + externalTiming - CDATiming) * 1000.)); #endif } //set the selectability level if (!idModel.isNull()) { OdTvModelPtr pTvModel = idModel.openObject(OdTv::kForWrite); OdTvSelectabilityDef selectability; selectability.setGeometries(true); pTvModel->setSelectability(selectability, true); } return idModel; } OdAnsiString OdTvVisualizeQifFiler::getLog(OdDAI::SessionPtr& pSession, OdQifFilePtr pFile) const { if (pFile.isNull()) return OdAnsiString(); OdString fileName = pFile->getFileName(); OdAnsiString logString; logString = "********************************************************************************\n"; auto t = std::time(nullptr); auto tm = *std::localtime(&t); logString += "Date:\t\t\t "; logString += std::asctime(&tm); logString += "File name:\t\t "; logString += fileName; logString += "\n"; logString += "Readed with schema:\t\t "; logString += pFile->getModel()->underlyingSchemaName(); logString += "\n"; OdDAIHostAppServicesBase* pServices = pFile->getAppServices(); logString += "Produced by:\t\t "; logString += "ODA QIF SDK "; logString += pServices->versionString(); logString += "\n"; logString += "User:\t\t\t "; logString += pServices->getAppUserName(Oda::kUserId); logString += "\n"; logString += "********************************************************************************\n\n" ; logString += "--------------------------------------------------------------------------------\n"; if (!pSession.isNull()) { OdDAI::List* errors = nullptr; if (pSession->getAttr("errors") >> errors) { if (errors->getMemberCount() > 0) { for (int i = 0; i < errors->getMemberCount(); ++i) { OdDAI::ErrorEventPtr pEvent; if (errors->getByIndex(i) >> pEvent) { OdAnsiString descr = pEvent->description(); OdAnsiString func = pEvent->functionId(); logString += descr; logString += "<"; logString += func; logString += ">"; logString += "\n"; } } } else logString += "SUCCESS\n"; } } logString += "--------------------------------------------------------------------------------\n"; return logString; } OdTvDatabaseId OdTvVisualizeQifFiler::loadFrom(OdStreamBuf* pBuffer, OdTvFilerTimeProfiling* pProfileRes /*= NULL*/, OdTvResult* rc /*= NULL*/) const { OdTvDatabaseId idDb; import(idDb, pBuffer, OdQifFilePtr(), pProfileRes, rc); return idDb; } OdTvDatabaseId OdTvVisualizeQifFiler::loadFrom(OdDbBaseDatabase* pDatabase, OdTvFilerTimeProfiling* pProfileRes /*= NULL*/, OdTvResult* rc /*= NULL*/) const { OdTvDatabaseId tvDbId; import(tvDbId, NULL, pDatabase, pProfileRes, rc); return tvDbId; } OdTvDatabaseId OdTvVisualizeQifFiler::generate(OdTvFilerTimeProfiling* pProfileRes) const { OdTvDatabaseId tvDbId; // does nothing return tvDbId; } OdTvModelId OdTvVisualizeQifFiler::appendFrom(const OdTvDatabaseId& databaseId, const OdString& filePath, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdStreamBufPtr pStreamBuf = odrxSystemServices()->createFile(filePath); if (pStreamBuf.isNull()) { if (rc) *rc = tvInvalidFilePath; return OdTvModelId(); } return appendFrom(databaseId, pStreamBuf, pProfileRes, rc); } OdTvModelId OdTvVisualizeQifFiler::appendFrom(const OdTvDatabaseId& databaseId, OdStreamBuf* pBuffer, OdTvFilerTimeProfiling* pProfileRes /*= NULL*/, OdTvResult* rc /*= NULL*/) const { OdTvDatabaseId idTvDb = (OdTvDatabaseId)databaseId; return import(idTvDb, pBuffer, OdQifFilePtr(), pProfileRes, rc); } OdTvModelId OdTvVisualizeQifFiler::appendFrom(const OdTvDatabaseId& databaseId, OdDbBaseDatabase* pDatabase, OdTvFilerTimeProfiling* pProfileRes /*= NULL*/, OdTvResult* rc /*= NULL*/) const { OdTvDatabaseId tvDbId = databaseId; return import(tvDbId, NULL, pDatabase, pProfileRes, rc); } int OdTvVisualizeQifFiler::getActiveViewId(OdGsQifLayoutHelper* pLayoutHelper) const { if (!pLayoutHelper) return -1; OdGsViewPtr pActiveView = pLayoutHelper->activeView(); int num = pLayoutHelper->numViews(); int iActViewViewInd = 0; for (int i = 0; i < num; ++i) { OdGsView* pView = pLayoutHelper->viewAt(i); if (pView == pActiveView.get()) { iActViewViewInd = i; break; } } return iActViewViewInd; } OdTvGsViewId OdTvVisualizeQifFiler::getActiveTvView(OdTvDatabaseId& dbId, int iActViewViewInd) const { OdTvDevicesIteratorPtr pDevicesIterator = dbId.openObject()->getDevicesIterator(); if (!pDevicesIterator.isNull() && !pDevicesIterator->done()) { OdTvGsDevicePtr pTvDevice = pDevicesIterator->getDevice().openObject(); if (!pTvDevice.isNull()) { return pTvDevice->viewAt(iActViewViewInd); } } return OdTvGsViewId(); } //***************************************************************************// // Native properties methods implementation //***************************************************************************// OdTvResult OdTvVisualizeQifFiler::startActionsWithNativeProperties(const OdString& sFilePath, bool bPartial) { if (!m_pQifFile.isNull()) { if (m_pQifFile->getFileName() != sFilePath) m_pQifFile.release(); else return tvOk; } { if (m_pRxPropertiesModule.isNull()) m_pRxPropertiesModule = ::odrxDynamicLinker()->loadModule(L"RxProperties"); } odQifInitialize(true, true); OdTvResult rc = tvOk; if (m_pFilerPtr.isNull()) { m_pFilerPtr = new OdTvVisualizeQifFilerDbSource; } OdQifFilePtr pQifFile = m_pFilerPtr->readFile(sFilePath); if (pQifFile.isNull()) return tvFilerEmptyInternalDatabase; //OdTvVisualizeDwgFilerSourceFromFile dl; //if (!dl.initialize(sFilePath, NULL, &rc)) { try { m_pQifFile = pQifFile; m_pQifModel = m_pQifFile->getModel(); } catch (...) { return tvFilerEmptyInternalDatabase; } } return rc; } bool OdTvVisualizeQifFiler::isActionsWithNativePropertiesStarted(const OdString& sFilePath) { if (!m_pQifFile.isNull() && m_pQifFile->getFileName() == sFilePath) return true; return false; } OdTvResult OdTvVisualizeQifFiler::endActionsWithNativeProperties() { m_pFilerPtr = NULL; m_pQifModel.release(); m_pQifFile.release(); m_pQifCoreModule.release(); m_pRxPropertiesModule.release(); odQifUninitialize(); ::odrxDynamicLinker()->unloadModule(L"RxProperties"); ::odrxDynamicLinker()->unloadUnreferenced(); return tvOk; } OdRxMemberIteratorPtr OdTvVisualizeQifFiler::getNativePropertiesIterator(OdUInt64 dbHandle, OdTvResult* rc /*= NULL*/) { if (m_pQifModel.isNull()) { if (rc) *rc = tvNativePropMissedDatabase; return OdRxMemberIteratorPtr(); } OdRxMemberIteratorPtr pIter; if (dbHandle == 0) pIter = OdRxMemberQueryEngine::theEngine()->newMemberIterator(m_pQifFile.get()); else { OdDAIObjectId id = m_pQifModel->getEntityInstance(dbHandle); if (id.isNull()) { if (rc) *rc = tvNativePropMissedObject; return OdRxMemberIteratorPtr(); } OdDAI::ApplicationInstancePtr pInst = id.openObject(); pIter = OdRxMemberQueryEngine::theEngine()->newMemberIterator(pInst.get()); } if (pIter.isNull()) { if (rc) *rc = tvInternal; return OdRxMemberIteratorPtr(); } if (rc) *rc = tvOk; return pIter; } OdRxValue OdTvVisualizeQifFiler::getNativePropertyValue(OdUInt64 dbHandle, const OdRxPropertyPtr& pProperty, bool* bReadOnly /*= NULL*/, OdTvResult* rc /*= NULL*/) { if (pProperty.isNull()) { if (rc) *rc = tvInvalidInput; return OdRxValue(); } if (m_pQifModel.isNull()) { if (rc) *rc = tvNativePropMissedDatabase; return OdRxValue(); } OdRxObjectPtr pInst; if (dbHandle == 0) pInst = m_pQifFile; else { OdDAIObjectId id = m_pQifModel->getEntityInstance(dbHandle); pInst = id.openObject(); } if (pInst.isNull()) { if (rc) *rc = tvNativePropMissedObject; return OdRxValue(); } OdRxValue value; OdResult odRes = pProperty->getValue(pInst, value); if (bReadOnly) *bReadOnly = pProperty->isReadOnly(pInst); if (odRes != eOk) { if (rc) *rc = tvInternal; return OdRxValue(); } if (rc) *rc = tvOk; return value; } OdRxValueIteratorPtr OdTvVisualizeQifFiler::getNativeCollectionPropertyIterator(OdUInt64 dbHandle, const OdRxCollectionPropertyPtr& pCollectionProperty, bool* bReadOnly /*= NULL*/, OdTvResult* rc /*= NULL*/) { return OdRxValueIteratorPtr(); } OdTvResult OdTvVisualizeQifFiler::setNativePropertyValue(OdUInt64 dbHandle, OdRxPropertyPtr& pProperty, const OdRxValue& value) { return tvOk; } OdDbBaseDatabase* OdTvVisualizeQifFiler::getNativeDatabase(OdTvResult* rc) const { if (m_pQifFile.isNull()) { if (rc) *rc = tvNativePropMissedDatabase; return NULL; } return (OdDbBaseDatabase*)m_pQifFile.get(); } //***************************************************************************// // 'OdTvVisualizeQifFilerModule' methods implementation //***************************************************************************// ODRX_DEFINE_DYNAMIC_MODULE(OdTvVisualizeQifFilerModule); void OdTvVisualizeQifFilerModule::initApp() { // initialize the Visualize SDK odTvInitialize(); OdTvQif2VisService::s_moduleDir = getModuleWorkDir(); } void OdTvVisualizeQifFilerModule::uninitApp() { // Uninitialize the Visualize SDK odTvUninitialize(); } OdTvVisualizeFilerPtr OdTvVisualizeQifFilerModule::getVisualizeFiler() const { OdTvVisualizeFilerPtr pDwgFiler = new OdTvVisualizeQifFiler(); return pDwgFiler; } OdString OdTvVisualizeQifFilerModule::getModuleWorkDir() const { OdString moduleDir = moduleName(); int pos = moduleDir.reverseFind('\\'); if (pos < 0) { pos = moduleDir.reverseFind('/'); } if (pos > 0) { moduleDir = moduleDir.mid(0, pos + 1); } return moduleDir; } //***************************************************************************// // 'OdTvVisualizeQifFilerDbSource' methods implementation //***************************************************************************// OdAnsiString OdTvQif2VisService::s_moduleDir; OdQifFilePtr OdTvVisualizeQifFilerDbSource::readFile(const OdString &file) { return m_svcs.readFile(file); } void OdTvQifPartialImportNotifier::entityVectorizationDone(const OdTvEntityId& entityId) { if (entityId.isNull()) return; m_nCurrentObject++; if (m_pMeter) { m_pMeter->meterProgress(); } } void OdTvQifPartialImportNotifier::insertVectorizationDone(const OdTvEntityId& insertId) { m_nCurrentObject++; if (m_pMeter) { m_pMeter->meterProgress(); } } OdTvQifPartialImportNotifier::OdTvQifPartialImportNotifier() { m_nEntitiesEstimation = 0; m_nCurrentObject = 0; m_pMeter = NULL; } OdTvQifPartialImportNotifier::~OdTvQifPartialImportNotifier() { } void OdTvQifPartialImportNotifier::setEntitiesCount(OdUInt32 nCount) { m_nEntitiesEstimation = nCount; if (m_pMeter) m_pMeter->setLimit(m_nEntitiesEstimation); }