///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2017 Statoil ASA // // ResInsight 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. // // ResInsight 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RimFracture.h" #include "RigFracture.h" #include "RigTesselatorTools.h" #include "RimFractureDefinition.h" #include "RimView.h" #include "cafPdmUiDoubleSliderEditor.h" #include "cvfMatrix4.h" CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimFracture, "Fracture"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimFracture::RimFracture(void) { CAF_PDM_InitObject("Fracture", "", "", ""); CAF_PDM_InitField(&azimuth, "Azimuth", 0.0, "Azimuth", "", "", ""); azimuth.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); m_rigFracture = new RigFracture; m_recomputeGeometry = true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimFracture::~RimFracture() { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const std::vector& RimFracture::polygonIndices() const { return m_rigFracture->polygonIndices(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const std::vector& RimFracture::nodeCoords() const { return m_rigFracture->nodeCoords(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { if (changedField == &azimuth) { computeGeometry(); RimView* rimView = nullptr; this->firstAncestorOrThisOfType(rimView); if (rimView) { rimView->createDisplayModelAndRedraw(); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFracture::computeGeometry() { std::vector nodeCoords; std::vector polygonIndices; cvf::Vec3d center = centerPointForFracture(); RimFractureDefinition* fractureDef = attachedFractureDefinition(); if (fractureDef && !center.isUndefined()) { RigEllipsisTesselator tesselator(20); float a = fractureDef->height / 2.0f; float b = fractureDef->halfLength; tesselator.tesselateEllipsis(a, b, &polygonIndices, &nodeCoords); } // Ellipsis geometry is produced in XY-plane, rotate 90 deg around X to get zero azimuth along Y cvf::Mat4f rotationFromTesselator = cvf::Mat4f::fromRotation(cvf::Vec3f::X_AXIS, cvf::Math::toRadians(90.0f)); // Azimuth rotation cvf::Mat4f azimuthRotation = cvf::Mat4f::fromRotation(cvf::Vec3f::Z_AXIS, cvf::Math::toRadians(-azimuth())); cvf::Mat4f m = azimuthRotation * rotationFromTesselator; m.setTranslation(cvf::Vec3f(center)); for (cvf::Vec3f& v : nodeCoords) { v.transformPoint(m); } m_rigFracture->setGeometry(polygonIndices, nodeCoords); m_recomputeGeometry = false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFracture::setRecomputeGeometryFlag() { m_recomputeGeometry = true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimFracture::isRecomputeGeometryFlagSet() { return m_recomputeGeometry; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFracture::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { caf::PdmUiGroup* geometryGroup = uiOrdering.addNewGroup("Properties"); geometryGroup->add(&azimuth); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFracture::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) { if (field == &azimuth) { caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast(attribute); if (myAttr) { myAttr->m_minimum = 0; myAttr->m_maximum = 360; } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimFracture::hasValidGeometry() const { if (m_recomputeGeometry) return false; return (nodeCoords().size() > 0 && polygonIndices().size() > 0); }