mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-27 08:47:00 -06:00
58149cbdb9
Commented out use of stipple line, as VizFwk is not update yet
355 lines
11 KiB
C++
355 lines
11 KiB
C++
//##################################################################################################
|
|
//
|
|
// Custom Visualization Core library
|
|
// Copyright (C) 2011-2013 Ceetron AS
|
|
//
|
|
// This library may be used under the terms of either the GNU General Public License or
|
|
// the GNU Lesser General Public License as follows:
|
|
//
|
|
// GNU General Public License Usage
|
|
// This library is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
|
// for more details.
|
|
//
|
|
// GNU Lesser General Public License Usage
|
|
// This library is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
// the Free Software Foundation; either version 2.1 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
|
// for more details.
|
|
//
|
|
//##################################################################################################
|
|
|
|
|
|
#include "cafPdmReferenceHelper.h"
|
|
|
|
#include "cafPdmFieldHandle.h"
|
|
|
|
#include <QStringList>
|
|
|
|
#include <assert.h>
|
|
#include <algorithm>
|
|
|
|
|
|
namespace caf
|
|
{
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString PdmReferenceHelper::referenceFromRootToObject(PdmObjectHandle* root, PdmObjectHandle* obj)
|
|
{
|
|
QStringList objectNames = referenceFromRootToObjectAsStringList(root, obj);
|
|
|
|
QString completeReference = objectNames.join(" ");
|
|
return completeReference;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString PdmReferenceHelper::referenceFromRootToField(PdmObjectHandle* root, PdmFieldHandle* field)
|
|
{
|
|
if (field == NULL || root == NULL) return QString();
|
|
|
|
PdmObjectHandle* owner = field->ownerObject();
|
|
if (!owner) return QString(); // Should be assert ?
|
|
|
|
QStringList refFromRootToField;
|
|
|
|
refFromRootToField = referenceFromRootToObjectAsStringList(root, owner);
|
|
|
|
refFromRootToField.push_front(field->keyword());
|
|
|
|
QString completeReference = refFromRootToField.join(" ");
|
|
return completeReference;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
PdmObjectHandle* PdmReferenceHelper::objectFromReference(PdmObjectHandle* root, const QString& reference)
|
|
{
|
|
QStringList decodedReference = reference.split(" ");
|
|
|
|
return objectFromReferenceStringList(root, decodedReference);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
PdmFieldHandle* PdmReferenceHelper::findField(PdmObjectHandle* object, const QString& fieldKeyword)
|
|
{
|
|
if (object == NULL) return NULL;
|
|
|
|
std::vector<PdmFieldHandle*> fields;
|
|
object->fields(fields);
|
|
|
|
for (size_t i = 0; i < fields.size(); i++)
|
|
{
|
|
if (fields[i]->keyword() == fieldKeyword)
|
|
{
|
|
return fields[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QStringList PdmReferenceHelper::referenceFromRootToObjectAsStringList(PdmObjectHandle* root, PdmObjectHandle* obj)
|
|
{
|
|
QStringList objectNames;
|
|
|
|
if (obj != NULL && root)
|
|
{
|
|
if (obj == root) return objectNames;
|
|
|
|
PdmObjectHandle* currentObject = obj;
|
|
|
|
bool continueParsing = true;
|
|
while (continueParsing)
|
|
{
|
|
caf::PdmFieldHandle* parentField = currentObject->parentField();
|
|
assert(parentField);
|
|
|
|
std::vector<PdmObjectHandle*> childObjects;
|
|
parentField->childObjects(&childObjects);
|
|
|
|
if (childObjects.size() > 0)
|
|
{
|
|
int index = -1;
|
|
|
|
for (size_t i = 0; i < childObjects.size(); i++)
|
|
{
|
|
if (childObjects[i] == currentObject)
|
|
{
|
|
index = static_cast<int>(i);
|
|
}
|
|
}
|
|
|
|
objectNames.push_front(QString::number(index));
|
|
objectNames.push_front(parentField->keyword());
|
|
}
|
|
else
|
|
{
|
|
continueParsing = false;
|
|
continue;
|
|
}
|
|
|
|
PdmObjectHandle* ownerObject = parentField->ownerObject();
|
|
assert(ownerObject);
|
|
|
|
if (ownerObject == root)
|
|
{
|
|
continueParsing = false;
|
|
continue;
|
|
}
|
|
|
|
currentObject = ownerObject;
|
|
}
|
|
}
|
|
|
|
return objectNames;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
PdmFieldHandle* PdmReferenceHelper::fieldFromReference(PdmObjectHandle* root, const QString& reference)
|
|
{
|
|
QStringList decodedReference = reference.split(" ");
|
|
|
|
QString fieldKeyword = decodedReference[0];
|
|
decodedReference.pop_front();
|
|
|
|
PdmObjectHandle* parentObject = objectFromReferenceStringList(root, decodedReference);
|
|
return findField(parentObject, fieldKeyword);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
PdmObjectHandle* PdmReferenceHelper::objectFromReferenceStringList(PdmObjectHandle* root, const QStringList& reference)
|
|
{
|
|
PdmObjectHandle* currentObject = root;
|
|
|
|
int i = 0;
|
|
while (i < reference.size())
|
|
{
|
|
QString fieldKeyword = reference.at(i++);
|
|
|
|
PdmFieldHandle* field = findField(currentObject, fieldKeyword);
|
|
if (field)
|
|
{
|
|
std::vector<PdmObjectHandle*> childObjects;
|
|
field->childObjects(&childObjects);
|
|
|
|
if (childObjects.size() > 0)
|
|
{
|
|
QString fieldIndex = reference.at(i++);
|
|
bool conversionOk = true;
|
|
int index = fieldIndex.toInt(&conversionOk);
|
|
if (!conversionOk)
|
|
{
|
|
index = -1;
|
|
}
|
|
|
|
if (index > -1)
|
|
{
|
|
PdmObjectHandle* listObject = childObjects[index];
|
|
currentObject = listObject;
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return currentObject;
|
|
}
|
|
|
|
std::vector<PdmObjectHandle*> findPathToObjectFromRoot(PdmObjectHandle* obj)
|
|
{
|
|
std::vector<PdmObjectHandle*> objPath;
|
|
PdmObjectHandle* currentObj = obj;
|
|
while (currentObj)
|
|
{
|
|
objPath.push_back(currentObj);
|
|
if (currentObj->parentField())
|
|
{
|
|
currentObj = currentObj->parentField()->ownerObject();
|
|
}
|
|
else
|
|
{
|
|
currentObj = NULL;
|
|
}
|
|
}
|
|
|
|
std::reverse(objPath.begin(), objPath.end());
|
|
|
|
return objPath;
|
|
}
|
|
|
|
QString PdmReferenceHelper::referenceFromFieldToObject(PdmFieldHandle* fromField, PdmObjectHandle* toObj)
|
|
{
|
|
assert(fromField);
|
|
if (toObj == NULL) return "";
|
|
|
|
PdmObjectHandle* fromObj = fromField->ownerObject();
|
|
std::vector<PdmObjectHandle*> fromObjPath = findPathToObjectFromRoot(fromObj);
|
|
std::vector<PdmObjectHandle*> toObjPath = findPathToObjectFromRoot(toObj);
|
|
|
|
// Make sure the objects actually have at least one common ancestor
|
|
assert(fromObjPath.front() == toObjPath.front());
|
|
|
|
bool anchestorIsEqual = true;
|
|
size_t idxToLastCommonAnchestor = 0;
|
|
while (anchestorIsEqual)
|
|
{
|
|
++idxToLastCommonAnchestor;
|
|
if ( idxToLastCommonAnchestor >= fromObjPath.size()
|
|
|| idxToLastCommonAnchestor >= toObjPath.size()
|
|
|| fromObjPath[idxToLastCommonAnchestor] != toObjPath[idxToLastCommonAnchestor])
|
|
{
|
|
anchestorIsEqual = false;
|
|
idxToLastCommonAnchestor -= 1;
|
|
}
|
|
}
|
|
|
|
size_t levelCountToCommonAnchestor = (fromObjPath.size() - 1) - idxToLastCommonAnchestor;
|
|
|
|
PdmObjectHandle* lastCommonAnchestor = fromObjPath[idxToLastCommonAnchestor];
|
|
|
|
QStringList referenceList = referenceFromRootToObjectAsStringList(lastCommonAnchestor, toObj);
|
|
|
|
for (size_t i = 0; i < levelCountToCommonAnchestor; ++i)
|
|
{
|
|
referenceList.push_front("..");
|
|
}
|
|
|
|
QString completeReference = referenceList.join(" ");
|
|
|
|
return completeReference;
|
|
}
|
|
|
|
PdmObjectHandle* PdmReferenceHelper::objectFromFieldReference(PdmFieldHandle* fromField, const QString& reference)
|
|
{
|
|
if (reference.isEmpty()) return NULL;
|
|
assert(fromField);
|
|
|
|
QStringList decodedReference = reference.split(" ");
|
|
PdmObjectHandle* lastCommonAnchestor = fromField->ownerObject();
|
|
assert(lastCommonAnchestor);
|
|
assert(decodedReference.size());
|
|
|
|
while (decodedReference.front() == "..")
|
|
{
|
|
PdmFieldHandle* parentField = lastCommonAnchestor->parentField();
|
|
if (!parentField)
|
|
{
|
|
// Error: Relative object reference has an invalid number of parent levels
|
|
return NULL;
|
|
}
|
|
|
|
lastCommonAnchestor = parentField->ownerObject();
|
|
assert(lastCommonAnchestor);
|
|
decodedReference.pop_front();
|
|
}
|
|
|
|
return objectFromReferenceStringList(lastCommonAnchestor, decodedReference);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
PdmObjectHandle* PdmReferenceHelper::findRoot(PdmObjectHandle* obj)
|
|
{
|
|
std::vector<PdmObjectHandle*> path = findPathToObjectFromRoot(obj);
|
|
|
|
if (path.size()) return path[0];
|
|
else return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
PdmObjectHandle* PdmReferenceHelper::findRoot(PdmFieldHandle* field)
|
|
{
|
|
if (field)
|
|
{
|
|
PdmObjectHandle* ownerObject = field->ownerObject();
|
|
return findRoot(ownerObject);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
} // end namespace caf
|