mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Initial commit of ResInsight version 0.4.8
This commit is contained in:
276
ApplicationCode/Adm/LicenseInformation.txt
Normal file
276
ApplicationCode/Adm/LicenseInformation.txt
Normal file
@@ -0,0 +1,276 @@
|
||||
===============================================================================
|
||||
Notice for ResInsight:
|
||||
===============================================================================
|
||||
Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
|
||||
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 <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
|
||||
===============================================================================
|
||||
Notice for Custom Visualization Core Library:
|
||||
===============================================================================
|
||||
Custom Visualization Core library
|
||||
Copyright (C) 2011-2012 Ceetron AS
|
||||
|
||||
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.
|
||||
|
||||
===============================================================================
|
||||
Notice for Ensemble based Reservoir Tool:
|
||||
===============================================================================
|
||||
Copyright (C) 2011-2012 Statoil ASA, Norway.
|
||||
|
||||
ERT 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.
|
||||
|
||||
ERT 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.
|
||||
|
||||
|
||||
===============================================================================
|
||||
Notice for GLew :
|
||||
===============================================================================
|
||||
The OpenGL Extension Wrangler Library
|
||||
Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
|
||||
Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
|
||||
Copyright (C) 2002, Lev Povalahev
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* The name of the author may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
===============================================================================
|
||||
Notice for the Font Droid Sans Regular:
|
||||
===============================================================================
|
||||
Copyright (c) Google Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
26
ApplicationCode/Adm/RIBaseDefs.h
Normal file
26
ApplicationCode/Adm/RIBaseDefs.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
// Company and Application name
|
||||
// These two together will become the registry key
|
||||
const char RI_COMPANY_NAME[] = "Ceetron";
|
||||
const char RI_APPLICATION_NAME[] = "ResInsight";
|
||||
|
||||
28
ApplicationCode/Adm/RIVersionInfo.h
Normal file
28
ApplicationCode/Adm/RIVersionInfo.h
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
|
||||
// The one and only version info for the application
|
||||
// The application should use STRPRODUCTVER to display product version information
|
||||
//
|
||||
// The PRODUCTVER define is used in VersionInfo block fields FILEVERSION, PRODUCTVERSION and "FileVersion"
|
||||
// The STRPRODUCTVER define is used in VersionInfo block fields "ProductVersion"
|
||||
// See file "*.rc2"
|
||||
//
|
||||
// PRODUCTVER define contains : <major version>, <minor version>, <unused>, <build number>
|
||||
//
|
||||
// Externally shipped versions should have even build numbers
|
||||
#define PRODUCTVER "0,4,0,8"
|
||||
#define STRPRODUCTVER "0.4.8"
|
||||
28
ApplicationCode/Adm/RIVersionInfo.h.cmake
Normal file
28
ApplicationCode/Adm/RIVersionInfo.h.cmake
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
|
||||
// The one and only version info for the application
|
||||
// The application should use STRPRODUCTVER to display product version information
|
||||
//
|
||||
// The PRODUCTVER define is used in VersionInfo block fields FILEVERSION, PRODUCTVERSION and "FileVersion"
|
||||
// The STRPRODUCTVER define is used in VersionInfo block fields "ProductVersion"
|
||||
// See file "*.rc2"
|
||||
//
|
||||
// PRODUCTVER define contains : <major version>, <minor version>, <unused>, <build number>
|
||||
//
|
||||
// Externally shipped versions should have even build numbers
|
||||
#define PRODUCTVER "@PRODUCTVER@"
|
||||
#define STRPRODUCTVER "@STRPRODUCTVER@"
|
||||
17
ApplicationCode/Adm/ResInsightLicenseText.txt
Normal file
17
ApplicationCode/Adm/ResInsightLicenseText.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
623
ApplicationCode/Adm/gplLicense.txt
Normal file
623
ApplicationCode/Adm/gplLicense.txt
Normal file
@@ -0,0 +1,623 @@
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
816
ApplicationCode/Application/RIApplication.cpp
Normal file
816
ApplicationCode/Application/RIApplication.cpp
Normal file
@@ -0,0 +1,816 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "cafLog.h"
|
||||
#include "cafEffectCache.h"
|
||||
#include "cafUtils.h"
|
||||
|
||||
#include "cvfPart.h"
|
||||
|
||||
#include "cvfStructGridGeometryGenerator.h"
|
||||
|
||||
#include "RIVersionInfo.h"
|
||||
#include "RIBaseDefs.h"
|
||||
|
||||
#include "RIApplication.h"
|
||||
#include "RIMainWindow.h"
|
||||
#include "RIViewer.h"
|
||||
#include "RIProcessMonitor.h"
|
||||
#include "RIPreferences.h"
|
||||
|
||||
#include "RimReservoir.h"
|
||||
|
||||
#include "RigReservoir.h"
|
||||
#include "RigCell.h"
|
||||
#include "RigReservoirBuilderMock.h"
|
||||
|
||||
#include "RimReservoirView.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include "cafPdmDocument.h"
|
||||
#include "RifReaderInterfaceMock.h"
|
||||
|
||||
#include "cafCeetronNavigation.h"
|
||||
#include "cafCadNavigation.h"
|
||||
#include "RiaSocketServer.h"
|
||||
#include "cafUiProcess.h"
|
||||
|
||||
#include "RimUiTreeModelPdm.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void AppEnum< RIApplication::RINavigationPolicy >::setUp()
|
||||
{
|
||||
addItem(RIApplication::NAVIGATION_POLICY_CEETRON, "NAVIGATION_POLICY_CEETRON", "Ceetron");
|
||||
addItem(RIApplication::NAVIGATION_POLICY_CAD, "NAVIGATION_POLICY_CAD", "CAD");
|
||||
setDefault(RIApplication::NAVIGATION_POLICY_CAD);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class RIApplication
|
||||
///
|
||||
/// Application class
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RIApplication::RIApplication(int& argc, char** argv)
|
||||
: QApplication(argc, argv)
|
||||
{
|
||||
// USed to get registry settings in the right place
|
||||
QCoreApplication::setOrganizationName(RI_COMPANY_NAME);
|
||||
QCoreApplication::setApplicationName(RI_APPLICATION_NAME);
|
||||
|
||||
// For idle processing
|
||||
// m_idleTimerStarted = false;
|
||||
installEventFilter(this);
|
||||
|
||||
//cvf::Trace::enable(false);
|
||||
|
||||
m_preferences = new RIPreferences;
|
||||
readPreferences();
|
||||
applyPreferences();
|
||||
|
||||
if (useShaders())
|
||||
{
|
||||
caf::EffectGenerator::setRenderingMode(caf::EffectGenerator::SHADER_BASED);
|
||||
}
|
||||
else
|
||||
{
|
||||
caf::EffectGenerator::setRenderingMode(caf::EffectGenerator::FIXED_FUNCTION);
|
||||
}
|
||||
|
||||
// Start with a project
|
||||
m_project = new RimProject;
|
||||
|
||||
setWindowIcon(QIcon(":/AppLogo48x48.png"));
|
||||
|
||||
m_socketServer = new RiaSocketServer( this);
|
||||
m_workerProcess = NULL;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RIApplication::~RIApplication()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RIApplication* RIApplication::instance()
|
||||
{
|
||||
return static_cast<RIApplication*>qApp;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::setWindowCaptionFromAppState()
|
||||
{
|
||||
RIMainWindow* mainWnd = RIMainWindow::instance();
|
||||
if (!mainWnd) return;
|
||||
|
||||
// The stuff being done here should really be handled by Qt automatically as a result of
|
||||
// setting applicationName and windowFilePath
|
||||
// Was unable to make this work in Qt4.4.0!
|
||||
|
||||
QString capt = RI_APPLICATION_NAME;
|
||||
#ifdef _DEBUG
|
||||
capt += " ##DEBUG##";
|
||||
#endif
|
||||
|
||||
{
|
||||
QString projFileName = m_currentProjectFileName;
|
||||
if (projFileName.isEmpty()) projFileName = "Untitled project";
|
||||
|
||||
capt = projFileName + QString("[*]") + QString(" - ") + capt;
|
||||
}
|
||||
|
||||
mainWnd->setWindowTitle(capt);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::processNonGuiEvents()
|
||||
{
|
||||
processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const char* RIApplication::getVersionStringApp(bool includeCrtInfo)
|
||||
{
|
||||
// Use static buf so we can return ptr
|
||||
static char szBuf[1024];
|
||||
|
||||
cvf::String crtInfo;
|
||||
if (includeCrtInfo)
|
||||
{
|
||||
#ifdef _MT
|
||||
#ifdef _DLL
|
||||
crtInfo = " (DLL CRT)";
|
||||
#else
|
||||
crtInfo = " (static CRT)";
|
||||
#endif
|
||||
#endif //_MT
|
||||
}
|
||||
|
||||
cvf::System::sprintf(szBuf, 1024, "%s%s", STRPRODUCTVER, crtInfo.toAscii().ptr());
|
||||
|
||||
return szBuf;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::loadProject(const QString& projectFileName)
|
||||
{
|
||||
if (!closeProject(true)) return false;
|
||||
|
||||
if (!QFile::exists(projectFileName)) return false;
|
||||
|
||||
m_project->fileName = projectFileName;
|
||||
m_project->readFile();
|
||||
|
||||
if (m_project->projectFileVersionString().isEmpty())
|
||||
{
|
||||
closeProject(false);
|
||||
|
||||
QString tmp = QString("Unknown project file version detected in file \n%1\n\nCould not open project.").arg(projectFileName);
|
||||
QMessageBox::warning(NULL, "Error when opening project file", tmp);
|
||||
|
||||
RIMainWindow* mainWnd = RIMainWindow::instance();
|
||||
mainWnd->setPdmRoot(NULL);
|
||||
|
||||
// Delete all object possibly generated by readFile()
|
||||
delete m_project;
|
||||
m_project = new RimProject;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentProjectFileName = projectFileName;
|
||||
m_preferences->lastUsedProjectFileName = projectFileName;
|
||||
writePreferences();
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < m_project->reservoirs().size(); ++i)
|
||||
{
|
||||
RimReservoir* ri = m_project->reservoirs()[i];
|
||||
CVF_ASSERT(ri);
|
||||
|
||||
size_t j;
|
||||
for (j = 0; j < ri->reservoirViews().size(); j++)
|
||||
{
|
||||
RimReservoirView* riv = ri->reservoirViews()[j];
|
||||
CVF_ASSERT(riv);
|
||||
|
||||
riv->loadDataAndUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onProjectOpenedOrClosed();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::loadLastUsedProject()
|
||||
{
|
||||
return loadProject(m_preferences->lastUsedProjectFileName);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::saveProject()
|
||||
{
|
||||
if (!QFile::exists(m_currentProjectFileName))
|
||||
{
|
||||
return saveProjectPromptForFileName();
|
||||
}
|
||||
else
|
||||
{
|
||||
return saveProjectAs(m_currentProjectFileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::saveProjectPromptForFileName()
|
||||
{
|
||||
//if (m_project.isNull()) return true;
|
||||
|
||||
QString startPath;
|
||||
if (!m_currentProjectFileName.isEmpty())
|
||||
{
|
||||
QFileInfo fi(m_currentProjectFileName);
|
||||
startPath = fi.absolutePath();
|
||||
}
|
||||
else
|
||||
{
|
||||
startPath = QDir::currentPath();
|
||||
}
|
||||
|
||||
startPath += "/ResInsightProject.rip";
|
||||
|
||||
QString fileName = QFileDialog::getSaveFileName(NULL, tr("Save File"), startPath, tr("Project Files (*.rip *.xml)"));
|
||||
if (fileName.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bSaveOk = saveProjectAs(fileName);
|
||||
|
||||
setWindowCaptionFromAppState();
|
||||
|
||||
return bSaveOk;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::saveProjectAs(const QString& fileName)
|
||||
{
|
||||
m_project->fileName = fileName;
|
||||
m_project->writeFile();
|
||||
|
||||
m_currentProjectFileName = fileName;
|
||||
m_preferences->lastUsedProjectFileName = fileName;
|
||||
writePreferences();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::closeProject(bool askToSaveIfDirty)
|
||||
{
|
||||
RIMainWindow* mainWnd = RIMainWindow::instance();
|
||||
|
||||
if (false)
|
||||
{
|
||||
QMessageBox msgBox(mainWnd);
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setText("The project being closed has been modified.");
|
||||
msgBox.setInformativeText("Do you want to save your changes?");
|
||||
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
||||
//msgBox.setDefaultButton(QMessageBox::Save);
|
||||
|
||||
int ret = msgBox.exec();
|
||||
if (ret == QMessageBox::Save)
|
||||
{
|
||||
//m_sceneManager->saveAll();
|
||||
}
|
||||
else if (ret == QMessageBox::Cancel)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mainWnd->cleanupGuiBeforeProjectClose();
|
||||
|
||||
caf::EffectCache::instance()->clear();
|
||||
m_project->close();
|
||||
|
||||
onProjectOpenedOrClosed();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::onProjectOpenedOrClosed()
|
||||
{
|
||||
RIMainWindow* mainWnd = RIMainWindow::instance();
|
||||
if (!mainWnd) return;
|
||||
|
||||
mainWnd->initializeGuiNewProjectLoaded();
|
||||
//mainWnd->redrawAllViews();
|
||||
|
||||
setWindowCaptionFromAppState();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RIApplication::lastProjectFileName() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::openEclipseCaseFromFile(const QString& fileName)
|
||||
{
|
||||
if (!QFile::exists(fileName)) return false;
|
||||
|
||||
QFileInfo gridFileName(fileName);
|
||||
QString caseName = gridFileName.completeBaseName();
|
||||
QString casePath = gridFileName.absolutePath();
|
||||
|
||||
return openEclipseCase(caseName, casePath);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::openEclipseCase(const QString& caseName, const QString& casePath)
|
||||
{
|
||||
RimReservoir* rimReservoir = new RimReservoir();
|
||||
rimReservoir->caseName = caseName;
|
||||
rimReservoir->caseDirectory = casePath;
|
||||
|
||||
m_project->reservoirs.push_back(rimReservoir);
|
||||
|
||||
RimReservoirView* riv = rimReservoir->createAndAddReservoirView();
|
||||
|
||||
// Select SOIL as default result variable
|
||||
riv->cellResult()->resultType = RimDefines::DYNAMIC_NATIVE;
|
||||
riv->cellResult()->resultVariable = "SOIL";
|
||||
riv->animationMode = true;
|
||||
|
||||
riv->loadDataAndUpdate();
|
||||
|
||||
if (!riv->cellResult()->hasResult())
|
||||
{
|
||||
riv->cellResult()->resultVariable = "";
|
||||
}
|
||||
|
||||
onProjectOpenedOrClosed();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::createMockModel()
|
||||
{
|
||||
openEclipseCase("Mock Debug Model Simple", "");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::createResultsMockModel()
|
||||
{
|
||||
openEclipseCase("Mock Debug Model With Results", "");
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::createLargeResultsMockModel()
|
||||
{
|
||||
openEclipseCase("Mock Debug Model Large With Results", "");
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RimReservoirView* RIApplication::activeReservoirView() const
|
||||
{
|
||||
return m_activeReservoirView;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimReservoirView* RIApplication::activeReservoirView()
|
||||
{
|
||||
return m_activeReservoirView;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::setActiveReservoirView(RimReservoirView* rv)
|
||||
{
|
||||
m_activeReservoirView = rv;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::setUseShaders(bool enable)
|
||||
{
|
||||
m_preferences->useShaders = enable;
|
||||
writePreferences();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::useShaders() const
|
||||
{
|
||||
bool isShadersSupported = caf::Viewer::isShadersSupported();
|
||||
if (!isShadersSupported) return false;
|
||||
|
||||
return m_preferences->useShaders;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RIApplication::RINavigationPolicy RIApplication::navigationPolicy() const
|
||||
{
|
||||
return m_preferences->navigationPolicy();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::setShowPerformanceInfo(bool enable)
|
||||
{
|
||||
m_preferences->showHud = enable;
|
||||
writePreferences();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::showPerformanceInfo() const
|
||||
{
|
||||
return m_preferences->showHud;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::parseArguments()
|
||||
{
|
||||
QStringList arguments = QCoreApplication::arguments();
|
||||
|
||||
bool openLatestProject = false;
|
||||
QString projectFilename;
|
||||
QStringList caseNames;
|
||||
|
||||
bool isParsingProjectFile = false;
|
||||
bool isParsingCaseNames = false;
|
||||
bool showHelp = false;
|
||||
|
||||
int i;
|
||||
for (i = 1; i < arguments.size(); i++)
|
||||
{
|
||||
QString arg = arguments[i];
|
||||
bool argParsedAsFlag = false;
|
||||
|
||||
if (arg.toLower() == "-help" || arg.toLower() == "-?")
|
||||
{
|
||||
showHelp = true;
|
||||
}
|
||||
|
||||
if (arg.toLower() == "-last")
|
||||
{
|
||||
openLatestProject = true;
|
||||
argParsedAsFlag = true;
|
||||
}
|
||||
else if (arg.toLower() == "-project")
|
||||
{
|
||||
isParsingCaseNames = false;
|
||||
isParsingProjectFile = true;
|
||||
argParsedAsFlag = true;
|
||||
}
|
||||
else if (arg.toLower() == "-case")
|
||||
{
|
||||
isParsingCaseNames = true;
|
||||
isParsingProjectFile = false;
|
||||
argParsedAsFlag = true;
|
||||
}
|
||||
|
||||
if (!argParsedAsFlag)
|
||||
{
|
||||
if (isParsingProjectFile && QFile::exists(arg))
|
||||
{
|
||||
projectFilename = arg;
|
||||
}
|
||||
|
||||
if (isParsingCaseNames)
|
||||
{
|
||||
caseNames.append(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showHelp)
|
||||
{
|
||||
QString helpText = QString("\n%1 v. %2\n").arg(RI_APPLICATION_NAME).arg(getVersionStringApp(false));
|
||||
helpText += "Copyright Statoil ASA, Ceetron AS 2011, 2012\n\n";
|
||||
|
||||
helpText +=
|
||||
"\nParameter Description\n"
|
||||
"-----------------------------------------------------------------\n"
|
||||
"-last Open last used project\n"
|
||||
"-project <filename> Open project file <filename>\n"
|
||||
"-case <casename> Open Eclipse case <casename>\n"
|
||||
" (do not include .GRID/.EGRID)\n"
|
||||
"-help \n"
|
||||
"-? Displays help text\n"
|
||||
"-----------------------------------------------------------------";
|
||||
|
||||
fprintf(stdout, "%s\n", helpText.toAscii().data());
|
||||
fflush(stdout);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (openLatestProject)
|
||||
{
|
||||
loadLastUsedProject();
|
||||
}
|
||||
|
||||
if (!projectFilename.isEmpty())
|
||||
{
|
||||
loadProject(projectFilename);
|
||||
}
|
||||
|
||||
if (!caseNames.isEmpty())
|
||||
{
|
||||
QString caseName;
|
||||
foreach (caseName, caseNames)
|
||||
{
|
||||
QString tmpCaseFileName = caseName + ".EGRID";
|
||||
|
||||
if (QFile::exists(tmpCaseFileName))
|
||||
{
|
||||
openEclipseCaseFromFile(tmpCaseFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpCaseFileName = caseName + ".GRID";
|
||||
if (QFile::exists(tmpCaseFileName))
|
||||
{
|
||||
openEclipseCaseFromFile(tmpCaseFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RIApplication::scriptDirectory() const
|
||||
{
|
||||
return m_preferences->scriptDirectory();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RIApplication::scriptEditorPath() const
|
||||
{
|
||||
return m_preferences->scriptEditorExecutable();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RIApplication::octavePath() const
|
||||
{
|
||||
return m_preferences->octaveExecutable();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
RIMainWindow::instance()->processMonitor()->stopMonitorWorkProcess();
|
||||
|
||||
// Execute delete later so that other slots that are hooked up
|
||||
// get a chance to run before we delete the object
|
||||
if (m_workerProcess)
|
||||
{
|
||||
m_workerProcess->deleteLater();
|
||||
}
|
||||
m_workerProcess = NULL;
|
||||
|
||||
// Either the work process crashed or was aborted by the user
|
||||
if (exitStatus == QProcess::CrashExit)
|
||||
{
|
||||
// MFLog::error("Simulation execution crashed or was aborted.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Exit code != 0 means we have an error
|
||||
if (exitCode != 0)
|
||||
{
|
||||
// MFLog::error(QString("Simulation execution failed (exit code %1).").arg(exitCode));
|
||||
return;
|
||||
}
|
||||
|
||||
//MFLog::info("Simulation completed successfully.");
|
||||
|
||||
//MFMainWindow::instance()->slotLoadResultsFromSimulationFolder();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RIApplication::launchProcess(const QString& program, const QStringList& arguments)
|
||||
{
|
||||
m_workerProcess = new caf::UiProcess(this);
|
||||
connect(m_workerProcess, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(slotWorkerProcessFinished(int, QProcess::ExitStatus)));
|
||||
|
||||
RIMainWindow::instance()->processMonitor()->startMonitorWorkProcess(m_workerProcess);
|
||||
|
||||
m_workerProcess->start(program, arguments);
|
||||
if (!m_workerProcess->waitForStarted(1000))
|
||||
{
|
||||
m_workerProcess->deleteLater();
|
||||
m_workerProcess = NULL;
|
||||
|
||||
RIMainWindow::instance()->processMonitor()->stopMonitorWorkProcess();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Read fields of a Pdm object using QSettings
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::readPreferences()
|
||||
{
|
||||
QSettings settings;
|
||||
std::vector<caf::PdmFieldHandle*> fields;
|
||||
|
||||
m_preferences->fields(fields);
|
||||
size_t i;
|
||||
for (i = 0; i < fields.size(); i++)
|
||||
{
|
||||
caf::PdmFieldHandle* fieldHandle = fields[i];
|
||||
|
||||
if (settings.contains(fieldHandle->keyword()))
|
||||
{
|
||||
QVariant val = settings.value(fieldHandle->keyword());
|
||||
fieldHandle->setValueFromUi(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Write fields of a Pdm object using QSettings
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::writePreferences()
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
std::vector<caf::PdmFieldHandle*> fields;
|
||||
m_preferences->fields(fields);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < fields.size(); i++)
|
||||
{
|
||||
caf::PdmFieldHandle* fieldHandle = fields[i];
|
||||
|
||||
settings.setValue(fieldHandle->keyword(), fieldHandle->uiValue());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RIPreferences* RIApplication::preferences()
|
||||
{
|
||||
return m_preferences;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RIApplication::applyPreferences()
|
||||
{
|
||||
if (m_activeReservoirView && m_activeReservoirView->viewer())
|
||||
{
|
||||
if (m_preferences->navigationPolicy() == NAVIGATION_POLICY_CAD)
|
||||
{
|
||||
m_activeReservoirView->viewer()->setNavigationPolicy(new caf::CadNavigation);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_activeReservoirView->viewer()->setNavigationPolicy(new caf::CeetronNavigation);
|
||||
}
|
||||
|
||||
m_activeReservoirView->viewer()->enablePerfInfoHud(m_preferences->showHud());
|
||||
}
|
||||
|
||||
if (useShaders())
|
||||
{
|
||||
caf::EffectGenerator::setRenderingMode(caf::EffectGenerator::SHADER_BASED);
|
||||
}
|
||||
else
|
||||
{
|
||||
caf::EffectGenerator::setRenderingMode(caf::EffectGenerator::FIXED_FUNCTION);
|
||||
}
|
||||
|
||||
if (this->project())
|
||||
{
|
||||
this->project()->setUserScriptPath(m_preferences->scriptDirectory());
|
||||
RimUiTreeModelPdm* treeModel = RIMainWindow::instance()->uiPdmModel();
|
||||
if (treeModel) treeModel->rebuildUiSubTree(this->project()->scriptCollection());
|
||||
}
|
||||
|
||||
}
|
||||
128
ApplicationCode/Application/RIApplication.h
Normal file
128
ApplicationCode/Application/RIApplication.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include <QtGui/QApplication>
|
||||
#include <QProcess>
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include "cvfScalarMapperUniformLevels.h"
|
||||
#include "cvfOverlayColorLegend.h"
|
||||
#include "RimReservoirView.h"
|
||||
|
||||
#include <iostream>
|
||||
#include "RimProject.h"
|
||||
|
||||
class RIProcess;
|
||||
class RigReservoir;
|
||||
class RimReservoir;
|
||||
class Drawable;
|
||||
class RiaSocketServer;
|
||||
class RIPreferences;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class UiProcess;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RIApplication : public QApplication
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum RINavigationPolicy
|
||||
{
|
||||
NAVIGATION_POLICY_CEETRON,
|
||||
NAVIGATION_POLICY_CAD
|
||||
};
|
||||
|
||||
public:
|
||||
RIApplication(int& argc, char** argv);
|
||||
~RIApplication();
|
||||
static RIApplication* instance();
|
||||
|
||||
bool parseArguments();
|
||||
|
||||
void setActiveReservoirView(RimReservoirView*);
|
||||
RimReservoirView* activeReservoirView();
|
||||
const RimReservoirView* activeReservoirView() const;
|
||||
|
||||
RimProject* project() {return m_project;}
|
||||
|
||||
void createMockModel();
|
||||
void createResultsMockModel();
|
||||
void createLargeResultsMockModel();
|
||||
|
||||
bool openEclipseCaseFromFile(const QString& fileName);
|
||||
bool openEclipseCase(const QString& caseName, const QString& casePath);
|
||||
bool loadLastUsedProject();
|
||||
QString lastProjectFileName() const;
|
||||
bool loadProject(const QString& fileName);
|
||||
bool saveProject();
|
||||
bool saveProjectAs(const QString& fileName);
|
||||
bool saveProjectPromptForFileName();
|
||||
bool closeProject(bool askToSaveIfDirty);
|
||||
|
||||
void processNonGuiEvents();
|
||||
|
||||
static const char* getVersionStringApp(bool includeCrtInfo);
|
||||
|
||||
void setUseShaders(bool enable);
|
||||
bool useShaders() const;
|
||||
|
||||
void setShowPerformanceInfo(bool enable);
|
||||
bool showPerformanceInfo() const;
|
||||
|
||||
RINavigationPolicy navigationPolicy() const;
|
||||
QString scriptDirectory() const;
|
||||
QString scriptEditorPath() const;
|
||||
QString octavePath() const;
|
||||
|
||||
bool launchProcess(const QString& program, const QStringList& arguments);
|
||||
|
||||
RIPreferences* preferences();
|
||||
void readPreferences();
|
||||
void writePreferences();
|
||||
void applyPreferences();
|
||||
|
||||
private:
|
||||
void onProjectOpenedOrClosed();
|
||||
void setWindowCaptionFromAppState();
|
||||
|
||||
|
||||
private slots:
|
||||
void slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
|
||||
|
||||
private:
|
||||
caf::PdmPointer<RimReservoirView> m_activeReservoirView;
|
||||
caf::PdmPointer<RimProject> m_project;
|
||||
|
||||
QString m_currentProjectFileName;
|
||||
RiaSocketServer* m_socketServer;
|
||||
|
||||
caf::UiProcess* m_workerProcess;
|
||||
|
||||
RIPreferences* m_preferences;
|
||||
};
|
||||
47
ApplicationCode/Application/RIPreferences.cpp
Normal file
47
ApplicationCode/Application/RIPreferences.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
#include "RIPreferences.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RIPreferences, "RIPreferences");
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RIPreferences::RIPreferences(void)
|
||||
{
|
||||
CAF_PDM_InitField(&navigationPolicy, "navigationPolicy", caf::AppEnum<RIApplication::RINavigationPolicy>(RIApplication::NAVIGATION_POLICY_CAD), "Navigation mode", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&scriptDirectory, "scriptDirectory", "Shared Script Folder", "", "", "");
|
||||
CAF_PDM_InitField(&scriptEditorExecutable, "scriptEditorExecutable", QString("kate"), "Script Editor", "", "", "");
|
||||
CAF_PDM_InitField(&octaveExecutable, "octaveExecutable", QString("octave"), "Octave", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&useShaders, "useShaders", true, "Use Shaders", "", "", "");
|
||||
CAF_PDM_InitField(&showHud, "showHud", true, "Show 3D Information", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&lastUsedProjectFileName,"lastUsedProjectFileName", "Last Used Project File", "", "", "");
|
||||
lastUsedProjectFileName.setHidden(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RIPreferences::~RIPreferences(void)
|
||||
{
|
||||
|
||||
}
|
||||
43
ApplicationCode/Application/RIPreferences.h
Normal file
43
ApplicationCode/Application/RIPreferences.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "RIApplication.h"
|
||||
|
||||
class RIPreferences : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RIPreferences(void);
|
||||
virtual ~RIPreferences(void);
|
||||
|
||||
public: // Pdm Fields
|
||||
caf::PdmField<caf::AppEnum< RIApplication::RINavigationPolicy > > navigationPolicy;
|
||||
|
||||
caf::PdmField<QString> scriptDirectory;
|
||||
caf::PdmField<QString> scriptEditorExecutable;
|
||||
caf::PdmField<QString> octaveExecutable;
|
||||
|
||||
caf::PdmField<bool> useShaders;
|
||||
caf::PdmField<bool> showHud;
|
||||
|
||||
caf::PdmField<QString> lastUsedProjectFileName;
|
||||
};
|
||||
293
ApplicationCode/CMakeLists.txt
Normal file
293
ApplicationCode/CMakeLists.txt
Normal file
@@ -0,0 +1,293 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project (ApplicationCode)
|
||||
|
||||
CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RIVersionInfo.h.cmake ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RIVersionInfo.h)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Adm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Application
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/FileInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SocketInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/UserInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ReservoirDataModel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert/ecl/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert/util/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert/geometry/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert/well/include
|
||||
)
|
||||
|
||||
|
||||
# Use all cpp and h files in the subdirectories
|
||||
file( GLOB_RECURSE HEADER_FILES *.h )
|
||||
|
||||
list( APPEND CPP_SOURCES
|
||||
RIMain.cpp
|
||||
RIStdInclude.cpp
|
||||
)
|
||||
|
||||
list( APPEND CPP_SOURCES
|
||||
Application/RIApplication.cpp
|
||||
Application/RIPreferences.cpp
|
||||
)
|
||||
|
||||
list( APPEND CPP_SOURCES
|
||||
ModelVisualization/RivCellEdgeEffectGenerator.cpp
|
||||
ModelVisualization/RivGridPartMgr.cpp
|
||||
ModelVisualization/RivReservoirPartMgr.cpp
|
||||
ModelVisualization/RivReservoirViewPartMgr.cpp
|
||||
ModelVisualization/RivPipeGeometryGenerator.cpp
|
||||
ModelVisualization/RivReservoirPipesPartMgr.cpp
|
||||
ModelVisualization/RivWellPipesPartMgr.cpp
|
||||
ModelVisualization/RivWellHeadPartMgr.cpp
|
||||
)
|
||||
|
||||
list( APPEND CPP_SOURCES
|
||||
FileInterface/RifReaderEclipseFileAccess.cpp
|
||||
FileInterface/RifReaderEclipseRestartFiles.cpp
|
||||
FileInterface/RifReaderEclipseResultAccess.cpp
|
||||
FileInterface/RifReaderEclipseUnifiedRestartFile.cpp
|
||||
FileInterface/RifReaderInterfaceEcl.cpp
|
||||
FileInterface/RifReaderInterfaceMock.cpp
|
||||
)
|
||||
|
||||
list( APPEND CPP_SOURCES
|
||||
SocketInterface/RiaSocketServer.cpp
|
||||
)
|
||||
|
||||
list( APPEND CPP_SOURCES
|
||||
ProjectDataModel/RimCellFilter.cpp
|
||||
ProjectDataModel/RimCellPropertyFilter.cpp
|
||||
ProjectDataModel/RimCellPropertyFilterCollection.cpp
|
||||
ProjectDataModel/RimCellRangeFilter.cpp
|
||||
ProjectDataModel/RimCellRangeFilterCollection.cpp
|
||||
ProjectDataModel/RimDefines.cpp
|
||||
ProjectDataModel/RimLegendConfig.cpp
|
||||
ProjectDataModel/RimProject.cpp
|
||||
ProjectDataModel/RimReservoir.cpp
|
||||
ProjectDataModel/RimReservoirView.cpp
|
||||
ProjectDataModel/RimResultDefinition.cpp
|
||||
ProjectDataModel/RimResultSlot.cpp
|
||||
ProjectDataModel/RimCellEdgeResultSlot.cpp
|
||||
ProjectDataModel/RimUiTreeModelPdm.cpp
|
||||
ProjectDataModel/RimWell.cpp
|
||||
ProjectDataModel/RimWellCollection.cpp
|
||||
ProjectDataModel/RimScriptCollection.cpp
|
||||
ProjectDataModel/RimCalcScript.cpp
|
||||
)
|
||||
|
||||
list( APPEND CPP_SOURCES
|
||||
ReservoirDataModel/RigCell.cpp
|
||||
ReservoirDataModel/RigGridBase.cpp
|
||||
ReservoirDataModel/RigReservoirCellResults.cpp
|
||||
ReservoirDataModel/RigLocalGrid.cpp
|
||||
ReservoirDataModel/RigMainGrid.cpp
|
||||
ReservoirDataModel/RigReservoir.cpp
|
||||
ReservoirDataModel/RigReservoirBuilderMock.cpp
|
||||
ReservoirDataModel/RigWellResults.cpp
|
||||
)
|
||||
|
||||
list( APPEND CPP_SOURCES
|
||||
UserInterface/RICursors.cpp
|
||||
UserInterface/RIMainWindow.cpp
|
||||
UserInterface/RIPreferencesDialog.cpp
|
||||
UserInterface/RIResultInfoPanel.cpp
|
||||
UserInterface/RIViewer.cpp
|
||||
UserInterface/RIProcessMonitor.cpp
|
||||
|
||||
)
|
||||
|
||||
# Define files for MOC-ing
|
||||
set ( QT_MOC_HEADERS
|
||||
Application/RIApplication.h
|
||||
ProjectDataModel/RimUiTreeModelPdm.h
|
||||
UserInterface/RIMainWindow.h
|
||||
UserInterface/RIPreferencesDialog.h
|
||||
UserInterface/RIResultInfoPanel.h
|
||||
UserInterface/RIViewer.h
|
||||
UserInterface/RIProcessMonitor.h
|
||||
SocketInterface/RiaSocketServer.h
|
||||
)
|
||||
|
||||
qt4_wrap_cpp( MOC_FILES_CPP ${QT_MOC_HEADERS} )
|
||||
|
||||
# NOTE! Resources in subfolders must append to QRC_FILES using the following statement
|
||||
# set( QRC_FILES
|
||||
# ${QRC_FILES}
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/Resources/myLibrary.qrc
|
||||
# PARENT_SCOPE
|
||||
# )
|
||||
|
||||
set( QRC_FILES
|
||||
${QRC_FILES}
|
||||
Resources/ResInsight.qrc
|
||||
)
|
||||
|
||||
# Runs RCC on specified files
|
||||
qt4_add_resources( QRC_FILES_CPP ${QRC_FILES} )
|
||||
|
||||
|
||||
#############################################################################
|
||||
# creating PCH's for MSVC and GCC on Linux
|
||||
#############################################################################
|
||||
|
||||
set( RAW_SOURCES ${CPP_SOURCES} )
|
||||
list( REMOVE_ITEM RAW_SOURCES RIStdInclude.cpp)
|
||||
list( REMOVE_ITEM RAW_SOURCES ReservoirDataModel/RigReaderInterfaceECL.cpp)
|
||||
list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivCellEdgeEffectGenerator.cpp)
|
||||
list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivPipeGeometryGenerator.cpp)
|
||||
list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivWellPipesPartMgr.cpp)
|
||||
list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivWellHeadPartMgr.cpp)
|
||||
|
||||
|
||||
list( REMOVE_ITEM RAW_SOURCES
|
||||
FileInterface/RifReaderEclipseFileAccess.cpp
|
||||
FileInterface/RifReaderEclipseRestartFiles.cpp
|
||||
FileInterface/RifReaderEclipseResultAccess.cpp
|
||||
FileInterface/RifReaderEclipseUnifiedRestartFile.cpp
|
||||
FileInterface/RifReaderInterfaceEcl.cpp
|
||||
)
|
||||
|
||||
include( CustomPCH.cmake )
|
||||
set( ALL_INCLUDES
|
||||
${LibCore_SOURCE_DIR}
|
||||
${LibGeometry_SOURCE_DIR}
|
||||
${LibGuiQt_SOURCE_DIR}
|
||||
${LibRender_SOURCE_DIR}
|
||||
${LibViewing_SOURCE_DIR}
|
||||
${QT_INCLUDES}
|
||||
)
|
||||
|
||||
set( PCH_NAME RIStdInclude )
|
||||
set( GCC_PCH_TARGET gccPCH )
|
||||
set( PCH_COMPILER_DEFINE EMPTY )
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set( PCH_COMPILER_DEFINE CVF_LINUX)
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
precompiled_header( RAW_SOURCES ALL_INCLUDES ${GCC_PCH_TARGET} ${PCH_NAME} ${PCH_COMPILER_DEFINE} )
|
||||
|
||||
################################################################################
|
||||
|
||||
|
||||
|
||||
add_executable(ResInsight
|
||||
${CPP_SOURCES}
|
||||
${MOC_FILES_CPP}
|
||||
${QRC_FILES_CPP}
|
||||
${HEADER_FILES}
|
||||
)
|
||||
|
||||
|
||||
set( LINK_LIBRARIES
|
||||
cafProjectDataModel
|
||||
cafPdmCvf
|
||||
cafUserInterface
|
||||
cafViewer
|
||||
cafAnimControl
|
||||
CommonCode
|
||||
QtPropertyBrowser
|
||||
LibGuiQt
|
||||
LibViewing
|
||||
LibRender
|
||||
LibGeometry
|
||||
LibCore
|
||||
${OPENGL_LIBRARIES}
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set ( LINUX_LINK_LIBRARIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert/ecl/lib/libecl.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert/util/lib/libutil.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert/geometry/lib/libgeometry.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert/well/lib/libwell.a
|
||||
lapack
|
||||
)
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
target_link_libraries( ResInsight ${LINK_LIBRARIES} ${LINUX_LINK_LIBRARIES})
|
||||
|
||||
# Copy Qt Dlls
|
||||
if (MSVC)
|
||||
set (QTLIBLIST QtCore QtGui QtOpenGl QtNetwork)
|
||||
foreach (qtlib ${QTLIBLIST})
|
||||
|
||||
# Debug
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}d4.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug/${qtlib}d4.dll)
|
||||
|
||||
# Release
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/${qtlib}4.dll)
|
||||
|
||||
# Release With debug info
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/${qtlib}4.dll)
|
||||
|
||||
endforeach( qtlib )
|
||||
endif(MSVC)
|
||||
|
||||
#############################################################################
|
||||
# Install
|
||||
#############################################################################
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set_target_properties(ResInsight PROPERTIES INSTALL_RPATH "${RESINSIGHT_FINAL_INSTALL_PATH};.")
|
||||
set (RESINSIGHT_FILES
|
||||
${QT_LIBRARY_DIR}/libQtCore.so.4.7.3
|
||||
${QT_LIBRARY_DIR}/libQtGui.so.4.7.3
|
||||
${QT_LIBRARY_DIR}/libQtOpenGL.so.4.7.3
|
||||
${QT_LIBRARY_DIR}/libQtNetwork.so.4.7.3
|
||||
${QT_LIBRARY_DIR}/libQtCore.so.4
|
||||
${QT_LIBRARY_DIR}/libQtGui.so.4
|
||||
${QT_LIBRARY_DIR}/libQtOpenGL.so.4
|
||||
${QT_LIBRARY_DIR}/libQtNetwork.so.4
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
set (RESINSIGHT_FILES
|
||||
${QT_LIBRARY_DIR}/QtCore4.dll
|
||||
${QT_LIBRARY_DIR}/QtGui4.dll
|
||||
${QT_LIBRARY_DIR}/QtOpenGL4.dll
|
||||
${QT_LIBRARY_DIR}/QtNetwork4.dll
|
||||
)
|
||||
endif()
|
||||
|
||||
set (RESINSIGHT_FILES ${RESINSIGHT_FILES}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Adm/LicenseInformation.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Adm/gplLicense.txt
|
||||
)
|
||||
|
||||
|
||||
install(TARGETS ResInsight DESTINATION ${RESINSIGHT_FINAL_NAME})
|
||||
|
||||
install(FILES ${RESINSIGHT_FILES} DESTINATION ${RESINSIGHT_FINAL_NAME} )
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resinsight DESTINATION ${RESINSIGHT_FINAL_NAME} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
|
||||
|
||||
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "No_Linux")
|
||||
install(CODE "
|
||||
set (INSTALLFILE_LIST
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ResInsight
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Adm/LicenseInformation.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Adm/gplLicense.txt
|
||||
${QT_LIBRARY_DIR}/libQtCore.so.4
|
||||
${QT_LIBRARY_DIR}/libQtGui.so.4
|
||||
${QT_LIBRARY_DIR}/libQtOpenGL.so.4
|
||||
/usr/lib64/libgfortran.so.1
|
||||
/usr/lib64/liblapack.so.3
|
||||
/usr/lib64/libblas.so.3
|
||||
)
|
||||
execute_process(COMMAND rm -r ${CMAKE_BINARY_DIR}/Install/ResInsight )
|
||||
execute_process(COMMAND mkdir -p ${CMAKE_BINARY_DIR}/Install/ResInsight )
|
||||
foreach (installFile \${INSTALLFILE_LIST})
|
||||
execute_process(COMMAND cp -v \${installFile} ${CMAKE_BINARY_DIR}/Install/ResInsight)
|
||||
endforeach (installFile)
|
||||
|
||||
execute_process(COMMAND bash -c \"cd ${CMAKE_BINARY_DIR}/Install/ ; tar cvzf ResInsight_${STRPRODUCTVER}-bin.tar.gz ResInsight/*\" )
|
||||
|
||||
")
|
||||
endif()
|
||||
92
ApplicationCode/CustomPCH.cmake
Normal file
92
ApplicationCode/CustomPCH.cmake
Normal file
@@ -0,0 +1,92 @@
|
||||
|
||||
# DON'T FORGET to include ${CMAKE_CURRENT_SOURCE_DIR} in include_directories for the compiler
|
||||
# to see the header, and ${CMAKE_CURRENT_BINARY_DIR} for the compiler to see the GCC PCH
|
||||
|
||||
# "sources" - unexpanded cmake variable holding all the source files
|
||||
# "includes" - unexpanded cmake variable holding all include paths the PCH needs to know about
|
||||
# "target_name" - the name of the a special target used to build the PCH for GCC
|
||||
# "header_name" - the name of the PCH header, without the extension; "stdafx" or something similar;
|
||||
# note that the source file compiling the header needs to have the same name
|
||||
macro( precompiled_header sources includes target_name header_name compiler_defines )
|
||||
|
||||
# MSVC precompiled headers cmake code
|
||||
if ( MSVC )
|
||||
set_source_files_properties( ${header_name}.cpp PROPERTIES COMPILE_FLAGS "/Yc${header_name}.h" )
|
||||
|
||||
foreach( src_file ${${sources}} )
|
||||
if( ${src_file} MATCHES ".*cpp$" )
|
||||
set_source_files_properties( ${src_file} PROPERTIES COMPILE_FLAGS "/Yu${header_name}.h" )
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# ${header_name}.cpp has to come before ${header_name}.h,
|
||||
# otherwise we get a linker error...
|
||||
list( INSERT ${sources} 0 ${header_name}.h )
|
||||
list( INSERT ${sources} 0 ${header_name}.cpp )
|
||||
|
||||
# GCC precompiled headers cmake code
|
||||
# We don't do this on Macs since GCC there goes haywire
|
||||
# when you try to generate a PCH with two "-arch" flags
|
||||
elseif( CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE )
|
||||
|
||||
# Get the compiler flags for this build type
|
||||
string( TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" flags_for_build_name )
|
||||
set( compile_flags ${${flags_for_build_name}} )
|
||||
|
||||
# Add all the Qt include directories
|
||||
foreach( item ${${includes}} )
|
||||
list( APPEND compile_flags "-I${item}" )
|
||||
endforeach()
|
||||
|
||||
# Get the list of all build-independent preprocessor definitions
|
||||
get_directory_property( defines_global COMPILE_DEFINITIONS )
|
||||
list( APPEND defines ${defines_global} )
|
||||
|
||||
# Get the list of all build-dependent preprocessor definitions
|
||||
string( TOUPPER "COMPILE_DEFINITIONS_${CMAKE_BUILD_TYPE}" defines_for_build_name )
|
||||
get_directory_property( defines_build ${defines_for_build_name} )
|
||||
list( APPEND defines ${defines_build} )
|
||||
|
||||
# Apppend special compiler defines
|
||||
list( APPEND defines ${compiler_defines} )
|
||||
|
||||
# Add the "-D" prefix to all of them
|
||||
foreach( item ${defines} )
|
||||
list( APPEND all_define_flags "-D${item}" )
|
||||
endforeach()
|
||||
|
||||
list( APPEND compile_flags ${all_define_flags} )
|
||||
|
||||
# Prepare the compile flags var for passing to GCC
|
||||
separate_arguments( compile_flags )
|
||||
|
||||
# Finally, build the precompiled header.
|
||||
# We don't add the buil command to add_custom_target
|
||||
# because that would force a PCH rebuild even when
|
||||
# the ${header_name}.h file hasn't changed. We add it to
|
||||
# a special add_custom_command to work around this problem.
|
||||
add_custom_target( ${target_name} ALL
|
||||
DEPENDS ${header_name}.h.gch
|
||||
)
|
||||
|
||||
add_custom_command( OUTPUT ${header_name}.h.gch
|
||||
COMMAND ${CMAKE_CXX_COMPILER} ${compile_flags} ${CMAKE_CURRENT_SOURCE_DIR}/${header_name}.h -o ${header_name}.h.gch
|
||||
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${header_name}.h
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
VERBATIM )
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Xcode PCH support. Has to be called *AFTER* the target is created.
|
||||
# "header_name" - the name of the PCH header, without the extension; "stdafx" or something similar;
|
||||
# note that the source file compiling the header needs to have the same name
|
||||
macro( xcode_pch header_name )
|
||||
if( APPLE )
|
||||
set_target_properties(
|
||||
${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/${PCH_NAME}.h"
|
||||
XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES"
|
||||
)
|
||||
endif()
|
||||
endmacro()
|
||||
@@ -0,0 +1,119 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
SET (ProjectName FileInterface_UnitTests)
|
||||
project ( ${ProjectName} )
|
||||
|
||||
# Qt
|
||||
find_package (Qt4 COMPONENTS QtCore QtGui QtMain QtOpenGl REQUIRED)
|
||||
include (${QT_USE_FILE})
|
||||
|
||||
include_directories(
|
||||
${LibCore_SOURCE_DIR}
|
||||
${LibGeometry_SOURCE_DIR}
|
||||
${LibRender_SOURCE_DIR}
|
||||
${LibViewing_SOURCE_DIR}
|
||||
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/FileInterface
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ProjectDataModel
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty
|
||||
|
||||
${ResInsight_SOURCE_DIR}/cafProjectDataModel
|
||||
|
||||
${ResInsight_SOURCE_DIR}/CommonCode
|
||||
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty/Ert/ecl/include
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty/Ert/util/include
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty/Ert/well/include
|
||||
|
||||
)
|
||||
|
||||
set( FILEINTERFACE_CPP_SOURCES
|
||||
../RifReaderEclipseFileAccess.cpp
|
||||
../RifReaderEclipseRestartFiles.cpp
|
||||
../RifReaderEclipseResultAccess.cpp
|
||||
../RifReaderEclipseUnifiedRestartFile.cpp
|
||||
../RifReaderInterfaceEcl.cpp
|
||||
../RifReaderInterfaceMock.cpp
|
||||
)
|
||||
|
||||
set( RESERVOIRDATAMODEL_CPP_SOURCES
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigCell.cpp
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigGridBase.cpp
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigReservoir.cpp
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.cpp
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigWellResults.cpp
|
||||
)
|
||||
|
||||
set( CPP_SOURCES
|
||||
${FILEINTERFACE_CPP_SOURCES}
|
||||
${RESERVOIRDATAMODEL_CPP_SOURCES}
|
||||
)
|
||||
|
||||
source_group( "FileInterface" FILES ${FILEINTERFACE_CPP_SOURCES} )
|
||||
source_group( "ReservoirDataModel" FILES ${RESERVOIRDATAMODEL_CPP_SOURCES} )
|
||||
|
||||
set( UNIT_TEST_CPP_SOURCES
|
||||
main.cpp
|
||||
RifReaderInterfaceEcl-Test.cpp
|
||||
Ert-Test.cpp
|
||||
)
|
||||
|
||||
|
||||
set( LINK_LIBRARIES
|
||||
CommonCode
|
||||
|
||||
LibViewing
|
||||
LibRender
|
||||
LibGeometry
|
||||
LibCore
|
||||
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
|
||||
add_executable( ${ProjectName}
|
||||
${CPP_SOURCES}
|
||||
${UNIT_TEST_CPP_SOURCES}
|
||||
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty/gtest/gtest-all.cc
|
||||
)
|
||||
|
||||
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set ( LINUX_LINK_LIBRARIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../ThirdParty/Ert/ecl/lib/libecl.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../ThirdParty/Ert/util/lib/libutil.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../ThirdParty/Ert/well/lib/libwell.a
|
||||
lapack
|
||||
)
|
||||
|
||||
# Linux specific code
|
||||
set(CMAKE_CXX_FLAGS "-DCVF_LINUX -DUSE_ECL_LIB -pipe -Wextra -Woverloaded-virtual -Wformat")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG -D_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNO_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
|
||||
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
|
||||
target_link_libraries( ${ProjectName} ${LINK_LIBRARIES} ${LINUX_LINK_LIBRARIES})
|
||||
|
||||
|
||||
# Copy Qt Dlls
|
||||
if (MSVC)
|
||||
set (QTLIBLIST QtCore QtGui QtOpenGl)
|
||||
foreach (qtlib ${QTLIBLIST})
|
||||
|
||||
# Debug
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}d4.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug/${qtlib}d4.dll)
|
||||
|
||||
# Release
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/${qtlib}4.dll)
|
||||
endforeach( qtlib )
|
||||
endif(MSVC)
|
||||
@@ -0,0 +1,104 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
|
||||
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <util.h>
|
||||
#include <int_vector.h>
|
||||
#include <ecl_intehead.h>
|
||||
#include <ecl_file.h>
|
||||
#include <ecl_kw.h>
|
||||
#include <ecl_kw_magic.h>
|
||||
#include <ecl_util.h>
|
||||
|
||||
#include <well_state.h>
|
||||
#include <well_info.h>
|
||||
#include <well_conn.h>
|
||||
#include <well_ts.h>
|
||||
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// This file contains test code taken from the test cases in ERT source code.
|
||||
// There is a typedef issue (center) between ERT and QTextStream, so this file does not include any
|
||||
// Qt files.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(RigReservoirTest, WellTestErt)
|
||||
{
|
||||
char filename[1024] = "/mnt/hgfs/Statoil/testcase_juli_2011/data/TEST10K_FLT_LGR_NNC.UNRST";
|
||||
|
||||
well_info_type * well_info = well_info_alloc( NULL );
|
||||
well_info_load_rstfile( well_info , filename);
|
||||
|
||||
// List all wells:
|
||||
{
|
||||
int iwell;
|
||||
for (iwell = 0; iwell < well_info_get_num_wells( well_info ); iwell++)
|
||||
{
|
||||
printf("Well[%02d] : %s \n",iwell , well_info_iget_well_name( well_info , iwell));
|
||||
}
|
||||
}
|
||||
|
||||
// Look at the timeseries for one well:
|
||||
{
|
||||
well_ts_type * well_ts = well_info_get_ts( well_info , well_info_iget_well_name( well_info , 0));
|
||||
for (int i =0; i < well_ts_get_size( well_ts ); i++)
|
||||
{
|
||||
well_state_type * well_state = well_ts_iget_state( well_ts , i );
|
||||
|
||||
printf("Well:%s report:%04d state:",well_state_get_name( well_state ), well_state_get_report_nr( well_state ));
|
||||
if (well_state_is_open( well_state ))
|
||||
printf("OPEN\n");
|
||||
else
|
||||
printf("CLOSED\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Look at one well_state:
|
||||
{
|
||||
well_state_type * well_state = well_info_iiget_state( well_info , 0 , 0 );
|
||||
printf("Well:%s report:%04d \n",well_state_get_name( well_state ), well_state_get_report_nr( well_state ));
|
||||
{
|
||||
int branchCount = well_state_get_num_branches(well_state);
|
||||
for (int ibranch = 0 ; ibranch < branchCount; ++ibranch)
|
||||
{
|
||||
printf("Branch: %d", ibranch);
|
||||
for (int iconn = 0; iconn < well_state_get_num_connections( well_state, ibranch ); iconn++)
|
||||
{
|
||||
const well_conn_type * conn = well_state_get_connections( well_state , ibranch)[iconn];
|
||||
printf("Connection:%02d i=%3d j=%3d k=%3d State:",iconn , conn->i, conn->j , conn->k);
|
||||
if (conn->open)
|
||||
printf("Open\n");
|
||||
else
|
||||
printf("Closed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
well_info_free( well_info );
|
||||
}
|
||||
|
||||
#endif //USE_ECL_LIB
|
||||
@@ -0,0 +1,99 @@
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "RigReservoir.h"
|
||||
|
||||
#include "RifReaderInterfaceEcl.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(RigReservoirTest, BasicTest)
|
||||
{
|
||||
cvf::ref<RifReaderInterfaceECL> readerInterfaceEcl = new RifReaderInterfaceECL;
|
||||
cvf::ref<RigReservoir> reservoir = new RigReservoir;
|
||||
|
||||
// Location of test dataset received from Håkon Høgstøl in July 2011 with 10k active cells
|
||||
QString filename("/mnt/hgfs/Statoil/testcase_juli_2011/data/TEST10K_FLT_LGR_NNC.EGRID");
|
||||
|
||||
bool result = readerInterfaceEcl->open(filename, reservoir.p());
|
||||
EXPECT_TRUE(result);
|
||||
|
||||
{
|
||||
QStringList staticResults = readerInterfaceEcl->staticResults();
|
||||
EXPECT_EQ(42, staticResults.size());
|
||||
qDebug() << "Static results\n" << staticResults;
|
||||
|
||||
QStringList dynamicResults = readerInterfaceEcl->dynamicResults();
|
||||
EXPECT_EQ(23, dynamicResults.size());
|
||||
qDebug() << "Dynamic results\n" << dynamicResults;
|
||||
|
||||
int numTimeSteps = static_cast<int>(readerInterfaceEcl->numTimeSteps());
|
||||
EXPECT_EQ(9, numTimeSteps);
|
||||
|
||||
QStringList timeStepText = readerInterfaceEcl->timeStepText();
|
||||
EXPECT_EQ(numTimeSteps, timeStepText.size());
|
||||
qDebug() << "Time step texts\n" << timeStepText;
|
||||
}
|
||||
|
||||
|
||||
readerInterfaceEcl->close();
|
||||
|
||||
{
|
||||
QStringList staticResults = readerInterfaceEcl->staticResults();
|
||||
EXPECT_EQ(0, staticResults.size());
|
||||
|
||||
QStringList dynamicResults = readerInterfaceEcl->dynamicResults();
|
||||
EXPECT_EQ(0, dynamicResults.size());
|
||||
|
||||
int numTimeSteps = static_cast<int>(readerInterfaceEcl->numTimeSteps());
|
||||
EXPECT_EQ(0, numTimeSteps);
|
||||
|
||||
QStringList timeStepText = readerInterfaceEcl->timeStepText();
|
||||
EXPECT_EQ(numTimeSteps, timeStepText.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(RigReservoirTest, WellTest)
|
||||
{
|
||||
cvf::ref<RifReaderInterfaceECL> readerInterfaceEcl = new RifReaderInterfaceECL;
|
||||
cvf::ref<RigReservoir> reservoir = new RigReservoir;
|
||||
|
||||
// Location of test dataset received from Håkon Høgstøl in July 2011 with 10k active cells
|
||||
QString filename("/mnt/hgfs/Statoil/testcase_juli_2011/data/TEST10K_FLT_LGR_NNC.EGRID");
|
||||
|
||||
bool result = readerInterfaceEcl->open(filename, reservoir.p());
|
||||
EXPECT_TRUE(result);
|
||||
|
||||
cvf::UByteArray* mainGridWellCells = reservoir->wellCellsInGrid(0);
|
||||
EXPECT_TRUE(mainGridWellCells->size() == reservoir->mainGrid()->cellCount());
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cvfTrace.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cvf::Assert::setReportMode(cvf::Assert::CONSOLE);
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
std::cout << "Please press <Enter> to close the window.";
|
||||
std::cin.get();
|
||||
|
||||
return result;
|
||||
}
|
||||
365
ApplicationCode/FileInterface/RifReaderEclipseFileAccess.cpp
Normal file
365
ApplicationCode/FileInterface/RifReaderEclipseFileAccess.cpp
Normal file
@@ -0,0 +1,365 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RifReaderEclipseFileAccess.h"
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
#include "ecl_file.h"
|
||||
#include "ecl_intehead.h"
|
||||
#endif //USE_ECL_LIB
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseFileAccess::RifReaderEclipseFileAccess()
|
||||
{
|
||||
#ifdef USE_ECL_LIB
|
||||
m_file = NULL;
|
||||
#endif //USE_ECL_LIB
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseFileAccess::~RifReaderEclipseFileAccess()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Open file given by name
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseFileAccess::open(const QString& fileName)
|
||||
{
|
||||
#ifdef USE_ECL_LIB
|
||||
// Close current file if any
|
||||
close();
|
||||
|
||||
m_file = ecl_file_open(fileName.toAscii().data());
|
||||
if (!m_file) return false;
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif //USE_ECL_LIB
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Close file
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderEclipseFileAccess::close()
|
||||
{
|
||||
#ifdef USE_ECL_LIB
|
||||
if (m_file)
|
||||
{
|
||||
ecl_file_close(m_file);
|
||||
m_file = NULL;
|
||||
}
|
||||
#endif //USE_ECL_LIB
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the number of occurrences of the given keyword
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RifReaderEclipseFileAccess::numOccurrences(const QString& keyword)
|
||||
{
|
||||
#ifdef USE_ECL_LIB
|
||||
CVF_ASSERT(m_file);
|
||||
return (size_t) ecl_file_get_num_named_kw(m_file, keyword.toAscii().data());
|
||||
#else
|
||||
return 0;
|
||||
#endif //USE_ECL_LIB
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get keywords found on file given by name.
|
||||
/// If numDataItems > -1, get keywords with that exact number of data items only.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseFileAccess::keywordsOnFile(QStringList* keywords, size_t numDataItems, size_t numSteps)
|
||||
{
|
||||
#ifdef USE_ECL_LIB
|
||||
CVF_ASSERT(m_file);
|
||||
CVF_ASSERT(keywords);
|
||||
keywords->clear();
|
||||
|
||||
size_t numKeywords = ecl_file_get_num_distinct_kw(m_file);
|
||||
size_t i;
|
||||
for (i = 0; i < numKeywords; i++)
|
||||
{
|
||||
const char* kw = ecl_file_iget_distinct_kw(m_file , i);
|
||||
size_t numKWOccurences = ecl_file_get_num_named_kw(m_file, kw);
|
||||
|
||||
if (numDataItems != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
bool dataTypeSupported = true;
|
||||
size_t numKWValues = 0;
|
||||
size_t j;
|
||||
for (j = 0; j < numKWOccurences; j++)
|
||||
{
|
||||
numKWValues += (size_t) ecl_file_iget_named_size(m_file, kw, j);
|
||||
|
||||
// Check the data type - only float and double are supported
|
||||
ecl_type_enum dataType = ecl_file_iget_named_type(m_file, kw, j);
|
||||
if (dataType != ECL_DOUBLE_TYPE && dataType != ECL_FLOAT_TYPE && dataType != ECL_INT_TYPE )
|
||||
{
|
||||
dataTypeSupported = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dataTypeSupported)
|
||||
{
|
||||
if (numSteps != cvf::UNDEFINED_SIZE_T && numSteps > 0)
|
||||
{
|
||||
numKWValues /= numSteps;
|
||||
}
|
||||
|
||||
// Append keyword to the list if it has the given number of values in total
|
||||
if (numKWValues == numDataItems)
|
||||
{
|
||||
keywords->append(QString(kw));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
keywords->append(QString(kw));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif //USE_ECL_LIB
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get list of time step texts (dates)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseFileAccess::timeStepsText(QStringList* timeSteps)
|
||||
{
|
||||
#ifdef USE_ECL_LIB
|
||||
CVF_ASSERT(timeSteps);
|
||||
CVF_ASSERT(m_file);
|
||||
|
||||
const char* KW_INTEHEAD = "INTEHEAD";
|
||||
|
||||
// Get the number of occurrences of the INTEHEAD keyword
|
||||
size_t numINTEHEAD = numOccurrences(KW_INTEHEAD);
|
||||
|
||||
QStringList timeStepsFound;
|
||||
size_t i;
|
||||
for (i = 0; i < numINTEHEAD; i++)
|
||||
{
|
||||
ecl_kw_type* kwINTEHEAD = ecl_file_iget_named_kw(m_file, KW_INTEHEAD, i);
|
||||
if (kwINTEHEAD)
|
||||
{
|
||||
// Get date info
|
||||
time_t stepTime = util_make_date(ecl_kw_iget_int(kwINTEHEAD, INTEHEAD_DAY_INDEX),
|
||||
ecl_kw_iget_int(kwINTEHEAD, INTEHEAD_MONTH_INDEX),
|
||||
ecl_kw_iget_int(kwINTEHEAD, INTEHEAD_YEAR_INDEX));
|
||||
|
||||
// Hack!!! We seem to get 01/01/1970 (time -1) for sub grids!
|
||||
if (stepTime < 0) continue;
|
||||
|
||||
// Build date string
|
||||
char* dateString = util_alloc_date_string(stepTime);
|
||||
timeStepsFound += QString(dateString);
|
||||
util_safe_free(dateString);
|
||||
}
|
||||
}
|
||||
|
||||
// Time steps are given for both the main grid and all sub grids,
|
||||
// so we need to make sure that duplicates are removed
|
||||
timeStepsFound.removeDuplicates();
|
||||
|
||||
// Return time step info to caller
|
||||
*timeSteps = timeStepsFound;
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif //USE_ECL_LIB
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get list of time step texts (dates)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseFileAccess::timeSteps(QList<QDateTime>* timeSteps)
|
||||
{
|
||||
#ifdef USE_ECL_LIB
|
||||
CVF_ASSERT(timeSteps);
|
||||
CVF_ASSERT(m_file);
|
||||
|
||||
const char* KW_INTEHEAD = "INTEHEAD";
|
||||
|
||||
// Get the number of occurrences of the INTEHEAD keyword
|
||||
size_t numINTEHEAD = numOccurrences(KW_INTEHEAD);
|
||||
|
||||
QList<QDateTime> timeStepsFound;
|
||||
size_t i;
|
||||
for (i = 0; i < numINTEHEAD; i++)
|
||||
{
|
||||
ecl_kw_type* kwINTEHEAD = ecl_file_iget_named_kw(m_file, KW_INTEHEAD, i);
|
||||
if (kwINTEHEAD)
|
||||
{
|
||||
// Get date info
|
||||
time_t stepTime = util_make_date(ecl_kw_iget_int(kwINTEHEAD, INTEHEAD_DAY_INDEX),
|
||||
ecl_kw_iget_int(kwINTEHEAD, INTEHEAD_MONTH_INDEX),
|
||||
ecl_kw_iget_int(kwINTEHEAD, INTEHEAD_YEAR_INDEX));
|
||||
|
||||
// Hack!!! We seem to get 01/01/1970 (time -1) for sub grids!
|
||||
if (stepTime < 0) continue;
|
||||
|
||||
// Build date string
|
||||
QDateTime dateTime = QDateTime::fromTime_t(stepTime);
|
||||
|
||||
if (timeStepsFound.indexOf(dateTime) < 0)
|
||||
{
|
||||
timeStepsFound.push_back(dateTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return time step info to caller
|
||||
*timeSteps = timeStepsFound;
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif //USE_ECL_LIB
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get first occurrence of file of given type in given list of filenames, as filename or NULL if not found
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseFileAccess::keywordData(const QString& keyword, size_t index, std::vector<double>* values)
|
||||
{
|
||||
#ifdef USE_ECL_LIB
|
||||
CVF_ASSERT(m_file);
|
||||
CVF_ASSERT(values);
|
||||
|
||||
ecl_kw_type* kwData = ecl_file_iget_named_kw(m_file, keyword.toAscii().data(), index);
|
||||
if (kwData)
|
||||
{
|
||||
size_t numValues = ecl_kw_get_size(kwData);
|
||||
|
||||
std::vector<double> doubleData;
|
||||
doubleData.resize(numValues);
|
||||
|
||||
ecl_kw_get_data_as_double(kwData, doubleData.data());
|
||||
values->insert(values->end(), doubleData.begin(), doubleData.end());
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif //USE_ECL_LIB
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get first occurrence of file of given type in given list of filenames, as filename or NULL if not found
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#ifdef USE_ECL_LIB
|
||||
QString RifReaderEclipseFileAccess::fileNameByType(const QStringList& fileSet, ecl_file_enum fileType)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < fileSet.count(); i++)
|
||||
{
|
||||
bool formatted = false;
|
||||
int reportNumber = -1;
|
||||
if (ecl_util_get_file_type(fileSet.at(i).toAscii().data(), &formatted, &reportNumber) == fileType)
|
||||
{
|
||||
return QString(fileSet.at(i).data());
|
||||
}
|
||||
}
|
||||
|
||||
return QString::null;
|
||||
}
|
||||
#endif //USE_ECL_LIB
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get all files of file of given type in given list of filenames, as filename or NULL if not found
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#ifdef USE_ECL_LIB
|
||||
QStringList RifReaderEclipseFileAccess::fileNamesByType(const QStringList& fileSet, ecl_file_enum fileType)
|
||||
{
|
||||
QStringList fileNames;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < fileSet.count(); i++)
|
||||
{
|
||||
bool formatted = false;
|
||||
int reportNumber = -1;
|
||||
if (ecl_util_get_file_type(fileSet.at(i).toAscii().data(), &formatted, &reportNumber) == fileType)
|
||||
{
|
||||
fileNames.append(QString(fileSet.at(i).data()));
|
||||
}
|
||||
}
|
||||
|
||||
return fileNames;
|
||||
}
|
||||
#endif //USE_ECL_LIB
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get set of Eclipse files based on an input file and its path
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseFileAccess::fileSet(const QString& fileName, QStringList* fileSet)
|
||||
{
|
||||
CVF_ASSERT(fileSet);
|
||||
fileSet->clear();
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
QString filePath = QFileInfo(fileName).path();
|
||||
QString fileNameBase = QFileInfo(fileName).baseName();
|
||||
|
||||
stringlist_type* eclipseFiles = stringlist_alloc_new();
|
||||
ecl_util_select_filelist(filePath.toAscii().data(), fileNameBase.toAscii().data(), ECL_OTHER_FILE, false, eclipseFiles);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < stringlist_get_size(eclipseFiles); i++)
|
||||
{
|
||||
fileSet->append(stringlist_safe_iget(eclipseFiles, i));
|
||||
}
|
||||
|
||||
stringlist_free(eclipseFiles);
|
||||
#endif //USE_ECL_LIB
|
||||
|
||||
return fileSet->count() > 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#ifdef USE_ECL_LIB
|
||||
ecl_file_type* RifReaderEclipseFileAccess::filePointer()
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
#endif //USE_ECL_LIB
|
||||
71
ApplicationCode/FileInterface/RifReaderEclipseFileAccess.h
Normal file
71
ApplicationCode/FileInterface/RifReaderEclipseFileAccess.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cvfLibCore.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QDateTime>
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
#include "ecl_file.h"
|
||||
#endif //USE_ECL_LIB
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Class for access to Eclipse "keyword" files using libecl
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifReaderEclipseFileAccess : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RifReaderEclipseFileAccess();
|
||||
virtual ~RifReaderEclipseFileAccess();
|
||||
|
||||
bool open(const QString& fileName);
|
||||
void close();
|
||||
|
||||
size_t numOccurrences(const QString& keyword);
|
||||
bool keywordsOnFile(QStringList* keywords, size_t numDataItems = cvf::UNDEFINED_SIZE_T, size_t numSteps = cvf::UNDEFINED_SIZE_T);
|
||||
|
||||
bool timeStepsText(QStringList* timeSteps);
|
||||
bool timeSteps(QList<QDateTime>* timeSteps);
|
||||
|
||||
bool keywordData(const QString& keyword, size_t index, std::vector<double>* values);
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
ecl_file_type* filePointer();
|
||||
#endif //USE_ECL_LIB
|
||||
|
||||
// Static methods
|
||||
static bool fileSet(const QString& fileName, QStringList* fileSet);
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
static QString fileNameByType(const QStringList& fileSet, ecl_file_enum fileType);
|
||||
static QStringList fileNamesByType(const QStringList& fileSet, ecl_file_enum fileType);
|
||||
#endif //USE_ECL_LIB
|
||||
|
||||
protected:
|
||||
#ifdef USE_ECL_LIB
|
||||
ecl_file_type* m_file;
|
||||
#endif //USE_ECL_LIB
|
||||
};
|
||||
177
ApplicationCode/FileInterface/RifReaderEclipseRestartFiles.cpp
Normal file
177
ApplicationCode/FileInterface/RifReaderEclipseRestartFiles.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RifReaderEclipseRestartFiles.h"
|
||||
#include "RifReaderEclipseFileAccess.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseRestartFiles::RifReaderEclipseRestartFiles(size_t numGrids, size_t numActiveCells)
|
||||
: RifReaderEclipseResultsAccess(numGrids, numActiveCells)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseRestartFiles::~RifReaderEclipseRestartFiles()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Open files
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseRestartFiles::open(const QStringList& fileSet)
|
||||
{
|
||||
close();
|
||||
|
||||
size_t numFiles = fileSet.size();
|
||||
size_t i;
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
cvf::ref<RifReaderEclipseFileAccess> fileAccess = new RifReaderEclipseFileAccess;
|
||||
if (!fileAccess->open(fileSet[i]))
|
||||
{
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_files.push_back(fileAccess);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Close files
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderEclipseRestartFiles::close()
|
||||
{
|
||||
m_files.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the number of time steps
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RifReaderEclipseRestartFiles::numTimeSteps()
|
||||
{
|
||||
return m_files.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the time step texts
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RifReaderEclipseRestartFiles::timeStepsText()
|
||||
{
|
||||
QStringList timeSteps;
|
||||
|
||||
size_t numSteps = numTimeSteps();
|
||||
size_t i;
|
||||
for (i = 0; i < numSteps; i++)
|
||||
{
|
||||
QStringList stepText;
|
||||
m_files[i]->timeStepsText(&stepText);
|
||||
timeSteps.append(stepText.size() == 1 ? stepText : QStringList(QString("Step %1").arg(i+1)));
|
||||
}
|
||||
|
||||
return timeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the time steps
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<QDateTime> RifReaderEclipseRestartFiles::timeSteps()
|
||||
{
|
||||
QList<QDateTime> timeSteps;
|
||||
|
||||
size_t numSteps = numTimeSteps();
|
||||
size_t i;
|
||||
for (i = 0; i < numSteps; i++)
|
||||
{
|
||||
QList<QDateTime> stepTime;
|
||||
m_files[i]->timeSteps(&stepTime);
|
||||
|
||||
if (stepTime.size() == 1)
|
||||
{
|
||||
timeSteps.push_back(stepTime[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeSteps.push_back(QDateTime());
|
||||
}
|
||||
}
|
||||
|
||||
return timeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get list of result names
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RifReaderEclipseRestartFiles::resultNames()
|
||||
{
|
||||
CVF_ASSERT(numTimeSteps() > 0);
|
||||
|
||||
// Get the results found on the first file
|
||||
QStringList resultsList;
|
||||
m_files[0]->keywordsOnFile(&resultsList, m_numActiveCells, 1);
|
||||
|
||||
return resultsList;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get result values for given time step
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseRestartFiles::results(const QString& resultName, size_t timeStep, std::vector<double>* values)
|
||||
{
|
||||
size_t numOccurrences = m_files[timeStep]->numOccurrences(resultName);
|
||||
CVF_ASSERT(m_numGrids == numOccurrences);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < numOccurrences; i++)
|
||||
{
|
||||
std::vector<double> partValues;
|
||||
if (!m_files[timeStep]->keywordData(resultName, i, &partValues)) // !! don't need to append afterwards
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
values->insert(values->end(), partValues.begin(), partValues.end());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#ifdef USE_ECL_LIB
|
||||
void RifReaderEclipseRestartFiles::readWellData(well_info_type* well_info)
|
||||
{
|
||||
if (!well_info) return;
|
||||
|
||||
size_t i;
|
||||
for (i=0; i < m_files.size(); i++)
|
||||
{
|
||||
well_info_add_UNRST_wells(well_info, m_files[i]->filePointer());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
54
ApplicationCode/FileInterface/RifReaderEclipseRestartFiles.h
Normal file
54
ApplicationCode/FileInterface/RifReaderEclipseRestartFiles.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RifReaderEclipseResultAccess.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RifReaderEclipseFileAccess;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Class for access to results from a set of restart files
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifReaderEclipseRestartFiles : public RifReaderEclipseResultsAccess
|
||||
{
|
||||
public:
|
||||
RifReaderEclipseRestartFiles(size_t numGrids, size_t numActiveCells);
|
||||
virtual ~RifReaderEclipseRestartFiles();
|
||||
|
||||
bool open(const QStringList& fileSet);
|
||||
void close();
|
||||
|
||||
size_t numTimeSteps();
|
||||
QStringList timeStepsText();
|
||||
QList<QDateTime> timeSteps();
|
||||
|
||||
QStringList resultNames();
|
||||
bool results(const QString& resultName, size_t timeStep, std::vector<double>* values);
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
virtual void readWellData(well_info_type* well_info);
|
||||
#endif //USE_ECL_LIB
|
||||
|
||||
private:
|
||||
std::vector< cvf::ref<RifReaderEclipseFileAccess> > m_files;
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RifReaderEclipseResultAccess.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseResultsAccess::RifReaderEclipseResultsAccess(size_t numGrids, size_t numActiveCells)
|
||||
{
|
||||
m_numGrids = numGrids;
|
||||
m_numActiveCells = numActiveCells;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseResultsAccess::~RifReaderEclipseResultsAccess()
|
||||
{
|
||||
}
|
||||
63
ApplicationCode/FileInterface/RifReaderEclipseResultAccess.h
Normal file
63
ApplicationCode/FileInterface/RifReaderEclipseResultAccess.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cvfLibCore.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <QDateTime>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
#include "well_info.h"
|
||||
#endif // USE_ECL_LIB
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Abstract class for results access
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifReaderEclipseResultsAccess : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RifReaderEclipseResultsAccess(size_t numGrids, size_t numActiveCells);
|
||||
virtual ~RifReaderEclipseResultsAccess();
|
||||
|
||||
virtual bool open(const QStringList& fileSet) = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual size_t numTimeSteps() = 0;
|
||||
virtual QStringList timeStepsText() = 0;
|
||||
virtual QList<QDateTime> timeSteps() = 0;
|
||||
|
||||
virtual QStringList resultNames() = 0;
|
||||
virtual bool results(const QString& resultName, size_t timeStep, std::vector<double>* values) = 0;
|
||||
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
virtual void readWellData(well_info_type * well_info) = 0;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
size_t m_numGrids;
|
||||
size_t m_numActiveCells;
|
||||
};
|
||||
@@ -0,0 +1,164 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RifReaderEclipseUnifiedRestartFile.h"
|
||||
#include "RifReaderEclipseFileAccess.h"
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
#include <well_state.h>
|
||||
#include <well_info.h>
|
||||
#include <well_conn.h>
|
||||
#include <well_ts.h>
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseUnifiedRestartFile::RifReaderEclipseUnifiedRestartFile(size_t numGrids, size_t numActiveCells)
|
||||
: RifReaderEclipseResultsAccess(numGrids, numActiveCells)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseUnifiedRestartFile::~RifReaderEclipseUnifiedRestartFile()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Open file
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseUnifiedRestartFile::open(const QStringList& fileSet)
|
||||
{
|
||||
#ifdef USE_ECL_LIB
|
||||
QString fileName = fileSet[0];
|
||||
|
||||
cvf::ref<RifReaderEclipseFileAccess> fileAccess = new RifReaderEclipseFileAccess;
|
||||
if (!fileAccess->open(fileName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_file = fileAccess;
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Close file
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderEclipseUnifiedRestartFile::close()
|
||||
{
|
||||
if (m_file.notNull())
|
||||
{
|
||||
m_file->close();
|
||||
m_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the number of time steps
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RifReaderEclipseUnifiedRestartFile::numTimeSteps()
|
||||
{
|
||||
QStringList timeSteps = timeStepsText();
|
||||
return timeSteps.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the time step texts
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RifReaderEclipseUnifiedRestartFile::timeStepsText()
|
||||
{
|
||||
RifReaderEclipseFileAccess* file = m_file.p();
|
||||
CVF_ASSERT(file != NULL);
|
||||
|
||||
QStringList timeSteps;
|
||||
file->timeStepsText(&timeSteps);
|
||||
|
||||
return timeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the time steps
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<QDateTime> RifReaderEclipseUnifiedRestartFile::timeSteps()
|
||||
{
|
||||
RifReaderEclipseFileAccess* file = m_file.p();
|
||||
CVF_ASSERT(file != NULL);
|
||||
|
||||
QList<QDateTime> timeSteps;
|
||||
file->timeSteps(&timeSteps);
|
||||
|
||||
return timeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get list of result names
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RifReaderEclipseUnifiedRestartFile::resultNames()
|
||||
{
|
||||
// Get the results found on the UNRST file
|
||||
QStringList resultsList;
|
||||
m_file->keywordsOnFile(&resultsList, m_numActiveCells, numTimeSteps());
|
||||
|
||||
return resultsList;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get result values for given time step
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseUnifiedRestartFile::results(const QString& resultName, size_t timeStep, std::vector<double>* values)
|
||||
{
|
||||
size_t numOccurrences = m_file->numOccurrences(resultName);
|
||||
size_t startIndex = timeStep*m_numGrids;
|
||||
CVF_ASSERT(startIndex + m_numGrids <= numOccurrences);
|
||||
|
||||
size_t i;
|
||||
for (i = startIndex; i < startIndex + m_numGrids; i++)
|
||||
{
|
||||
std::vector<double> partValues;
|
||||
if (!m_file->keywordData(resultName, i, &partValues)) // !! don't need to append afterwards
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
values->insert(values->end(), partValues.begin(), partValues.end());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#ifdef USE_ECL_LIB
|
||||
void RifReaderEclipseUnifiedRestartFile::readWellData(well_info_type* well_info)
|
||||
{
|
||||
if (!well_info) return;
|
||||
|
||||
well_info_add_UNRST_wells(well_info, m_file->filePointer());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RifReaderEclipseResultAccess.h"
|
||||
|
||||
class RifReaderEclipseFileAccess;
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
#include "well_info.h"
|
||||
#endif // USE_ECL_LIB
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Class for access to results from a unified restart file
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifReaderEclipseUnifiedRestartFile : public RifReaderEclipseResultsAccess
|
||||
{
|
||||
public:
|
||||
RifReaderEclipseUnifiedRestartFile(size_t numGrids, size_t numActiveCells);
|
||||
virtual ~RifReaderEclipseUnifiedRestartFile();
|
||||
|
||||
bool open(const QStringList& fileSet);
|
||||
void close();
|
||||
|
||||
size_t numTimeSteps();
|
||||
QStringList timeStepsText();
|
||||
QList<QDateTime> timeSteps();
|
||||
|
||||
QStringList resultNames();
|
||||
bool results(const QString& resultName, size_t timeStep, std::vector<double>* values);
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
virtual void readWellData(well_info_type * well_info);
|
||||
#endif
|
||||
|
||||
private:
|
||||
cvf::ref<RifReaderEclipseFileAccess> m_file;
|
||||
};
|
||||
52
ApplicationCode/FileInterface/RifReaderInterface.h
Normal file
52
ApplicationCode/FileInterface/RifReaderInterface.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cvfLibCore.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
|
||||
class RigReservoir;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Data interface base class
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifReaderInterface : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RifReaderInterface() {}
|
||||
virtual ~RifReaderInterface() {}
|
||||
|
||||
virtual bool open(const QString& fileName, RigReservoir* reservoir) = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual const QStringList& staticResults() const = 0;
|
||||
virtual const QStringList& dynamicResults() const = 0;
|
||||
virtual size_t numTimeSteps() const = 0;
|
||||
virtual const QStringList& timeStepText() const = 0;
|
||||
virtual bool staticResult(const QString& result, std::vector<double>* values) = 0;
|
||||
virtual bool dynamicResult(const QString& result, size_t stepIndex, std::vector<double>* values) = 0;
|
||||
};
|
||||
|
||||
609
ApplicationCode/FileInterface/RifReaderInterfaceEcl.cpp
Normal file
609
ApplicationCode/FileInterface/RifReaderInterfaceEcl.cpp
Normal file
@@ -0,0 +1,609 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cvfBase.h"
|
||||
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigReservoir.h"
|
||||
|
||||
#include "RifReaderInterfaceEcl.h"
|
||||
#include "RifReaderEclipseFileAccess.h"
|
||||
#include "RifReaderEclipseUnifiedRestartFile.h"
|
||||
#include "RifReaderEclipseRestartFiles.h"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
#include "ecl_grid.h"
|
||||
#include "well_state.h"
|
||||
#endif //USE_ECL_LIB
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// ECLIPSE cell numbering layout:
|
||||
/// Lower layer: Upper layer
|
||||
///
|
||||
/// 2---3 6---7
|
||||
/// | | | |
|
||||
/// 0---1 4---5
|
||||
///
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
// The indexing conventions for vertices in ECLIPSE
|
||||
//
|
||||
// 6-------------7
|
||||
// /| /|
|
||||
// / | / |
|
||||
// / | / |
|
||||
// 4-------------5 |
|
||||
// | | | |
|
||||
// | 2---------|---3
|
||||
// | / | /
|
||||
// | / | /
|
||||
// |/ |/
|
||||
// 0-------------1
|
||||
// vertex indices
|
||||
//
|
||||
// The indexing conventions for vertices in ResInsight
|
||||
//
|
||||
// 7-------------6
|
||||
// /| /|
|
||||
// / | / |
|
||||
// / | / |
|
||||
// 4-------------5 |
|
||||
// | | | |
|
||||
// | 3---------|---2
|
||||
// | / | /
|
||||
// | / | /
|
||||
// |/ |/
|
||||
// 0-------------1
|
||||
// vertex indices
|
||||
//
|
||||
|
||||
static const size_t cellMappingECLRi[8] = { 0, 1, 3, 2, 4, 5, 7, 6 };
|
||||
|
||||
|
||||
//**************************************************************************************************
|
||||
// Static functions
|
||||
//**************************************************************************************************
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, ecl_grid_type* localEclGrid, size_t activeStartIndex)
|
||||
{
|
||||
int cellCount = ecl_grid_get_global_size(localEclGrid);
|
||||
size_t cellStartIndex = mainGrid->cells().size();
|
||||
size_t nodeStartIndex = mainGrid->nodes().size();
|
||||
|
||||
RigCell defaultCell;
|
||||
defaultCell.setHostGrid(localGrid);
|
||||
mainGrid->cells().resize(cellStartIndex + cellCount, defaultCell);
|
||||
|
||||
mainGrid->nodes().resize(nodeStartIndex + cellCount*8, cvf::Vec3d(0,0,0));
|
||||
|
||||
// Loop over cells and fill them with data
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int gIdx = 0; gIdx < cellCount; ++gIdx)
|
||||
{
|
||||
RigCell& cell = mainGrid->cells()[cellStartIndex + gIdx];
|
||||
|
||||
// The invalid (tainted) cell concept in ecl was not correct at all,
|
||||
// so this is disabeled.
|
||||
//bool invalid = ecl_grid_cell_invalid1(localEclGrid, gIdx);
|
||||
//cell.setInvalid(invalid);
|
||||
|
||||
cell.setCellIndex(gIdx);
|
||||
bool active = ecl_grid_cell_active1(localEclGrid, gIdx);
|
||||
cell.setActive(active);
|
||||
cell.setGlobalActiveIndex(active ? activeStartIndex + ecl_grid_get_active_index1(localEclGrid, gIdx) : cvf::UNDEFINED_SIZE_T);
|
||||
|
||||
int parentCellIndex = ecl_grid_get_parent_cell1(localEclGrid, gIdx);
|
||||
if (parentCellIndex == -1)
|
||||
{
|
||||
cell.setParentCellIndex(cvf::UNDEFINED_SIZE_T);
|
||||
}
|
||||
else
|
||||
{
|
||||
cell.setParentCellIndex(parentCellIndex);
|
||||
}
|
||||
|
||||
// Corner coordinates
|
||||
int cIdx;
|
||||
for (cIdx = 0; cIdx < 8; ++cIdx)
|
||||
{
|
||||
double * point = mainGrid->nodes()[nodeStartIndex + gIdx * 8 + cellMappingECLRi[cIdx]].ptr();
|
||||
ecl_grid_get_corner_xyz1(localEclGrid, gIdx, cIdx, &(point[0]), &(point[1]), &(point[2]));
|
||||
point[2] = -point[2];
|
||||
cell.cornerIndices()[cIdx] = nodeStartIndex + gIdx*8 + cIdx;
|
||||
}
|
||||
|
||||
// Sub grid in cell
|
||||
const ecl_grid_type* subGrid = ecl_grid_get_cell_lgr1(localEclGrid, gIdx);
|
||||
if (subGrid != NULL)
|
||||
{
|
||||
int subGridFileIndex = ecl_grid_get_grid_nr(subGrid);
|
||||
CVF_ASSERT(subGridFileIndex > 0);
|
||||
cell.setSubGrid(static_cast<RigLocalGrid*>(mainGrid->gridByIndex(subGridFileIndex)));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Class RigReaderInterfaceECL
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderInterfaceECL::RifReaderInterfaceECL()
|
||||
{
|
||||
ground();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderInterfaceECL::~RifReaderInterfaceECL()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Ground members
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderInterfaceECL::ground()
|
||||
{
|
||||
m_fileName.clear();
|
||||
m_fileSet.clear();
|
||||
|
||||
m_staticResults.clear();
|
||||
m_dynamicResults.clear();
|
||||
m_timeStepTexts.clear();
|
||||
m_timeSteps.clear();
|
||||
|
||||
m_numGrids = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Close interface (for now, no files are kept open after calling methods, so just clear members)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderInterfaceECL::close()
|
||||
{
|
||||
m_staticResultsAccess = NULL;
|
||||
m_dynamicResultsAccess = NULL;
|
||||
|
||||
ground();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Read geometry from file given by name into given reservoir object
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderInterfaceECL::readGeometry(const QString& filename, RigReservoir* reservoir)
|
||||
{
|
||||
CVF_ASSERT(reservoir);
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
ecl_grid_type * mainEclGrid = ecl_grid_alloc( filename.toAscii().data() );
|
||||
if (!mainEclGrid)
|
||||
{
|
||||
// Some error
|
||||
return false;
|
||||
}
|
||||
|
||||
RigMainGrid* mainGrid = reservoir->mainGrid();
|
||||
{
|
||||
cvf::Vec3st gridPointDim(0,0,0);
|
||||
gridPointDim.x() = ecl_grid_get_nx(mainEclGrid) + 1;
|
||||
gridPointDim.y() = ecl_grid_get_ny(mainEclGrid) + 1;
|
||||
gridPointDim.z() = ecl_grid_get_nz(mainEclGrid) + 1;
|
||||
mainGrid->setGridPointDimensions(gridPointDim);
|
||||
}
|
||||
|
||||
// Get and set grid and lgr metadata
|
||||
|
||||
size_t totalCellCount = static_cast<size_t>(ecl_grid_get_global_size(mainEclGrid));
|
||||
|
||||
int numLGRs = ecl_grid_get_num_lgr(mainEclGrid);
|
||||
int lgrIdx;
|
||||
for (lgrIdx = 0; lgrIdx < numLGRs; ++lgrIdx)
|
||||
{
|
||||
ecl_grid_type* localEclGrid = ecl_grid_iget_lgr(mainEclGrid, lgrIdx);
|
||||
|
||||
std::string lgrName = ecl_grid_get_name(localEclGrid);
|
||||
cvf::Vec3st gridPointDim(0,0,0);
|
||||
gridPointDim.x() = ecl_grid_get_nx(localEclGrid) + 1;
|
||||
gridPointDim.y() = ecl_grid_get_ny(localEclGrid) + 1;
|
||||
gridPointDim.z() = ecl_grid_get_nz(localEclGrid) + 1;
|
||||
|
||||
RigLocalGrid* localGrid = new RigLocalGrid(mainGrid);
|
||||
mainGrid->addLocalGrid(localGrid);
|
||||
|
||||
localGrid->setIndexToStartOfCells(totalCellCount);
|
||||
localGrid->setGridName(lgrName);
|
||||
localGrid->setGridPointDimensions(gridPointDim);
|
||||
|
||||
totalCellCount += ecl_grid_get_global_size(localEclGrid);
|
||||
}
|
||||
|
||||
// Reserve room for the cells and nodes and fill them with data
|
||||
|
||||
mainGrid->cells().reserve(totalCellCount);
|
||||
mainGrid->nodes().reserve(8*totalCellCount);
|
||||
|
||||
transferGridCellData(mainGrid, mainGrid, mainEclGrid, 0);
|
||||
|
||||
size_t globalActiveSize = ecl_grid_get_active_size(mainEclGrid);
|
||||
|
||||
for (lgrIdx = 0; lgrIdx < numLGRs; ++lgrIdx)
|
||||
{
|
||||
ecl_grid_type* localEclGrid = ecl_grid_iget_lgr(mainEclGrid, lgrIdx);
|
||||
transferGridCellData(mainGrid, static_cast<RigLocalGrid*>(mainGrid->gridByIndex(lgrIdx+1)), localEclGrid, globalActiveSize);
|
||||
globalActiveSize += ecl_grid_get_active_size(localEclGrid);
|
||||
}
|
||||
|
||||
ecl_grid_free( mainEclGrid );
|
||||
|
||||
// !! Maybe this should set somewhere else, in a method that builds meta data !!
|
||||
m_numGrids = numLGRs + 1;
|
||||
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Open file and read geometry into given reservoir object
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderInterfaceECL::open(const QString& fileName, RigReservoir* reservoir)
|
||||
{
|
||||
CVF_ASSERT(reservoir);
|
||||
|
||||
// Make sure everything's closed
|
||||
close();
|
||||
|
||||
// Get set of files
|
||||
QStringList fileSet;
|
||||
if (!RifReaderEclipseFileAccess::fileSet(fileName, &fileSet)) return false;
|
||||
|
||||
// Keep the set of files of interest
|
||||
m_fileSet = fileSet;
|
||||
|
||||
// Read geometry
|
||||
if (!readGeometry(fileName, reservoir)) return false;
|
||||
|
||||
// Build results meta data
|
||||
if (!buildMetaData(reservoir)) return false;
|
||||
|
||||
readWellCells(reservoir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Build meta data - get states and results info
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderInterfaceECL::buildMetaData(RigReservoir* reservoir)
|
||||
{
|
||||
#ifdef USE_ECL_LIB
|
||||
CVF_ASSERT(reservoir);
|
||||
CVF_ASSERT(m_fileSet.size() > 0);
|
||||
|
||||
// Get the number of active cells in the grid
|
||||
size_t numActiveCells = reservoir->mainGrid()->numActiveCells();
|
||||
|
||||
// Create access object for dynamic results
|
||||
m_dynamicResultsAccess = dynamicResultsAccess(m_fileSet, m_numGrids, numActiveCells);
|
||||
if (m_dynamicResultsAccess.notNull())
|
||||
{
|
||||
// Get time steps texts
|
||||
m_timeStepTexts = m_dynamicResultsAccess->timeStepsText();
|
||||
m_timeSteps = m_dynamicResultsAccess->timeSteps();
|
||||
|
||||
// Get the names of the dynamic results
|
||||
m_dynamicResults = m_dynamicResultsAccess->resultNames();
|
||||
}
|
||||
|
||||
QString initFileName = RifReaderEclipseFileAccess::fileNameByType(m_fileSet, ECL_INIT_FILE);
|
||||
if (initFileName.size() > 0)
|
||||
{
|
||||
// Open init file
|
||||
cvf::ref<RifReaderEclipseFileAccess> initFile = new RifReaderEclipseFileAccess;
|
||||
if (!initFile->open(initFileName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the names of the static results
|
||||
QStringList staticResults;
|
||||
initFile->keywordsOnFile(&staticResults, numActiveCells);
|
||||
m_staticResults = staticResults;
|
||||
|
||||
m_staticResultsAccess = initFile;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif //USE_ECL_LIB
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Create results access object (.UNRST or .X0001 ... .XNNNN)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseResultsAccess* RifReaderInterfaceECL::dynamicResultsAccess(const QStringList& fileSet, size_t numGrids, size_t numActiveCells)
|
||||
{
|
||||
RifReaderEclipseResultsAccess* resultsAccess = NULL;
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
// Look for unified restart file
|
||||
QString unrstFileName = RifReaderEclipseFileAccess::fileNameByType(fileSet, ECL_UNIFIED_RESTART_FILE);
|
||||
if (unrstFileName.size() > 0)
|
||||
{
|
||||
resultsAccess = new RifReaderEclipseUnifiedRestartFile(numGrids, numActiveCells);
|
||||
if (!resultsAccess->open(QStringList(unrstFileName)))
|
||||
{
|
||||
delete resultsAccess;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look for set of restart files (one file per time step)
|
||||
QStringList restartFiles = RifReaderEclipseFileAccess::fileNamesByType(fileSet, ECL_RESTART_FILE);
|
||||
if (restartFiles.size() > 0)
|
||||
{
|
||||
resultsAccess = new RifReaderEclipseRestartFiles(numGrids, numActiveCells);
|
||||
if (!resultsAccess->open(restartFiles))
|
||||
{
|
||||
delete resultsAccess;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //USE_ECL_LIB
|
||||
|
||||
// !! could add support for formatted result files
|
||||
// !! consider priorities in case multiple types exist (.UNRST, .XNNNN, ...)
|
||||
|
||||
return resultsAccess;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the names of all static results
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QStringList& RifReaderInterfaceECL::staticResults() const
|
||||
{
|
||||
return m_staticResults;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the names of all dynamic results
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QStringList& RifReaderInterfaceECL::dynamicResults() const
|
||||
{
|
||||
return m_dynamicResults;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the number of time steps
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RifReaderInterfaceECL::numTimeSteps() const
|
||||
{
|
||||
return m_timeStepTexts.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get all values of a given static result as doubles
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderInterfaceECL::staticResult(const QString& result, std::vector<double>* values)
|
||||
{
|
||||
CVF_ASSERT(values);
|
||||
CVF_ASSERT(m_staticResultsAccess.notNull());
|
||||
|
||||
size_t numOccurrences = m_staticResultsAccess->numOccurrences(result);
|
||||
size_t i;
|
||||
for (i = 0; i < numOccurrences; i++)
|
||||
{
|
||||
std::vector<double> partValues;
|
||||
if (!m_staticResultsAccess->keywordData(result, i, &partValues)) return false;
|
||||
values->insert(values->end(), partValues.begin(), partValues.end());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get dynamic result at given step index. Will concatenate values for the main grid and all sub grids.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderInterfaceECL::dynamicResult(const QString& result, size_t stepIndex, std::vector<double>* values)
|
||||
{
|
||||
CVF_ASSERT(m_dynamicResultsAccess.notNull());
|
||||
return m_dynamicResultsAccess->results(result, stepIndex, values);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get list of time step texts
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QStringList& RifReaderInterfaceECL::timeStepText() const
|
||||
{
|
||||
return m_timeStepTexts;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QList<QDateTime>& RifReaderInterfaceECL::timeSteps() const
|
||||
{
|
||||
return m_timeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderInterfaceECL::readWellCells(RigReservoir* reservoir)
|
||||
{
|
||||
CVF_ASSERT(reservoir);
|
||||
|
||||
if (m_dynamicResultsAccess.isNull()) return;
|
||||
|
||||
#ifdef USE_ECL_LIB
|
||||
well_info_type* ert_well_info = well_info_alloc(NULL);
|
||||
if (!ert_well_info) return;
|
||||
|
||||
m_dynamicResultsAccess->readWellData(ert_well_info);
|
||||
|
||||
RigMainGrid* mainGrid = reservoir->mainGrid();
|
||||
std::vector<RigGridBase*> grids;
|
||||
reservoir->allGrids(&grids);
|
||||
|
||||
cvf::Collection<RigWellResults> wells;
|
||||
|
||||
int wellIdx;
|
||||
for (wellIdx = 0; wellIdx < well_info_get_num_wells(ert_well_info); wellIdx++)
|
||||
{
|
||||
const char* wellName = well_info_iget_well_name(ert_well_info, wellIdx);
|
||||
CVF_ASSERT(wellName);
|
||||
|
||||
cvf::ref<RigWellResults> wellResults = new RigWellResults;
|
||||
wellResults->m_wellName = wellName;
|
||||
|
||||
well_ts_type* ert_well_time_series = well_info_get_ts(ert_well_info , wellName);
|
||||
int timeStepCount = well_ts_get_size(ert_well_time_series);
|
||||
|
||||
wellResults->m_wellCellsTimeSteps.resize(timeStepCount);
|
||||
|
||||
int timeIdx;
|
||||
for (timeIdx = 0; timeIdx < timeStepCount; timeIdx++)
|
||||
{
|
||||
well_state_type* ert_well_state = well_ts_iget_state(ert_well_time_series, timeIdx);
|
||||
|
||||
RigWellResultFrame& wellResFrame = wellResults->m_wellCellsTimeSteps[timeIdx];
|
||||
|
||||
// Build timestamp for well
|
||||
// Also see RifReaderEclipseFileAccess::timeStepsText for accessing time_t structures
|
||||
{
|
||||
time_t stepTime = well_state_get_sim_time(ert_well_state);
|
||||
wellResFrame.m_timestamp = QDateTime::fromTime_t(stepTime);
|
||||
}
|
||||
|
||||
// Production type
|
||||
well_type_enum ert_well_type = well_state_get_type(ert_well_state);
|
||||
if (ert_well_type == PRODUCER)
|
||||
{
|
||||
wellResFrame.m_productionType = RigWellResultFrame::PRODUCER;
|
||||
}
|
||||
else if (ert_well_type == WATER_INJECTOR)
|
||||
{
|
||||
wellResFrame.m_productionType = RigWellResultFrame::WATER_INJECTOR;
|
||||
}
|
||||
else if (ert_well_type == GAS_INJECTOR)
|
||||
{
|
||||
wellResFrame.m_productionType = RigWellResultFrame::GAS_INJECTOR;
|
||||
}
|
||||
else if (ert_well_type == OIL_INJECTOR)
|
||||
{
|
||||
wellResFrame.m_productionType = RigWellResultFrame::OIL_INJECTOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
wellResFrame.m_productionType = RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE;
|
||||
}
|
||||
|
||||
wellResFrame.m_isOpen = well_state_is_open( ert_well_state );
|
||||
|
||||
|
||||
|
||||
|
||||
// Loop over all the grids in the model. If we have connections in one, we will discard
|
||||
// the maingrid connections as they are "duplicates"
|
||||
|
||||
bool hasWellConnectionsInLGR = false;
|
||||
for (size_t gridNr = 1; gridNr < grids.size(); ++gridNr)
|
||||
{
|
||||
int branchCount = well_state_iget_lgr_num_branches(ert_well_state, gridNr);
|
||||
if (branchCount > 0)
|
||||
{
|
||||
hasWellConnectionsInLGR = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
size_t gridNr = hasWellConnectionsInLGR ? 1 : 0;
|
||||
for (; gridNr < grids.size(); ++gridNr)
|
||||
{
|
||||
|
||||
// Wellhead. If several grids have a wellhead definition for this well, we use tha last one. (Possibly the innermost LGR)
|
||||
const well_conn_type* ert_wellhead = well_state_iget_wellhead(ert_well_state, gridNr);
|
||||
if (ert_wellhead)
|
||||
{
|
||||
wellResFrame.m_wellHead.m_gridIndex = gridNr;
|
||||
int gridK = CVF_MAX(0, ert_wellhead->k); // Why this ?
|
||||
wellResFrame.m_wellHead.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(ert_wellhead->i, ert_wellhead->j, gridK);
|
||||
}
|
||||
|
||||
int branchCount = well_state_iget_lgr_num_branches(ert_well_state, gridNr);
|
||||
if (branchCount > 0)
|
||||
{
|
||||
if (static_cast<int>(wellResFrame.m_wellResultBranches.size()) < branchCount) wellResFrame.m_wellResultBranches.resize(branchCount);
|
||||
|
||||
for (int branchIdx = 0; branchIdx < branchCount; ++branchIdx )
|
||||
{
|
||||
// Connections
|
||||
int connectionCount = well_state_iget_num_lgr_connections(ert_well_state, gridNr, branchIdx);
|
||||
if (connectionCount > 0)
|
||||
{
|
||||
|
||||
RigWellResultBranch& wellSegment = wellResFrame.m_wellResultBranches[branchIdx]; // Is this completely right? Is the branch index actually the same between lgrs ?
|
||||
wellSegment.m_branchNumber = branchIdx;
|
||||
size_t existingConnCount = wellSegment.m_wellCells.size();
|
||||
wellSegment.m_wellCells.resize(existingConnCount + connectionCount);
|
||||
|
||||
int connIdx;
|
||||
for (connIdx = 0; connIdx < connectionCount; connIdx++)
|
||||
{
|
||||
const well_conn_type* ert_connection = well_state_iget_lgr_connections( ert_well_state, gridNr, branchIdx)[connIdx];
|
||||
CVF_ASSERT(ert_connection);
|
||||
|
||||
RigWellResultCell& data = wellSegment.m_wellCells[existingConnCount + connIdx];
|
||||
data.m_gridIndex = gridNr;
|
||||
data.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(ert_connection->i, ert_connection->j, ert_connection->k);
|
||||
data.m_isOpen = ert_connection->open;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wellResults->computeMappingFromResultTimeIndicesToWellTimeIndices(m_timeSteps);
|
||||
|
||||
wells.push_back(wellResults.p());
|
||||
}
|
||||
|
||||
well_info_free(ert_well_info);
|
||||
|
||||
reservoir->setWellResults(wells);
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
70
ApplicationCode/FileInterface/RifReaderInterfaceEcl.h
Normal file
70
ApplicationCode/FileInterface/RifReaderInterfaceEcl.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RifReaderInterface.h"
|
||||
|
||||
class RifReaderEclipseFileAccess;
|
||||
class RifReaderEclipseResultsAccess;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// File interface for Eclipse output files
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifReaderInterfaceECL : public RifReaderInterface
|
||||
{
|
||||
public:
|
||||
RifReaderInterfaceECL();
|
||||
virtual ~RifReaderInterfaceECL();
|
||||
|
||||
bool open(const QString& fileName, RigReservoir* reservoir);
|
||||
void close();
|
||||
|
||||
const QStringList& staticResults() const;
|
||||
const QStringList& dynamicResults() const;
|
||||
|
||||
size_t numTimeSteps() const;
|
||||
const QStringList& timeStepText() const;
|
||||
const QList<QDateTime>& timeSteps() const;
|
||||
|
||||
bool staticResult(const QString& result, std::vector<double>* values);
|
||||
bool dynamicResult(const QString& result, size_t stepIndex, std::vector<double>* values);
|
||||
|
||||
private:
|
||||
void ground();
|
||||
bool buildMetaData(RigReservoir* reservoir);
|
||||
bool readGeometry(const QString& fileName, RigReservoir* reservoir);
|
||||
void readWellCells(RigReservoir* reservoir);
|
||||
|
||||
static RifReaderEclipseResultsAccess* staticResultsAccess(const QStringList& fileSet, size_t numGrids, size_t numActiveCells);
|
||||
static RifReaderEclipseResultsAccess* dynamicResultsAccess(const QStringList& fileSet, size_t numGrids, size_t numActiveCells);
|
||||
|
||||
private:
|
||||
QString m_fileName; // Name of file used to start accessing Eclipse output files
|
||||
QStringList m_fileSet; // Set of files in filename's path with same base name as filename
|
||||
QStringList m_staticResults; // List of names of static results
|
||||
QStringList m_dynamicResults; // List of names of dynamic results
|
||||
QStringList m_timeStepTexts; // List of time step infos (dates)
|
||||
QList<QDateTime> m_timeSteps;
|
||||
size_t m_numGrids; // Total number of grids (main grid and all sub grids)
|
||||
|
||||
cvf::ref<RifReaderEclipseFileAccess> m_staticResultsAccess; // File access to static results
|
||||
cvf::ref<RifReaderEclipseResultsAccess> m_dynamicResultsAccess; // File access to dynamic results
|
||||
};
|
||||
178
ApplicationCode/FileInterface/RifReaderInterfaceMock.cpp
Normal file
178
ApplicationCode/FileInterface/RifReaderInterfaceMock.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RifReaderInterfaceMock.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderInterfaceMock::open(const QString& fileName, RigReservoir* reservoir)
|
||||
{
|
||||
m_reservoirBuilder.populateReservoir(reservoir);
|
||||
|
||||
m_reservoir = reservoir;
|
||||
|
||||
m_dynamicResults.clear();
|
||||
m_staticResults.clear();
|
||||
m_timeStepTexts.clear();
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < m_reservoirBuilder.resultCount(); i++)
|
||||
{
|
||||
m_dynamicResults.push_back(QString("Dynamic_Result_%1").arg(i));
|
||||
}
|
||||
|
||||
for (i = 0; i < m_reservoirBuilder.resultCount(); i++)
|
||||
{
|
||||
QString varEnd;
|
||||
if (i == 0) varEnd = "X";
|
||||
if (i == 1) varEnd = "Y";
|
||||
int resIndex = 0;
|
||||
if (i > 1) resIndex = i;
|
||||
|
||||
m_staticResults.push_back(QString("Static_Result_%1%2").arg(resIndex).arg(varEnd));
|
||||
}
|
||||
|
||||
for (i = 0; i < m_reservoirBuilder.timeStepCount(); i++)
|
||||
{
|
||||
m_timeStepTexts.push_back(QString("Timestep %1").arg(i));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderInterfaceMock::close()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QStringList& RifReaderInterfaceMock::staticResults() const
|
||||
{
|
||||
|
||||
return m_staticResults;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QStringList& RifReaderInterfaceMock::dynamicResults() const
|
||||
{
|
||||
return m_dynamicResults;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RifReaderInterfaceMock::numTimeSteps() const
|
||||
{
|
||||
return m_reservoirBuilder.timeStepCount();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderInterfaceMock::staticResult(const QString& result, std::vector<double>* values)
|
||||
{
|
||||
m_reservoirBuilder.staticResult(m_reservoir.p(), result, values);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderInterfaceMock::dynamicResult(const QString& result, size_t stepIndex, std::vector<double>* values)
|
||||
{
|
||||
m_reservoirBuilder.dynamicResult(m_reservoir.p(), result, stepIndex, values);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderInterfaceMock::RifReaderInterfaceMock()
|
||||
{
|
||||
/*
|
||||
m_cellResults.push_back("Dummy results");
|
||||
m_cellProperties.push_back("Dummy static result");
|
||||
*/
|
||||
}
|
||||
|
||||
RifReaderInterfaceMock::~RifReaderInterfaceMock()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderInterfaceMock::setWorldCoordinates(cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate)
|
||||
{
|
||||
m_reservoirBuilder.setWorldCoordinates(minWorldCoordinate, maxWorldCoordinate);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderInterfaceMock::setGridPointDimensions(const cvf::Vec3st& gridPointDimensions)
|
||||
{
|
||||
m_reservoirBuilder.setGridPointDimensions(gridPointDimensions);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderInterfaceMock::setResultInfo(size_t resultCount, size_t timeStepCount)
|
||||
{
|
||||
m_reservoirBuilder.setResultInfo(resultCount, timeStepCount);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderInterfaceMock::addLocalGridRefinement(const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, const cvf::Vec3st& singleCellRefinementFactors)
|
||||
{
|
||||
m_reservoirBuilder.addLocalGridRefinement(minCellPosition, maxCellPosition, singleCellRefinementFactors);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderInterfaceMock::populateReservoir(RigReservoir* reservoir)
|
||||
{
|
||||
m_reservoirBuilder.populateReservoir(reservoir);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QStringList& RifReaderInterfaceMock::timeStepText() const
|
||||
{
|
||||
return m_timeStepTexts;
|
||||
}
|
||||
|
||||
|
||||
58
ApplicationCode/FileInterface/RifReaderInterfaceMock.h
Normal file
58
ApplicationCode/FileInterface/RifReaderInterfaceMock.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RifReaderInterface.h"
|
||||
#include "RigReservoirBuilderMock.h"
|
||||
|
||||
class RifReaderInterfaceMock : public RifReaderInterface
|
||||
{
|
||||
public:
|
||||
RifReaderInterfaceMock();
|
||||
virtual ~RifReaderInterfaceMock();
|
||||
|
||||
void setWorldCoordinates(cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate);
|
||||
void setGridPointDimensions(const cvf::Vec3st& gridPointDimensions);
|
||||
void setResultInfo(size_t resultCount, size_t timeStepCount);
|
||||
|
||||
void addLocalGridRefinement(const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, const cvf::Vec3st& singleCellRefinementFactors);
|
||||
|
||||
|
||||
virtual bool open( const QString& fileName, RigReservoir* reservoir );
|
||||
virtual void close();
|
||||
virtual const QStringList& staticResults() const;
|
||||
virtual const QStringList& dynamicResults() const;
|
||||
virtual size_t numTimeSteps() const;
|
||||
const QStringList& timeStepText() const;
|
||||
|
||||
virtual bool staticResult( const QString& result, std::vector<double>* values );
|
||||
virtual bool dynamicResult( const QString& result, size_t stepIndex, std::vector<double>* values );
|
||||
|
||||
private:
|
||||
void populateReservoir(RigReservoir* reservoir);
|
||||
|
||||
QStringList m_staticResults;
|
||||
QStringList m_dynamicResults;
|
||||
QStringList m_timeStepTexts;
|
||||
|
||||
RigReservoirBuilderMock m_reservoirBuilder;
|
||||
|
||||
cvf::ref<RigReservoir> m_reservoir;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
SET (ProjectName ModelVisualization_UnitTests)
|
||||
project ( ${ProjectName} )
|
||||
|
||||
include_directories(
|
||||
${LibCore_SOURCE_DIR}
|
||||
${LibGeometry_SOURCE_DIR}
|
||||
${LibRender_SOURCE_DIR}
|
||||
${LibViewing_SOURCE_DIR}
|
||||
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty
|
||||
${ResInsight_SOURCE_DIR}/CommonCode
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
|
||||
|
||||
)
|
||||
|
||||
set( MODEL_VISUALIZATION_CPP_SOURCES
|
||||
../RivPipeGeometryGenerator.cpp
|
||||
)
|
||||
|
||||
|
||||
set( CPP_SOURCES
|
||||
${MODEL_VISUALIZATION_CPP_SOURCES}
|
||||
)
|
||||
|
||||
set( UNIT_TEST_CPP_SOURCES
|
||||
main.cpp
|
||||
RivPipeGeometryGenerator-Test.cpp
|
||||
)
|
||||
|
||||
|
||||
set( LINK_LIBRARIES
|
||||
LibViewing
|
||||
LibRender
|
||||
LibGeometry
|
||||
LibCore
|
||||
|
||||
CommonCode
|
||||
|
||||
${OPENGL_LIBRARIES}
|
||||
)
|
||||
|
||||
|
||||
add_executable( ${ProjectName}
|
||||
${CPP_SOURCES}
|
||||
${UNIT_TEST_CPP_SOURCES}
|
||||
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty/gtest/gtest-all.cc
|
||||
)
|
||||
|
||||
|
||||
target_link_libraries( ${ProjectName} ${LINK_LIBRARIES})
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "cvfLibCore.h"
|
||||
#include "cvfLibViewing.h"
|
||||
#include "cvfLibRender.h"
|
||||
#include "cvfLibGeometry.h"
|
||||
|
||||
#include "RivPipeGeometryGenerator.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::Vec3dArray> buildPipeCoords()
|
||||
{
|
||||
cvf::ref<cvf::Vec3dArray> coords = new cvf::Vec3dArray;
|
||||
coords->resize(10);
|
||||
|
||||
// Two identical at start
|
||||
coords->set(0, cvf::Vec3d(10, 10, 10));
|
||||
coords->set(1, cvf::Vec3d(10, 10, 10));
|
||||
|
||||
// 180 degree
|
||||
coords->set(2, cvf::Vec3d(12, 20, 10));
|
||||
coords->set(3, cvf::Vec3d(13, 20, 20));
|
||||
coords->set(4, cvf::Vec3d(13, 20, 20));
|
||||
coords->set(5, cvf::Vec3d(12, 20, 10));
|
||||
|
||||
//coords->set(5, cvf::Vec3d(15, 10, 10));
|
||||
coords->set(6, cvf::Vec3d(16, 10, 10));
|
||||
coords->set(7, cvf::Vec3d(17, 10, 10));
|
||||
|
||||
// Two identical at end
|
||||
coords->set(8, cvf::Vec3d(18, 10, 10));
|
||||
coords->set(9, cvf::Vec3d(18, 10, 10));
|
||||
|
||||
return coords;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(ModelVisualizationTest, AllPartsInputTest)
|
||||
{
|
||||
cvf::ref<cvf::Vec3dArray> coords = new cvf::Vec3dArray;
|
||||
RivPipeGeometryGenerator gen;
|
||||
|
||||
// Set empty coords array
|
||||
gen.setPipeCenterCoords(coords.p());
|
||||
{
|
||||
cvf::ref<cvf::DrawableGeo> geo = gen.createPipeSurface();
|
||||
EXPECT_TRUE(geo.isNull());
|
||||
}
|
||||
|
||||
coords->resize(2);
|
||||
coords->set(0, cvf::Vec3d(10, 10, 10));
|
||||
coords->set(1, cvf::Vec3d(10, 10, 10));
|
||||
|
||||
gen.setPipeCenterCoords(coords.p());
|
||||
{
|
||||
cvf::ref<cvf::DrawableGeo> geo = gen.createPipeSurface();
|
||||
EXPECT_TRUE(geo.isNull());
|
||||
}
|
||||
|
||||
coords->set(1, cvf::Vec3d(10, 10, 20));
|
||||
gen.setPipeCenterCoords(coords.p());
|
||||
{
|
||||
cvf::ref<cvf::DrawableGeo> geo = gen.createPipeSurface();
|
||||
EXPECT_TRUE(geo.notNull());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(ModelVisualizationTest, PipeGeometryTest)
|
||||
{
|
||||
cvf::ref<cvf::Vec3dArray> coords = buildPipeCoords();
|
||||
|
||||
RivPipeGeometryGenerator gen;
|
||||
gen.setPipeCenterCoords(coords.p());
|
||||
gen.createPipeSurface();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "cvfBase.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cvfTrace.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cvf::Assert::setReportMode(cvf::Assert::CONSOLE);
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
std::cout << "Please press <Enter> to close the window.";
|
||||
std::cin.get();
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,365 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RivCellEdgeEffectGenerator.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfAssert.h"
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfVertexAttribute.h"
|
||||
#include "cvfStructGridGeometryGenerator.h"
|
||||
#include "cvfScalarMapperUniformLevels.h"
|
||||
|
||||
#include "cvfShaderProgramGenerator.h"
|
||||
#include "cvfShaderSourceProvider.h"
|
||||
#include "cvfqtUtils.h"
|
||||
#include "cvfShaderProgram.h"
|
||||
|
||||
#include <vector>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "RimReservoirView.h"
|
||||
#include "RigGridBase.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigReservoirCellResults.h"
|
||||
#include "cvfTextureImage.h"
|
||||
#include "cvfTexture.h"
|
||||
#include "cvfSampler.h"
|
||||
#include "cvfScalarMapper.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(
|
||||
size_t timeStepIndex,
|
||||
RimResultSlot* cellResultSlot,
|
||||
RimCellEdgeResultSlot* cellEdgeResultSlot,
|
||||
cvf::StructGridGeometryGenerator* generator,
|
||||
cvf::DrawableGeo* geo)
|
||||
{
|
||||
const std::vector<size_t>& quadToCell = generator->quadToGridCellIndices();
|
||||
const std::vector<cvf::StructGridInterface::FaceType>& quadToFace = generator->quadToFace();
|
||||
|
||||
size_t vertexCount = geo->vertexArray()->size();
|
||||
size_t quadCount = vertexCount / 4;
|
||||
|
||||
cvf::ref<cvf::Vec2fArray> localCoords = new cvf::Vec2fArray;
|
||||
localCoords->resize(vertexCount);
|
||||
|
||||
cvf::ref<cvf::IntArray> faceIndexArray = new cvf::IntArray;
|
||||
faceIndexArray->resize(vertexCount);
|
||||
|
||||
cvf::ref<cvf::FloatArray> cellColorTextureCoordArray = new cvf::FloatArray;
|
||||
cellColorTextureCoordArray->resize(vertexCount);
|
||||
|
||||
// Build six cell face color arrays
|
||||
cvf::Collection<cvf::FloatArray> cellEdgeColorTextureCoordsArrays;
|
||||
size_t idx;
|
||||
for (idx = 0; idx < 6; idx++)
|
||||
{
|
||||
cvf::ref<cvf::FloatArray> colorArray = new cvf::FloatArray;
|
||||
colorArray->resize(vertexCount);
|
||||
cellEdgeColorTextureCoordsArrays.push_back(colorArray.p());
|
||||
}
|
||||
|
||||
cvf::ScalarMapper* cellResultScalarMapper = cellResultSlot->legendConfig()->scalarMapper();
|
||||
cvf::ScalarMapper* edgeResultScalarMapper = cellEdgeResultSlot->legendConfig()->scalarMapper();
|
||||
|
||||
const RigGridBase* grid = dynamic_cast<const RigGridBase*>(generator->activeGrid());
|
||||
|
||||
CVF_ASSERT(grid != NULL);
|
||||
const std::vector< double >* cellScalarResults = NULL;
|
||||
const std::vector< double >* edgeScalarResults[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
if (cellResultSlot->hasResult())
|
||||
{
|
||||
const std::vector< std::vector<double> >& scalarResultTimeSteps = grid->mainGrid()->results()->cellScalarResults(cellResultSlot->gridScalarIndex());
|
||||
if (cellResultSlot->hasDynamicResult())
|
||||
{
|
||||
cellScalarResults = &scalarResultTimeSteps[timeStepIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
cellScalarResults = &scalarResultTimeSteps[0];
|
||||
}
|
||||
}
|
||||
|
||||
size_t resultIndices[6];
|
||||
cellEdgeResultSlot->gridScalarIndices(resultIndices);
|
||||
|
||||
if (cellEdgeResultSlot->hasResult())
|
||||
{
|
||||
size_t cubeFaceIdx;
|
||||
for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++)
|
||||
{
|
||||
if (resultIndices[cubeFaceIdx] != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
const std::vector< std::vector<double> >& scalarResultTimeSteps = grid->mainGrid()->results()->cellScalarResults(resultIndices[cubeFaceIdx]);
|
||||
edgeScalarResults[cubeFaceIdx] = &scalarResultTimeSteps[0]; // Assuming only static edge results
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double ignoredScalarValue = cellEdgeResultSlot->ignoredScalarValue();
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int quadIdx = 0; quadIdx < static_cast<int>(quadCount); quadIdx++)
|
||||
{
|
||||
localCoords->set(quadIdx * 4 + 0, cvf::Vec2f(0, 0));
|
||||
localCoords->set(quadIdx * 4 + 1, cvf::Vec2f(1, 0));
|
||||
localCoords->set(quadIdx * 4 + 2, cvf::Vec2f(1, 1));
|
||||
localCoords->set(quadIdx * 4 + 3, cvf::Vec2f(0, 1));
|
||||
|
||||
faceIndexArray->set(quadIdx * 4 + 0, quadToFace[quadIdx] );
|
||||
faceIndexArray->set(quadIdx * 4 + 1, quadToFace[quadIdx] );
|
||||
faceIndexArray->set(quadIdx * 4 + 2, quadToFace[quadIdx] );
|
||||
faceIndexArray->set(quadIdx * 4 + 3, quadToFace[quadIdx] );
|
||||
|
||||
float cellColorTextureCoord = 0.5f; // If no results exists, the texture will have a special color
|
||||
size_t cellIndex = quadToCell[quadIdx];
|
||||
size_t resultIndex = grid->cell(cellIndex).globalActiveIndex();
|
||||
|
||||
if (cellScalarResults )
|
||||
{
|
||||
if (resultIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
double scalarValue = (*cellScalarResults)[resultIndex];
|
||||
|
||||
cellColorTextureCoord = cellResultScalarMapper->mapToTextureCoord(scalarValue)[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
cellColorTextureCoord = -1.0f; // Undefined texture coord. Shader handles this.
|
||||
}
|
||||
}
|
||||
|
||||
cellColorTextureCoordArray->set(quadIdx * 4 + 0, cellColorTextureCoord);
|
||||
cellColorTextureCoordArray->set(quadIdx * 4 + 1, cellColorTextureCoord);
|
||||
cellColorTextureCoordArray->set(quadIdx * 4 + 2, cellColorTextureCoord);
|
||||
cellColorTextureCoordArray->set(quadIdx * 4 + 3, cellColorTextureCoord);
|
||||
|
||||
size_t cubeFaceIdx;
|
||||
float edgeColor;
|
||||
for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++)
|
||||
{
|
||||
edgeColor = -1.0f; // Undefined texture coord. Shader handles this.
|
||||
|
||||
if (resultIndices[cubeFaceIdx] != cvf::UNDEFINED_SIZE_T && resultIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
double scalarValue = (*(edgeScalarResults[cubeFaceIdx]))[resultIndex];
|
||||
if(scalarValue != ignoredScalarValue)
|
||||
{
|
||||
edgeColor = edgeResultScalarMapper->mapToTextureCoord(scalarValue)[0];
|
||||
}
|
||||
}
|
||||
|
||||
cvf::FloatArray* colArr = cellEdgeColorTextureCoordsArrays.at(cubeFaceIdx);
|
||||
|
||||
colArr->set(quadIdx * 4 + 0, edgeColor);
|
||||
colArr->set(quadIdx * 4 + 1, edgeColor);
|
||||
colArr->set(quadIdx * 4 + 2, edgeColor);
|
||||
colArr->set(quadIdx * 4 + 3, edgeColor);
|
||||
}
|
||||
}
|
||||
|
||||
geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_localCoord", localCoords.p()));
|
||||
geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorCell", cellColorTextureCoordArray.p()));
|
||||
|
||||
cvf::ref<cvf::IntVertexAttributeDirect> faceIntAttribute = new cvf::IntVertexAttributeDirect("a_face", faceIndexArray.p());
|
||||
//faceIntAttribute->setIntegerTypeConversion(cvf::VertexAttribute::DIRECT_FLOAT);
|
||||
geo->setVertexAttribute(faceIntAttribute.p());
|
||||
|
||||
geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosI", cellEdgeColorTextureCoordsArrays.at(0)));
|
||||
geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegI", cellEdgeColorTextureCoordsArrays.at(1)));
|
||||
geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosJ", cellEdgeColorTextureCoordsArrays.at(2)));
|
||||
geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegJ", cellEdgeColorTextureCoordsArrays.at(3)));
|
||||
geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosK", cellEdgeColorTextureCoordsArrays.at(4)));
|
||||
geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegK", cellEdgeColorTextureCoordsArrays.at(5)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
CellEdgeEffectGenerator::CellEdgeEffectGenerator(const cvf::ScalarMapper* edgeScalarMapper, const cvf::ScalarMapper* cellScalarMapper)
|
||||
{
|
||||
CVF_ASSERT(edgeScalarMapper != NULL);
|
||||
|
||||
m_cellScalarMapper = cellScalarMapper;
|
||||
m_edgeScalarMapper = edgeScalarMapper;
|
||||
|
||||
m_cullBackfaces = false;
|
||||
m_opacityLevel = 1.0f;
|
||||
m_defaultCellColor = cvf::Color3f(cvf::Color3::WHITE);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool CellEdgeEffectGenerator::isEqual(const EffectGenerator* other) const
|
||||
{
|
||||
const CellEdgeEffectGenerator* otherCellFaceEffectGenerator = dynamic_cast<const CellEdgeEffectGenerator*>(other);
|
||||
|
||||
if (otherCellFaceEffectGenerator
|
||||
&& m_cellScalarMapper.p() == otherCellFaceEffectGenerator->m_cellScalarMapper.p()
|
||||
&& m_edgeScalarMapper.p() == otherCellFaceEffectGenerator->m_edgeScalarMapper.p()
|
||||
&& m_cullBackfaces == otherCellFaceEffectGenerator->m_cullBackfaces
|
||||
&& m_opacityLevel == otherCellFaceEffectGenerator->m_opacityLevel
|
||||
&& m_undefinedColor == otherCellFaceEffectGenerator->m_undefinedColor
|
||||
&& m_defaultCellColor == otherCellFaceEffectGenerator->m_defaultCellColor
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::EffectGenerator* CellEdgeEffectGenerator::copy() const
|
||||
{
|
||||
CellEdgeEffectGenerator * newEffect = new CellEdgeEffectGenerator(m_edgeScalarMapper.p(), m_cellScalarMapper.p());
|
||||
newEffect->setOpacityLevel(m_opacityLevel);
|
||||
newEffect->setCullBackfaces(m_cullBackfaces);
|
||||
newEffect->setUndefinedColor(m_undefinedColor);
|
||||
newEffect->setDefaultCellColor(m_defaultCellColor);
|
||||
|
||||
return newEffect;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) const
|
||||
{
|
||||
cvf::ref<cvf::Effect> eff = effect;
|
||||
|
||||
// Set up shader program
|
||||
|
||||
cvf::ShaderProgramGenerator shaderGen("CellEdgeFaceShaderProgramGenerator", cvf::ShaderSourceProvider::instance());
|
||||
{
|
||||
QFile data(":/Shader/fs_CellFace.glsl");
|
||||
if (data.open(QFile::ReadOnly))
|
||||
{
|
||||
QTextStream in(&data);
|
||||
|
||||
QString data = in.readAll();
|
||||
cvf::String cvfString = cvfqt::Utils::fromQString(data);
|
||||
|
||||
shaderGen.addFragmentCode(cvfString);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QFile data(":/Shader/vs_CellFace.glsl");
|
||||
if (data.open(QFile::ReadOnly))
|
||||
{
|
||||
QTextStream in(&data);
|
||||
|
||||
QString data = in.readAll();
|
||||
cvf::String cvfString = cvfqt::Utils::fromQString(data);
|
||||
|
||||
shaderGen.addVertexCode(cvfString);
|
||||
}
|
||||
}
|
||||
|
||||
shaderGen.addFragmentCode(cvf::ShaderSourceRepository::light_AmbientDiffuse);
|
||||
shaderGen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard);
|
||||
|
||||
cvf::ref<cvf::ShaderProgram> prog = shaderGen.generate();
|
||||
eff->setShaderProgram(prog.p());
|
||||
|
||||
// Set up textures
|
||||
|
||||
cvf::ref<cvf::TextureImage> edgeTexImg = new cvf::TextureImage;
|
||||
cvf::ref<cvf::TextureImage> cellTexImg = new cvf::TextureImage;
|
||||
|
||||
m_edgeScalarMapper->updateTexture(edgeTexImg.p());
|
||||
if (m_cellScalarMapper.notNull())
|
||||
{
|
||||
m_cellScalarMapper->updateTexture(cellTexImg.p());
|
||||
cellTexImg = caf::ScalarMapperEffectGenerator::addAlphaAndUndefStripes(cellTexImg.p(), m_undefinedColor, m_opacityLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
cellTexImg->allocate(2,1);
|
||||
cellTexImg->fill(cvf::Color4ub(cvf::Color4f(m_defaultCellColor, m_opacityLevel)));
|
||||
}
|
||||
|
||||
cvf::ref<cvf::Texture> edgeTexture = new cvf::Texture(edgeTexImg.p());
|
||||
cvf::ref<cvf::Texture> cellTexture = new cvf::Texture(cellTexImg.p());
|
||||
|
||||
cvf::ref<cvf::Sampler> sampler = new cvf::Sampler;
|
||||
sampler->setWrapMode(cvf::Sampler::CLAMP_TO_EDGE);
|
||||
sampler->setMinFilter(cvf::Sampler::NEAREST);
|
||||
sampler->setMagFilter(cvf::Sampler::NEAREST);
|
||||
|
||||
cvf::ref<cvf::TextureBindings> texBind = new cvf::TextureBindings;
|
||||
texBind->addBinding(edgeTexture.p(), sampler.p(), "u_edgeTexture2D");
|
||||
texBind->addBinding(cellTexture.p(), sampler.p(), "u_cellTexture2D");
|
||||
eff->setRenderState(texBind.p());
|
||||
|
||||
// Polygon offset
|
||||
|
||||
if (true)
|
||||
{
|
||||
cvf::ref<cvf::PolygonOffset> polyOffset = new cvf::PolygonOffset;
|
||||
polyOffset->configurePolygonPositiveOffset();
|
||||
eff->setRenderState(polyOffset.p());
|
||||
}
|
||||
|
||||
// Simple transparency
|
||||
if (m_opacityLevel < 1.0f)
|
||||
{
|
||||
cvf::ref<cvf::Blending> blender = new cvf::Blending;
|
||||
blender->configureTransparencyBlending();
|
||||
eff->setRenderState(blender.p());
|
||||
}
|
||||
|
||||
// Backface culling
|
||||
|
||||
if (m_cullBackfaces)
|
||||
{
|
||||
cvf::ref<cvf::CullFace> faceCulling = new cvf::CullFace;
|
||||
eff->setRenderState(faceCulling.p());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void CellEdgeEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* effect) const
|
||||
{
|
||||
caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(cvf::Color3f::CRIMSON), true);
|
||||
|
||||
surfaceGen.updateEffect(effect);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafEffectGenerator.h"
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class StructGridGeometryGenerator;
|
||||
class DrawableGeo;
|
||||
}
|
||||
|
||||
class RimCellEdgeResultSlot;
|
||||
class RimResultSlot;
|
||||
class RigGridBase;
|
||||
|
||||
|
||||
class RivCellEdgeGeometryGenerator
|
||||
{
|
||||
public:
|
||||
static void addCellEdgeResultsToDrawableGeo(size_t timeStepIndex,
|
||||
RimResultSlot* cellResultSlot,
|
||||
RimCellEdgeResultSlot* cellEdgeResultSlot,
|
||||
cvf::StructGridGeometryGenerator* generator,
|
||||
cvf::DrawableGeo* geo);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Cell Face Effect
|
||||
//
|
||||
//==================================================================================================
|
||||
class CellEdgeEffectGenerator : public caf::EffectGenerator
|
||||
{
|
||||
public:
|
||||
CellEdgeEffectGenerator(const cvf::ScalarMapper* edgeScalarMapper, const cvf::ScalarMapper* cellScalarMapper);
|
||||
|
||||
void setOpacityLevel(float opacity) { m_opacityLevel = cvf::Math::clamp(opacity, 0.0f , 1.0f ); }
|
||||
void setUndefinedColor(cvf::Color3f color) { m_undefinedColor = color; }
|
||||
void setCullBackfaces(bool cullBackFaces) { m_cullBackfaces = cullBackFaces; }
|
||||
void setDefaultCellColor(cvf::Color3f color) { m_defaultCellColor = color; }
|
||||
|
||||
virtual bool isEqual( const EffectGenerator* other ) const;
|
||||
virtual EffectGenerator* copy() const;
|
||||
|
||||
|
||||
protected:
|
||||
virtual void updateForShaderBasedRendering(cvf::Effect* effect) const;
|
||||
virtual void updateForFixedFunctionRendering(cvf::Effect* effect) const;
|
||||
|
||||
private:
|
||||
cvf::cref<cvf::ScalarMapper> m_edgeScalarMapper;
|
||||
cvf::cref<cvf::ScalarMapper> m_cellScalarMapper;
|
||||
|
||||
float m_opacityLevel;
|
||||
bool m_cullBackfaces;
|
||||
cvf::Color3f m_undefinedColor;
|
||||
cvf::Color3f m_defaultCellColor;
|
||||
|
||||
};
|
||||
|
||||
329
ApplicationCode/ModelVisualization/RivGridPartMgr.cpp
Normal file
329
ApplicationCode/ModelVisualization/RivGridPartMgr.cpp
Normal file
@@ -0,0 +1,329 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
#include "RivGridPartMgr.h"
|
||||
#include "cvfPart.h"
|
||||
#include "cafEffectGenerator.h"
|
||||
#include "cvfStructGrid.h"
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfModelBasicList.h"
|
||||
#include "RivCellEdgeEffectGenerator.h"
|
||||
#include "RimReservoirView.h"
|
||||
#include "RimResultSlot.h"
|
||||
#include "RimCellEdgeResultSlot.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivGridPartMgr::RivGridPartMgr(const RigGridBase* grid, size_t gridIdx)
|
||||
: m_surfaceGenerator(grid),
|
||||
m_faultGenerator(grid),
|
||||
m_gridIdx(gridIdx),
|
||||
m_surfaceFaceFilter(grid),
|
||||
m_faultFaceFilter(grid),
|
||||
m_opacityLevel(1.0f),
|
||||
m_defaultColor(cvf::Color3::WHITE)
|
||||
{
|
||||
CVF_ASSERT(grid);
|
||||
m_cellVisibility = new cvf::UByteArray;
|
||||
m_surfaceFacesTextureCoords = new cvf::Vec2fArray;
|
||||
m_faultFacesTextureCoords = new cvf::Vec2fArray;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivGridPartMgr::setTransform(cvf::Transform* scaleTransform)
|
||||
{
|
||||
m_scaleTransform = scaleTransform;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivGridPartMgr::setCellVisibility(cvf::UByteArray* cellVisibilities)
|
||||
{
|
||||
CVF_ASSERT(m_scaleTransform.notNull());
|
||||
CVF_ASSERT(cellVisibilities);
|
||||
|
||||
m_cellVisibility = cellVisibilities;
|
||||
|
||||
m_surfaceGenerator.setCellVisibility(cellVisibilities);
|
||||
m_surfaceFaceFilter.m_showExternalFaces = true;
|
||||
m_surfaceFaceFilter.m_showFaultFaces = false;
|
||||
m_surfaceGenerator.addFaceVisibilityFilter(&m_surfaceFaceFilter);
|
||||
|
||||
m_faultGenerator.setCellVisibility(cellVisibilities);
|
||||
m_faultFaceFilter.m_showExternalFaces = false;
|
||||
m_faultFaceFilter.m_showFaultFaces = true;
|
||||
m_faultGenerator.addFaceVisibilityFilter(&m_faultFaceFilter);
|
||||
|
||||
generatePartGeometry(m_surfaceGenerator, false);
|
||||
generatePartGeometry(m_faultGenerator, true);
|
||||
}
|
||||
|
||||
void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry)
|
||||
{
|
||||
bool useBufferObjects = true;
|
||||
// Surface geometry
|
||||
{
|
||||
cvf::ref<cvf::DrawableGeo> geo = geoBuilder.generateSurface();
|
||||
if (geo.notNull())
|
||||
{
|
||||
geo->computeNormals();
|
||||
|
||||
if (useBufferObjects)
|
||||
{
|
||||
geo->setRenderMode(cvf::DrawableGeo::BUFFER_OBJECT);
|
||||
}
|
||||
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setName("Grid " + cvf::String(static_cast<int>(m_gridIdx)));
|
||||
part->setId(m_gridIdx); // !! For now, use grid index as part ID (needed for pick info)
|
||||
part->setDrawable(geo.p());
|
||||
part->setTransform(m_scaleTransform.p());
|
||||
|
||||
// Set mapping from triangle face index to cell index
|
||||
part->setSourceInfo(geoBuilder.triangleToSourceGridCellMap().p());
|
||||
|
||||
part->updateBoundingBox();
|
||||
|
||||
// Set default effect
|
||||
caf::SurfaceEffectGenerator geometryEffgen(cvf::Color4f(cvf::Color3f::WHITE), true);
|
||||
cvf::ref<cvf::Effect> geometryOnlyEffect = geometryEffgen.generateEffect();
|
||||
part->setEffect(geometryOnlyEffect.p());
|
||||
|
||||
if (faultGeometry)
|
||||
{
|
||||
part->setEnableMask(faultBit);
|
||||
m_faultFaces = part;
|
||||
}
|
||||
else
|
||||
{
|
||||
part->setEnableMask(surfaceBit);
|
||||
m_surfaceFaces = part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mesh geometry
|
||||
{
|
||||
cvf::ref<cvf::DrawableGeo> geoMesh = geoBuilder.createMeshDrawable();
|
||||
if (geoMesh.notNull())
|
||||
{
|
||||
if (useBufferObjects)
|
||||
{
|
||||
geoMesh->setRenderMode(cvf::DrawableGeo::BUFFER_OBJECT);
|
||||
}
|
||||
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setName("Grid mesh " + cvf::String(static_cast<int>(m_gridIdx)));
|
||||
part->setDrawable(geoMesh.p());
|
||||
|
||||
part->setTransform(m_scaleTransform.p());
|
||||
part->updateBoundingBox();
|
||||
|
||||
cvf::ref<cvf::Effect> eff;
|
||||
if (faultGeometry)
|
||||
{
|
||||
caf::MeshEffectGenerator effGen(cvf::Color3f::BLACK);
|
||||
eff = effGen.generateEffect();
|
||||
|
||||
part->setEnableMask(meshFaultBit);
|
||||
part->setEffect(eff.p());
|
||||
m_faultGridLines = part;
|
||||
}
|
||||
else
|
||||
{
|
||||
caf::MeshEffectGenerator effGen(cvf::Color3f::WHITE);
|
||||
eff = effGen.generateEffect();
|
||||
|
||||
// Set priority to make sure fault lines are rendered first
|
||||
part->setPriority(10);
|
||||
|
||||
part->setEnableMask(meshSurfaceBit);
|
||||
part->setEffect(eff.p());
|
||||
m_surfaceGridLines = part;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivGridPartMgr::appendPartsToModel(cvf::ModelBasicList* model)
|
||||
{
|
||||
CVF_ASSERT(model != NULL);
|
||||
|
||||
if(m_surfaceFaces.notNull() ) model->addPart(m_surfaceFaces.p() );
|
||||
if(m_surfaceGridLines.notNull()) model->addPart(m_surfaceGridLines.p());
|
||||
if(m_faultFaces.notNull() ) model->addPart(m_faultFaces.p() );
|
||||
if(m_faultGridLines.notNull() ) model->addPart(m_faultGridLines.p() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivGridPartMgr::updateCellColor(cvf::Color4f color)
|
||||
{
|
||||
if (m_surfaceFaces.isNull() && m_faultFaces.isNull()) return;
|
||||
|
||||
// Set default effect
|
||||
caf::SurfaceEffectGenerator geometryEffgen(color, true);
|
||||
cvf::ref<cvf::Effect> geometryOnlyEffect = geometryEffgen.generateEffect();
|
||||
|
||||
if (m_surfaceFaces.notNull()) m_surfaceFaces->setEffect(geometryOnlyEffect.p());
|
||||
if (m_faultFaces.notNull()) m_faultFaces->setEffect(geometryOnlyEffect.p());
|
||||
|
||||
if (color.a() < 1.0f)
|
||||
{
|
||||
// Set priority to make sure this transparent geometry are rendered last
|
||||
if (m_surfaceFaces.notNull()) m_surfaceFaces->setPriority(100);
|
||||
if (m_faultFaces.notNull()) m_faultFaces->setPriority(100);
|
||||
}
|
||||
|
||||
m_opacityLevel = color.a();
|
||||
m_defaultColor = color.toColor3f();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot)
|
||||
{
|
||||
CVF_ASSERT(cellResultSlot);
|
||||
|
||||
size_t scalarSetIndex = cellResultSlot->gridScalarIndex();
|
||||
const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper();
|
||||
|
||||
// If the result is static, only read that.
|
||||
size_t resTimeStepIdx = timeStepIndex;
|
||||
if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0;
|
||||
|
||||
// Outer surface
|
||||
if (m_surfaceFaces.notNull())
|
||||
{
|
||||
m_surfaceGenerator.textureCoordinates(m_surfaceFacesTextureCoords.p(), resTimeStepIdx, scalarSetIndex, mapper);
|
||||
|
||||
for(size_t i = 0; i < m_surfaceFacesTextureCoords->size(); ++i)
|
||||
{
|
||||
if ((*m_surfaceFacesTextureCoords)[i].y() != 1.0f)
|
||||
{
|
||||
if (m_opacityLevel == 1.0f) (*m_surfaceFacesTextureCoords)[i].y() = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_surfaceFaces->drawable());
|
||||
if (dg) dg->setTextureCoordArray(m_surfaceFacesTextureCoords.p());
|
||||
|
||||
bool usePolygonOffset = true;
|
||||
caf::ScalarMapperEffectGenerator scalarEffgen(mapper, usePolygonOffset);
|
||||
|
||||
scalarEffgen.setOpacityLevel(m_opacityLevel);
|
||||
|
||||
cvf::ref<cvf::Effect> scalarEffect = scalarEffgen.generateEffect();
|
||||
|
||||
m_surfaceFaces->setEffect(scalarEffect.p());
|
||||
}
|
||||
|
||||
// Faults
|
||||
if (m_faultFaces.notNull())
|
||||
{
|
||||
m_faultGenerator.textureCoordinates(m_faultFacesTextureCoords.p(), resTimeStepIdx, scalarSetIndex, mapper);
|
||||
|
||||
for(size_t i = 0; i < m_faultFacesTextureCoords->size(); ++i)
|
||||
{
|
||||
if ((*m_faultFacesTextureCoords)[i].y() != 1.0f)
|
||||
{
|
||||
if (m_opacityLevel == 1.0f) (*m_faultFacesTextureCoords)[i].y() = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_faultFaces->drawable());
|
||||
if (dg) dg->setTextureCoordArray(m_faultFacesTextureCoords.p());
|
||||
|
||||
bool usePolygonOffset = true;
|
||||
caf::ScalarMapperEffectGenerator scalarEffgen(mapper, usePolygonOffset);
|
||||
|
||||
scalarEffgen.setOpacityLevel(m_opacityLevel);
|
||||
|
||||
cvf::ref<cvf::Effect> scalarEffect = scalarEffgen.generateEffect();
|
||||
|
||||
m_faultFaces->setEffect(scalarEffect.p());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivGridPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot)
|
||||
{
|
||||
if (m_surfaceFaces.notNull())
|
||||
{
|
||||
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_surfaceFaces->drawable());
|
||||
if (dg)
|
||||
{
|
||||
RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultSlot, cellEdgeResultSlot, &m_surfaceGenerator, dg);
|
||||
|
||||
cvf::ScalarMapper* cellScalarMapper = NULL;
|
||||
if (cellResultSlot->hasResult()) cellScalarMapper = cellResultSlot->legendConfig()->scalarMapper();
|
||||
|
||||
CellEdgeEffectGenerator cellFaceEffectGen(cellEdgeResultSlot->legendConfig()->scalarMapper(), cellScalarMapper);
|
||||
cellFaceEffectGen.setOpacityLevel(m_opacityLevel);
|
||||
cellFaceEffectGen.setDefaultCellColor(m_defaultColor);
|
||||
|
||||
cvf::ref<cvf::Effect> eff = cellFaceEffectGen.generateEffect();
|
||||
|
||||
m_surfaceFaces->setEffect(eff.p());
|
||||
}
|
||||
}
|
||||
if (m_faultFaces.notNull())
|
||||
{
|
||||
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_faultFaces->drawable());
|
||||
if (dg)
|
||||
{
|
||||
RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultSlot, cellEdgeResultSlot, &m_faultGenerator, dg);
|
||||
|
||||
cvf::ScalarMapper* cellScalarMapper = NULL;
|
||||
if (cellResultSlot->hasResult()) cellScalarMapper = cellResultSlot->legendConfig()->scalarMapper();
|
||||
|
||||
CellEdgeEffectGenerator cellFaceEffectGen(cellEdgeResultSlot->legendConfig()->scalarMapper(), cellScalarMapper);
|
||||
cellFaceEffectGen.setOpacityLevel(m_opacityLevel);
|
||||
cellFaceEffectGen.setDefaultCellColor(m_defaultColor);
|
||||
|
||||
cvf::ref<cvf::Effect> eff = cellFaceEffectGen.generateEffect();
|
||||
|
||||
m_faultFaces->setEffect(eff.p());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivGridPartMgr::~RivGridPartMgr()
|
||||
{
|
||||
#if 0
|
||||
if (m_faultFaces.notNull()) m_faultFaces->deleteOrReleaseOpenGLResources();
|
||||
if (m_faultGridLines.notNull()) m_faultGridLines->deleteOrReleaseOpenGLResources();
|
||||
if (m_surfaceGridLines.notNull()) m_surfaceGridLines->deleteOrReleaseOpenGLResources();
|
||||
if (m_surfaceFaces.notNull()) m_surfaceFaces->deleteOrReleaseOpenGLResources();
|
||||
#endif
|
||||
}
|
||||
95
ApplicationCode/ModelVisualization/RivGridPartMgr.h
Normal file
95
ApplicationCode/ModelVisualization/RivGridPartMgr.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfStructGridGeometryGenerator.h"
|
||||
#include "RigGridBase.h"
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class StructGridInterface;
|
||||
class ModelBasicList;
|
||||
class Transform;
|
||||
class Part;
|
||||
}
|
||||
|
||||
class RimResultSlot;
|
||||
class RimCellEdgeResultSlot;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// RivGridGeometry: Class to handle visualization structures that embodies a specific grid at a specific time step.
|
||||
/// frame on a certain level
|
||||
/// LGR's have their own instance and the parent grid as well
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
class RivGridPartMgr: public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivGridPartMgr(const RigGridBase* grid, size_t gridIdx);
|
||||
~RivGridPartMgr();
|
||||
void setTransform(cvf::Transform* scaleTransform);
|
||||
void setCellVisibility(cvf::UByteArray* cellVisibilities );
|
||||
cvf::ref<cvf::UByteArray> cellVisibility() { return m_cellVisibility;}
|
||||
|
||||
void updateCellColor(cvf::Color4f color);
|
||||
void updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot);
|
||||
void updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot,
|
||||
RimCellEdgeResultSlot* cellEdgeResultSlot);
|
||||
|
||||
void appendPartsToModel(cvf::ModelBasicList* model);
|
||||
|
||||
enum PartRenderMaskEnum
|
||||
{
|
||||
surfaceBit = 0x00000001,
|
||||
meshSurfaceBit = 0x00000002,
|
||||
faultBit = 0x00000004,
|
||||
meshFaultBit = 0x00000008,
|
||||
};
|
||||
|
||||
private:
|
||||
void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry);
|
||||
|
||||
private:
|
||||
size_t m_gridIdx;
|
||||
cvf::ref<cvf::Transform> m_scaleTransform;
|
||||
float m_opacityLevel;
|
||||
cvf::Color3f m_defaultColor;
|
||||
|
||||
// Surface visualization
|
||||
cvf::StructGridGeometryGenerator m_surfaceGenerator;
|
||||
RigGridCellFaceVisibilityFilter m_surfaceFaceFilter;
|
||||
cvf::ref<cvf::Part> m_surfaceFaces;
|
||||
cvf::ref<cvf::Vec2fArray> m_surfaceFacesTextureCoords;
|
||||
|
||||
cvf::ref<cvf::Part> m_surfaceGridLines;
|
||||
|
||||
// Fault visualization
|
||||
cvf::StructGridGeometryGenerator m_faultGenerator;
|
||||
RigGridCellFaceVisibilityFilter m_faultFaceFilter;
|
||||
cvf::ref<cvf::Part> m_faultFaces;
|
||||
cvf::ref<cvf::Vec2fArray> m_faultFacesTextureCoords;
|
||||
|
||||
cvf::ref<cvf::Part> m_faultGridLines;
|
||||
|
||||
cvf::ref<cvf::UByteArray> m_cellVisibility;
|
||||
|
||||
//cvf::ref<cvf::Part> m_gridOutlines;
|
||||
};
|
||||
572
ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp
Normal file
572
ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp
Normal file
@@ -0,0 +1,572 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "cvfLibCore.h"
|
||||
#include "cvfLibRender.h"
|
||||
#include "cvfLibGeometry.h"
|
||||
#include "cvfLibViewing.h"
|
||||
|
||||
#include "RivPipeGeometryGenerator.h"
|
||||
#include <vector>
|
||||
#include "cafEffectGenerator.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivPipeGeometryGenerator::RivPipeGeometryGenerator()
|
||||
{
|
||||
m_radius = 1.0;
|
||||
m_crossSectionNodeCount = 8;
|
||||
m_minimumBendAngle = 80.0;
|
||||
m_bendScalingFactor = 0.00001;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivPipeGeometryGenerator::~RivPipeGeometryGenerator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::setPipeCenterCoords(const cvf::Vec3dArray* coords)
|
||||
{
|
||||
m_originalPipeCenterCoords = coords;
|
||||
|
||||
clearComputedData();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::setMinimumBendAngle(double degrees)
|
||||
{
|
||||
m_minimumBendAngle = degrees;
|
||||
|
||||
clearComputedData();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::setBendScalingFactor(double scaleFactor)
|
||||
{
|
||||
m_bendScalingFactor = scaleFactor;
|
||||
|
||||
clearComputedData();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::setRadius(double radius)
|
||||
{
|
||||
m_radius = radius;
|
||||
|
||||
clearComputedData();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::setCrossSectionVertexCount(size_t nodeCount)
|
||||
{
|
||||
m_crossSectionNodeCount = nodeCount;
|
||||
|
||||
clearComputedData();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableGeo> RivPipeGeometryGenerator::createPipeSurface()
|
||||
{
|
||||
if (m_radius == 0.0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
updateFilteredPipeCenterCoords();
|
||||
|
||||
cvf::ref<cvf::Vec3dArray> activeCoords = new cvf::Vec3dArray(m_filteredPipeCenterCoords);
|
||||
|
||||
return RivPipeGeometryGenerator::generateExtrudedCylinder(m_radius, m_crossSectionNodeCount, activeCoords.p());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableGeo> RivPipeGeometryGenerator::createCenterLine()
|
||||
{
|
||||
return generateLine(m_originalPipeCenterCoords.p());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::pipeSurfaceTextureCoords(cvf::Vec2fArray* textureCoords, const std::vector<double>& segmentResults, const cvf::ScalarMapper* mapper) const
|
||||
{
|
||||
CVF_ASSERT(textureCoords);
|
||||
CVF_ASSERT(mapper);
|
||||
CVF_ASSERT(segmentResults.size() == m_originalPipeCenterCoords->size() - 1);
|
||||
|
||||
size_t nodeCountPerSegment = m_crossSectionNodeCount * 4;
|
||||
|
||||
size_t vertexCount = m_filteredPipeSegmentToResult.size() * nodeCountPerSegment;
|
||||
if (textureCoords->size() != vertexCount) textureCoords->resize(vertexCount);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < m_filteredPipeSegmentToResult.size(); i++)
|
||||
{
|
||||
size_t resultIndex = m_filteredPipeSegmentToResult[i];
|
||||
|
||||
cvf::Vec2f texCoord = mapper->mapToTextureCoord(segmentResults[resultIndex]);
|
||||
|
||||
size_t j;
|
||||
for (j = 0; j < nodeCountPerSegment; j++)
|
||||
{
|
||||
textureCoords->set(i * nodeCountPerSegment + j, texCoord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::centerlineTextureCoords(cvf::Vec2fArray* textureCoords, const std::vector<double>& segmentResults, const cvf::ScalarMapper* mapper) const
|
||||
{
|
||||
CVF_ASSERT(textureCoords);
|
||||
CVF_ASSERT(mapper);
|
||||
CVF_ASSERT(segmentResults.size() == m_originalPipeCenterCoords->size() - 1);
|
||||
|
||||
size_t vertexCount = segmentResults.size() * 2;
|
||||
if (textureCoords->size() != vertexCount) textureCoords->resize(vertexCount);
|
||||
|
||||
for (size_t vxIdx = 0; vxIdx < vertexCount; ++vxIdx)
|
||||
{
|
||||
cvf::Vec2f texCoord = mapper->mapToTextureCoord(segmentResults[vxIdx/2]);
|
||||
textureCoords->set(vxIdx, texCoord);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// The circle points are generated in positive direction with circle normal pointing along yDir ^ zDir
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::computeCircle(double radius, size_t tesselationCount, const cvf::Vec3d& center, const cvf::Vec3d& yDirection, const cvf::Vec3d& zDirection, std::vector<cvf::Vec3d>* nodes)
|
||||
{
|
||||
cvf::Vec3d normal;
|
||||
cvf::Vec3d expandedCoord;
|
||||
|
||||
double delta = (2 * cvf::PI_D) / tesselationCount;
|
||||
double angle = 0.0;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < tesselationCount; i++)
|
||||
{
|
||||
// These are the local coordinates on the circle
|
||||
double fLocalNormCoordY = cvf::Math::cos(angle);
|
||||
double fLocalNormCoordZ = cvf::Math::sin(angle);
|
||||
|
||||
// Compute normal (vector going from center to the point on the circle)
|
||||
// Do it this way and we can use this normal directly as long as both input orientation vectors are normalized (which they should be)
|
||||
|
||||
normal = yDirection*fLocalNormCoordY + zDirection*fLocalNormCoordZ;
|
||||
normal.normalize();
|
||||
|
||||
// get the global expanded coord by scaling by radius
|
||||
|
||||
expandedCoord = center + radius*normal;
|
||||
nodes->push_back(expandedCoord);
|
||||
|
||||
angle += delta;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableGeo> RivPipeGeometryGenerator::generateLine(const cvf::Vec3dArray* coords)
|
||||
{
|
||||
CVF_ASSERT(coords != NULL);
|
||||
|
||||
if (coords->size() < 2 ) return NULL;
|
||||
|
||||
size_t duplicateVertexCount = 2 * (coords->size() - 1);
|
||||
|
||||
cvf::ref<cvf::UIntArray> indices = new cvf::UIntArray;
|
||||
indices->resize(duplicateVertexCount);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < duplicateVertexCount; i++)
|
||||
{
|
||||
indices->set(i, i);
|
||||
}
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
||||
|
||||
// Convert double data to float data before sending them to ceeViz.
|
||||
// Sigh ....
|
||||
cvf::ref<cvf::Vec3fArray> floatCoords = new cvf::Vec3fArray;
|
||||
floatCoords->resize(duplicateVertexCount);
|
||||
|
||||
(*floatCoords)[0] = cvf::Vec3f((*coords)[0]);
|
||||
|
||||
for (i = 1; i < coords->size() - 1; ++i)
|
||||
{
|
||||
(*floatCoords)[2 * i - 1] = cvf::Vec3f((*coords)[i]);
|
||||
(*floatCoords)[2 * i + 0] = cvf::Vec3f((*coords)[i]);
|
||||
}
|
||||
|
||||
(*floatCoords)[duplicateVertexCount - 1] = cvf::Vec3f((*coords)[coords->size() - 1]);
|
||||
|
||||
geo->setVertexArray(floatCoords.p());
|
||||
|
||||
cvf::ref<cvf::PrimitiveSetIndexedUInt> prim = new cvf::PrimitiveSetIndexedUInt(cvf::PT_LINES);
|
||||
prim->setIndices(indices.p());
|
||||
|
||||
geo->addPrimitiveSet(prim.p());
|
||||
|
||||
return geo;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableGeo> RivPipeGeometryGenerator::generateExtrudedCylinder(double radius, size_t crossSectionNodeCount, const cvf::Vec3dArray* cylinderCenterCoords)
|
||||
{
|
||||
CVF_ASSERT(cylinderCenterCoords != NULL);
|
||||
|
||||
if (cylinderCenterCoords->size() < 2) return NULL;
|
||||
|
||||
std::vector<cvf::Vec3f> crossSectionVertices;
|
||||
std::vector<cvf::Vec3f> cylinderSegmentNormals;
|
||||
|
||||
cvf::Vec3d dir = (*cylinderCenterCoords)[1] - (*cylinderCenterCoords)[0];
|
||||
dir.normalize();
|
||||
|
||||
cvf::Vec3d orient1 = dir.perpendicularVector();
|
||||
orient1.normalize();
|
||||
|
||||
cvf::Vec3d orient2 = dir ^ orient1;
|
||||
orient2.normalize();
|
||||
|
||||
std::vector<cvf::Vec3d> extrudedNodes;
|
||||
computeCircle(radius, crossSectionNodeCount, (*cylinderCenterCoords)[0], orient1, orient2, &extrudedNodes);
|
||||
|
||||
// Insert the first set of vertices
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < extrudedNodes.size(); i++)
|
||||
{
|
||||
crossSectionVertices.push_back(cvf::Vec3f(extrudedNodes[i]));
|
||||
}
|
||||
|
||||
|
||||
// Calculate first valid pipe direction, to be able to handle centerNodes in the same place
|
||||
|
||||
cvf::Vec3d lastValidPipeDirection(0,0,-1);
|
||||
for (i = 0; i < cylinderCenterCoords->size() - 1; i++)
|
||||
{
|
||||
cvf::Vec3d candidateDir = (*cylinderCenterCoords)[i] - (*cylinderCenterCoords)[i+1];
|
||||
if (candidateDir.normalize())
|
||||
{
|
||||
lastValidPipeDirection = candidateDir;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= cylinderCenterCoords->size()-1) return NULL; // The pipe coordinates is all the same point
|
||||
|
||||
// Loop along the cylinder center coords and calculate the cross section vertexes in each center vertex
|
||||
|
||||
for (size_t ccIdx = 0; ccIdx < cylinderCenterCoords->size() - 1; ccIdx++)
|
||||
{
|
||||
size_t nextCcIdx = ccIdx + 1;
|
||||
|
||||
// Calculate this and next pipe direction, and intersection plane
|
||||
|
||||
cvf::Vec3d firstCoord = (*cylinderCenterCoords)[ccIdx];
|
||||
cvf::Vec3d secondCoord = (*cylinderCenterCoords)[nextCcIdx];
|
||||
|
||||
cvf::Vec3d candidateDir = secondCoord - firstCoord;
|
||||
if (!candidateDir.normalize())
|
||||
{
|
||||
candidateDir = lastValidPipeDirection;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastValidPipeDirection = candidateDir;
|
||||
}
|
||||
|
||||
cvf::Vec3d nextDir = lastValidPipeDirection;
|
||||
if (nextCcIdx + 1 < cylinderCenterCoords->size())
|
||||
{
|
||||
cvf::Vec3d thirdCoord = (*cylinderCenterCoords)[nextCcIdx + 1];
|
||||
nextDir = thirdCoord - secondCoord;
|
||||
}
|
||||
|
||||
// If the next vector is too small, just assume the pipe is heading straight on
|
||||
if (!nextDir.normalize()) nextDir = candidateDir;
|
||||
|
||||
cvf::Vec3d intersectionPlaneNormal = candidateDir + nextDir;
|
||||
|
||||
// if (intersectionPlaneNormal.lengthSquared() < 1e-10) intersectionPlaneNormal = nextDir; // candidateDir == -nextDir => 180 deg turn
|
||||
|
||||
computeExtrudedCoordsAndNormals(secondCoord, intersectionPlaneNormal, candidateDir, crossSectionNodeCount, &extrudedNodes, &crossSectionVertices, &cylinderSegmentNormals);
|
||||
}
|
||||
|
||||
size_t crossSectionCount = crossSectionVertices.size() / crossSectionNodeCount;
|
||||
|
||||
if (crossSectionCount < 2) return NULL;
|
||||
|
||||
CVF_ASSERT(crossSectionVertices.size() - crossSectionNodeCount == cylinderSegmentNormals.size());
|
||||
|
||||
size_t segmentCount = crossSectionCount - 1;
|
||||
size_t vertexCount = segmentCount * crossSectionNodeCount * 4;
|
||||
|
||||
cvf::ref<cvf::Vec3fArray> quadVertexArray = new cvf::Vec3fArray();
|
||||
quadVertexArray->reserve(vertexCount);
|
||||
|
||||
cvf::ref<cvf::Vec3fArray> quadNormalArray = new cvf::Vec3fArray();
|
||||
quadNormalArray->reserve(vertexCount);
|
||||
|
||||
size_t segmentIdx = 0;
|
||||
for (segmentIdx = 0; segmentIdx < segmentCount; segmentIdx++)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < crossSectionNodeCount - 1; i++)
|
||||
{
|
||||
quadVertexArray->add(crossSectionVertices[( (segmentIdx + 0) * crossSectionNodeCount) + i + 0]);
|
||||
quadVertexArray->add(crossSectionVertices[( (segmentIdx + 0) * crossSectionNodeCount) + i + 1]);
|
||||
quadVertexArray->add(crossSectionVertices[( (segmentIdx + 1) * crossSectionNodeCount) + i + 1]);
|
||||
quadVertexArray->add(crossSectionVertices[( (segmentIdx + 1) * crossSectionNodeCount) + i + 0]);
|
||||
|
||||
quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + i + 0]);
|
||||
quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + i + 1]);
|
||||
quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + i + 1]);
|
||||
quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + i + 0]);
|
||||
}
|
||||
|
||||
// Last quad closing the cylinder
|
||||
quadVertexArray->add(crossSectionVertices[( (segmentIdx + 0) * crossSectionNodeCount) + crossSectionNodeCount - 1]);
|
||||
quadVertexArray->add(crossSectionVertices[( (segmentIdx + 0) * crossSectionNodeCount) + 0]);
|
||||
quadVertexArray->add(crossSectionVertices[( (segmentIdx + 1) * crossSectionNodeCount) + 0]);
|
||||
quadVertexArray->add(crossSectionVertices[( (segmentIdx + 1) * crossSectionNodeCount) + crossSectionNodeCount - 1]);
|
||||
|
||||
quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + crossSectionNodeCount - 1]);
|
||||
quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + 0]);
|
||||
quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + 0]);
|
||||
quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + crossSectionNodeCount - 1]);
|
||||
}
|
||||
|
||||
CVF_ASSERT(vertexCount == quadVertexArray->size());
|
||||
CVF_ASSERT(vertexCount == quadNormalArray->size());
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
||||
geo->setFromQuadVertexArray(quadVertexArray.p());
|
||||
geo->setNormalArray(quadNormalArray.p());
|
||||
|
||||
return geo;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::computeExtrudedCoordsAndNormals( cvf::Vec3d intersectionCoord,
|
||||
cvf::Vec3d intersectionPlaneNormal,
|
||||
cvf::Vec3d segmentDirection,
|
||||
size_t crossSectionNodeCount,
|
||||
std::vector<cvf::Vec3d>* extrudedNodes,
|
||||
std::vector<cvf::Vec3f>* crossSectionVertices,
|
||||
std::vector<cvf::Vec3f>* cylinderSegmentNormals)
|
||||
{
|
||||
cvf::Plane intersectionPlane;
|
||||
intersectionPlane.setFromPointAndNormal(intersectionCoord, intersectionPlaneNormal);
|
||||
|
||||
cvf::Ray ray;
|
||||
ray.setDirection(segmentDirection);
|
||||
|
||||
// Calculate next set of extruded vertices
|
||||
|
||||
std::vector<cvf::Vec3d> nextExtrudedNodes;
|
||||
|
||||
for (size_t csnIdx = 0; csnIdx < crossSectionNodeCount; csnIdx++)
|
||||
{
|
||||
ray.setOrigin((*extrudedNodes)[csnIdx]);
|
||||
|
||||
cvf::Vec3d intersection;
|
||||
if (ray.planeIntersect(intersectionPlane, &intersection))
|
||||
{
|
||||
nextExtrudedNodes.push_back(intersection);
|
||||
}
|
||||
else
|
||||
{
|
||||
cvf::Ray oppositeRay(ray);
|
||||
oppositeRay.setDirection(-segmentDirection);
|
||||
if (oppositeRay.planeIntersect(intersectionPlane, &intersection))
|
||||
{
|
||||
nextExtrudedNodes.push_back(intersection);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parallel plane and ray
|
||||
CVF_ASSERT(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate the normals for the cylinder segment
|
||||
|
||||
cvf::Plane cylinderPlane;
|
||||
cylinderPlane.setFromPointAndNormal(intersectionCoord, segmentDirection);
|
||||
|
||||
for (size_t csnIdx = 0; csnIdx < crossSectionNodeCount; csnIdx++)
|
||||
{
|
||||
crossSectionVertices->push_back(cvf::Vec3f(nextExtrudedNodes[csnIdx]));
|
||||
|
||||
cvf::Vec3d pipeNormal;
|
||||
cylinderPlane.projectVector(nextExtrudedNodes[csnIdx] - intersectionCoord, &pipeNormal);
|
||||
cylinderSegmentNormals->push_back(cvf::Vec3f(pipeNormal));
|
||||
}
|
||||
|
||||
*extrudedNodes = nextExtrudedNodes;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords()
|
||||
{
|
||||
if (m_originalPipeCenterCoords->size() < 2) return;
|
||||
if (m_filteredPipeCenterCoords.size() > 0) return;
|
||||
|
||||
|
||||
double distanceTolerance = 1e-10;
|
||||
double angleTolerance = 1e-5;
|
||||
|
||||
size_t firstSegmentWithLength = 0;
|
||||
size_t i;
|
||||
for (i = 0; i < m_originalPipeCenterCoords->size() - 1; i++)
|
||||
{
|
||||
cvf::Vec3d candidateDir = (*m_originalPipeCenterCoords)[i] - (*m_originalPipeCenterCoords)[i+1];
|
||||
if (candidateDir.normalize())
|
||||
{
|
||||
firstSegmentWithLength = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only zero-length segments
|
||||
if (i == m_originalPipeCenterCoords->size() - 1) return;
|
||||
|
||||
m_filteredPipeCenterCoords.push_back(m_originalPipeCenterCoords->get(firstSegmentWithLength));
|
||||
m_filteredPipeSegmentToResult.push_back(firstSegmentWithLength);
|
||||
|
||||
cvf::Vec3d lastValidDirectionAB;
|
||||
size_t lastValidSegment = 0;
|
||||
|
||||
for (i = firstSegmentWithLength + 1; i < m_originalPipeCenterCoords->size() - 1; i++)
|
||||
{
|
||||
cvf::Vec3d coordA = m_originalPipeCenterCoords->get(i - 1);
|
||||
cvf::Vec3d coordB = m_originalPipeCenterCoords->get(i + 0);
|
||||
cvf::Vec3d coordC = m_originalPipeCenterCoords->get(i + 1);
|
||||
|
||||
cvf::Vec3d directionAB = coordB - coordA;
|
||||
|
||||
// Skip segment lengths below tolerance
|
||||
if (directionAB.lengthSquared() > distanceTolerance)
|
||||
{
|
||||
lastValidDirectionAB = directionAB.getNormalized();
|
||||
lastValidSegment = i;
|
||||
}
|
||||
|
||||
cvf::Vec3d directionBC = coordC - coordB;
|
||||
if (directionBC.lengthSquared() < distanceTolerance)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double cosMinBendAngle = cvf::Math::cos(cvf::Math::toRadians(m_minimumBendAngle));
|
||||
double dotProduct = lastValidDirectionAB * (-directionBC).getNormalized();
|
||||
if (dotProduct > cosMinBendAngle)
|
||||
{
|
||||
bool success = false;
|
||||
cvf::Vec3d pipeIntermediateDirection = (lastValidDirectionAB + directionBC.getNormalized()).getNormalized(&success);
|
||||
if (!success)
|
||||
{
|
||||
pipeIntermediateDirection = lastValidDirectionAB.perpendicularVector();
|
||||
}
|
||||
|
||||
double bendRadius = m_bendScalingFactor * m_radius + 1.0e-30;
|
||||
cvf::Vec3d firstIntermediate = coordB - pipeIntermediateDirection * bendRadius;
|
||||
|
||||
m_filteredPipeCenterCoords.push_back(firstIntermediate);
|
||||
m_filteredPipeSegmentToResult.push_back(lastValidSegment);
|
||||
|
||||
m_filteredPipeCenterCoords.push_back(coordB);
|
||||
m_filteredPipeSegmentToResult.push_back(i);
|
||||
|
||||
cvf::Vec3d secondIntermediate = coordB + pipeIntermediateDirection * bendRadius;
|
||||
m_filteredPipeCenterCoords.push_back(secondIntermediate);
|
||||
m_filteredPipeSegmentToResult.push_back(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_filteredPipeCenterCoords.push_back(coordB);
|
||||
m_filteredPipeSegmentToResult.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Add last cross section if not duplicate coordinate
|
||||
cvf::Vec3d coordA = m_originalPipeCenterCoords->get(m_originalPipeCenterCoords->size() - 2);
|
||||
cvf::Vec3d coordB = m_originalPipeCenterCoords->get(m_originalPipeCenterCoords->size() - 1);
|
||||
|
||||
cvf::Vec3d directionAB = coordB - coordA;
|
||||
if (directionAB.lengthSquared() > distanceTolerance)
|
||||
{
|
||||
m_filteredPipeCenterCoords.push_back(m_originalPipeCenterCoords->get(m_originalPipeCenterCoords->size() - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove last segment as the length is below tolerance
|
||||
m_filteredPipeSegmentToResult.pop_back();
|
||||
}
|
||||
|
||||
CVF_ASSERT(m_filteredPipeCenterCoords.size() - 1 == m_filteredPipeSegmentToResult.size());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivPipeGeometryGenerator::clearComputedData()
|
||||
{
|
||||
m_filteredPipeCenterCoords.clear();
|
||||
m_filteredPipeSegmentToResult.clear();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
class RivPipeGeometryGenerator : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivPipeGeometryGenerator();
|
||||
~RivPipeGeometryGenerator();
|
||||
|
||||
// Coordinates and orientations
|
||||
void setPipeCenterCoords(const cvf::Vec3dArray* coords);
|
||||
|
||||
// Pipe bends with a opening angle below given angle is modified with extra bend coordinates
|
||||
void setMinimumBendAngle(double degrees);
|
||||
// Scaling factor used to control how far from original pipe position the extra bend coordinates are located
|
||||
// This will affect how sharp or smooth bend will appear
|
||||
void setBendScalingFactor(double scaleFactor);
|
||||
|
||||
// Appearance
|
||||
void setRadius(double radius);
|
||||
void setCrossSectionVertexCount(size_t vertexCount);
|
||||
void setPipeColor(cvf::Color3f val) { m_pipeColor = val; }
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> createPipeSurface();
|
||||
cvf::ref<cvf::DrawableGeo> createCenterLine();
|
||||
|
||||
void pipeSurfaceTextureCoords(cvf::Vec2fArray* textureCoords, const std::vector<double>& segmentResults, const cvf::ScalarMapper* mapper) const;
|
||||
void centerlineTextureCoords(cvf::Vec2fArray* textureCoords, const std::vector<double>& segmentResults, const cvf::ScalarMapper* mapper) const;
|
||||
|
||||
private:
|
||||
void clearComputedData();
|
||||
void updateFilteredPipeCenterCoords();
|
||||
|
||||
static void computeCircle(double radius, size_t tesselationCount, const cvf::Vec3d& center, const cvf::Vec3d& orient1, const cvf::Vec3d& orient2, std::vector<cvf::Vec3d>* nodes);
|
||||
|
||||
static cvf::ref<cvf::DrawableGeo> generateLine(const cvf::Vec3dArray* coords);
|
||||
static cvf::ref<cvf::DrawableGeo> generateExtrudedCylinder(double radius, size_t crossSectionNodeCount,const cvf::Vec3dArray* cylinderCenterCoords);
|
||||
|
||||
static void computeExtrudedCoordsAndNormals(cvf::Vec3d intersectionCoord,
|
||||
cvf::Vec3d intersectionPlaneNormal,
|
||||
cvf::Vec3d segmentDirection,
|
||||
size_t crossSectionNodeCount,
|
||||
std::vector<cvf::Vec3d>* extrudedNodes,
|
||||
std::vector<cvf::Vec3f>* crossSectionVertices,
|
||||
std::vector<cvf::Vec3f>* cylinderSegmentNormals);
|
||||
private:
|
||||
cvf::cref<cvf::Vec3dArray> m_originalPipeCenterCoords;
|
||||
|
||||
// Based on m_originalPipeCenterCoords, produce list of coords where coords at the same location is removed
|
||||
// When a bend is detected, extra bend coordinates are inserted
|
||||
std::vector<cvf::Vec3d> m_filteredPipeCenterCoords;
|
||||
|
||||
// Map from generated cylinder segments to pipe result indices
|
||||
std::vector<size_t> m_filteredPipeSegmentToResult;
|
||||
|
||||
double m_radius;
|
||||
double m_minimumBendAngle;
|
||||
double m_bendScalingFactor;
|
||||
size_t m_crossSectionNodeCount;
|
||||
cvf::Color3f m_pipeColor;
|
||||
};
|
||||
128
ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp
Normal file
128
ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
#include "RivReservoirPartMgr.h"
|
||||
#include "RivGridPartMgr.h"
|
||||
#include "cvfStructGrid.h"
|
||||
#include "cvfModelBasicList.h"
|
||||
#include "RigReservoir.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPartMgr::clearAndSetReservoir(const RigReservoir* reservoir)
|
||||
{
|
||||
m_allGrids.clear();
|
||||
if (reservoir)
|
||||
{
|
||||
std::vector<const RigGridBase*> grids;
|
||||
reservoir->allGrids(&grids);
|
||||
for (size_t i = 0; i < grids.size() ; ++i)
|
||||
{
|
||||
m_allGrids.push_back(new RivGridPartMgr(grids[i], i) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPartMgr::setTransform(cvf::Transform* scaleTransform)
|
||||
{
|
||||
for (size_t i = 0; i < m_allGrids.size() ; ++i)
|
||||
{
|
||||
m_allGrids[i]->setTransform(scaleTransform);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPartMgr::setCellVisibility(size_t gridIndex, cvf::UByteArray* cellVisibilities)
|
||||
{
|
||||
CVF_ASSERT(gridIndex < m_allGrids.size());
|
||||
m_allGrids[gridIndex]->setCellVisibility(cellVisibilities);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::UByteArray> RivReservoirPartMgr::cellVisibility(size_t gridIdx)
|
||||
{
|
||||
CVF_ASSERT(gridIdx < m_allGrids.size());
|
||||
return m_allGrids[gridIdx]->cellVisibility();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPartMgr::updateCellColor(cvf::Color4f color)
|
||||
{
|
||||
for (size_t i = 0; i < m_allGrids.size() ; ++i)
|
||||
{
|
||||
m_allGrids[i]->updateCellColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot)
|
||||
{
|
||||
for (size_t i = 0; i < m_allGrids.size() ; ++i)
|
||||
{
|
||||
m_allGrids[i]->updateCellResultColor(timeStepIndex, cellResultSlot);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot)
|
||||
{
|
||||
for (size_t i = 0; i < m_allGrids.size() ; ++i)
|
||||
{
|
||||
m_allGrids[i]->updateCellEdgeResultColor(timeStepIndex, cellResultSlot, cellEdgeResultSlot);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPartMgr::appendPartsToModel(cvf::ModelBasicList* model)
|
||||
{
|
||||
for (size_t i = 0; i < m_allGrids.size() ; ++i)
|
||||
{
|
||||
m_allGrids[i]->appendPartsToModel(model);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPartMgr::appendPartsToModel(cvf::ModelBasicList* model, const std::vector<size_t>& gridIndices)
|
||||
{
|
||||
for (size_t i = 0; i < gridIndices.size() ; ++i)
|
||||
{
|
||||
if (gridIndices[i] < m_allGrids.size())
|
||||
{
|
||||
m_allGrids[gridIndices[i]]->appendPartsToModel(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
ApplicationCode/ModelVisualization/RivReservoirPartMgr.h
Normal file
65
ApplicationCode/ModelVisualization/RivReservoirPartMgr.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfArray.h"
|
||||
#include "cvfCollection.h"
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class ModelBasicList;
|
||||
class Transform;
|
||||
}
|
||||
|
||||
class RimResultSlot;
|
||||
class RimCellEdgeResultSlot;
|
||||
class RivGridPartMgr;
|
||||
class RigReservoir;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// RivReservoirGeometry: Class to handle visualization structures that embodies a complete reservoir at a specific
|
||||
/// time step.
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
class RivReservoirPartMgr: public cvf::Object
|
||||
{
|
||||
public:
|
||||
void clearAndSetReservoir(const RigReservoir* reservoir);
|
||||
void setTransform(cvf::Transform* scaleTransform);
|
||||
void setCellVisibility(size_t gridIndex, cvf::UByteArray* cellVisibilities );
|
||||
|
||||
//size_t gridCount() { return m_allGrids.size(); }
|
||||
cvf::ref<cvf::UByteArray>
|
||||
cellVisibility(size_t gridIdx);
|
||||
|
||||
void updateCellColor(cvf::Color4f color);
|
||||
void updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot);
|
||||
void updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot,
|
||||
RimCellEdgeResultSlot* cellEdgeResultSlot);
|
||||
|
||||
void appendPartsToModel(cvf::ModelBasicList* model, const std::vector<size_t>& gridIdxes);
|
||||
void appendPartsToModel(cvf::ModelBasicList* model);
|
||||
|
||||
private:
|
||||
|
||||
cvf::Collection<RivGridPartMgr> m_allGrids; // Main grid and all LGR's
|
||||
};
|
||||
116
ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp
Normal file
116
ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RivReservoirPipesPartMgr.h"
|
||||
#include "RimReservoirView.h"
|
||||
#include "RimWellCollection.h"
|
||||
#include "RivWellPipesPartMgr.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivReservoirPipesPartMgr::RivReservoirPipesPartMgr(RimReservoirView* reservoirView)
|
||||
{
|
||||
m_reservoirView = reservoirView;
|
||||
|
||||
m_scaleTransform = new cvf::Transform();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivReservoirPipesPartMgr::~RivReservoirPipesPartMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPipesPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex)
|
||||
{
|
||||
if (m_reservoirView->wellCollection()->wellPipeVisibility() == RimWellCollection::FORCE_ALL_OFF) return;
|
||||
|
||||
if (m_reservoirView->wellCollection()->wells.size() != m_wellPipesPartMgrs.size())
|
||||
{
|
||||
m_wellPipesPartMgrs.clear();
|
||||
m_wellPipesPartMgrs.clear();
|
||||
|
||||
for (size_t i = 0; i < m_reservoirView->wellCollection()->wells.size(); ++i)
|
||||
{
|
||||
RivWellPipesPartMgr * wppmgr = new RivWellPipesPartMgr(m_reservoirView, m_reservoirView->wellCollection()->wells[i]);
|
||||
m_wellPipesPartMgrs.push_back(wppmgr);
|
||||
wppmgr->setScaleTransform(m_scaleTransform.p());
|
||||
|
||||
RivWellHeadPartMgr* wellHeadMgr = new RivWellHeadPartMgr(m_reservoirView, m_reservoirView->wellCollection()->wells[i]);
|
||||
m_wellHeadPartMgrs.push_back(wellHeadMgr);
|
||||
wellHeadMgr->setScaleTransform(m_scaleTransform.p());
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
m_wellPipesPartMgrs[wIdx]->appendDynamicGeometryPartsToModel(model, frameIndex);
|
||||
m_wellHeadPartMgrs[wIdx]->appendDynamicGeometryPartsToModel(model, frameIndex);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPipesPartMgr::updatePipeResultColor(size_t frameIndex)
|
||||
{
|
||||
for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
m_wellPipesPartMgrs[wIdx]->updatePipeResultColor( frameIndex);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPipesPartMgr::setScaleTransform(cvf::Transform * scaleTransform)
|
||||
{
|
||||
m_scaleTransform = scaleTransform;
|
||||
|
||||
for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
m_wellPipesPartMgrs[wIdx]->setScaleTransform(scaleTransform);
|
||||
}
|
||||
|
||||
for (size_t wIdx = 0; wIdx != m_wellHeadPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
m_wellHeadPartMgrs[wIdx]->setScaleTransform(scaleTransform);
|
||||
}
|
||||
}
|
||||
|
||||
void RivReservoirPipesPartMgr::scheduleGeometryRegen()
|
||||
{
|
||||
for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
m_wellPipesPartMgrs[wIdx]->scheduleGeometryRegen();
|
||||
}
|
||||
|
||||
for (size_t wIdx = 0; wIdx != m_wellHeadPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
//m_wellHeadPartMgrs[wIdx]->scheduleGeometryRegen(scaleTransform);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimWellCollection.h"
|
||||
|
||||
|
||||
#include "cvfCollection.h"
|
||||
#include "RivWellHeadPartMgr.h"
|
||||
|
||||
class RimReservoirView;
|
||||
class RivWellPipesPartMgr;
|
||||
|
||||
class RivReservoirPipesPartMgr : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivReservoirPipesPartMgr(RimReservoirView* reservoirView);
|
||||
~RivReservoirPipesPartMgr();
|
||||
|
||||
void setScaleTransform(cvf::Transform * scaleTransform);
|
||||
void scheduleGeometryRegen();
|
||||
|
||||
void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex);
|
||||
void updatePipeResultColor(size_t frameIndex);
|
||||
|
||||
private:
|
||||
caf::PdmPointer<RimReservoirView> m_reservoirView;
|
||||
cvf::ref<cvf::Transform> m_scaleTransform;
|
||||
|
||||
cvf::Collection< RivWellPipesPartMgr > m_wellPipesPartMgrs;
|
||||
cvf::Collection< RivWellHeadPartMgr > m_wellHeadPartMgrs;
|
||||
};
|
||||
701
ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp
Normal file
701
ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp
Normal file
@@ -0,0 +1,701 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
#include "RivReservoirViewPartMgr.h"
|
||||
#include "RivGridPartMgr.h"
|
||||
#include "RimReservoirView.h"
|
||||
#include "RigReservoir.h"
|
||||
#include "RigGridBase.h"
|
||||
#include "RigReservoirCellResults.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivReservoirViewPartMgr::RivReservoirViewPartMgr(RimReservoirView * resv) :
|
||||
m_reservoirView(resv)
|
||||
{
|
||||
m_scaleTransform = new cvf::Transform();
|
||||
clearGeometryCache();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Clears the geometry cache for the given, and the dependent geometryTypes (from a visibility standpoint)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::scheduleGeometryRegen(ReservoirGeometryCacheType geometryType)
|
||||
{
|
||||
switch (geometryType)
|
||||
{
|
||||
case INACTIVE:
|
||||
clearGeometryCache(INACTIVE);
|
||||
clearGeometryCache(RANGE_FILTERED_INACTIVE);
|
||||
break;
|
||||
case RANGE_FILTERED_INACTIVE:
|
||||
clearGeometryCache(RANGE_FILTERED_INACTIVE);
|
||||
break;
|
||||
case ACTIVE:
|
||||
clearGeometryCache(ACTIVE);
|
||||
clearGeometryCache(ALL_WELL_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS);
|
||||
clearGeometryCache(RANGE_FILTERED);
|
||||
clearGeometryCache(RANGE_FILTERED_WELL_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(PROPERTY_FILTERED);
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
break;
|
||||
case ALL_WELL_CELLS:
|
||||
clearGeometryCache(ALL_WELL_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS);
|
||||
clearGeometryCache(RANGE_FILTERED);
|
||||
clearGeometryCache(RANGE_FILTERED_WELL_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
break;
|
||||
case VISIBLE_WELL_CELLS:
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(PROPERTY_FILTERED);
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
break;
|
||||
case VISIBLE_WELL_FENCE_CELLS:
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
break;
|
||||
case RANGE_FILTERED:
|
||||
clearGeometryCache(RANGE_FILTERED);
|
||||
clearGeometryCache(RANGE_FILTERED_INACTIVE);
|
||||
clearGeometryCache(RANGE_FILTERED_WELL_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(PROPERTY_FILTERED);
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
break;
|
||||
case RANGE_FILTERED_WELL_CELLS:
|
||||
clearGeometryCache(RANGE_FILTERED_WELL_CELLS);
|
||||
clearGeometryCache(RANGE_FILTERED);
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
break;
|
||||
case VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER:
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
break;
|
||||
case VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER:
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
break;
|
||||
case PROPERTY_FILTERED:
|
||||
clearGeometryCache(PROPERTY_FILTERED);
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
break;
|
||||
case PROPERTY_FILTERED_WELL_CELLS:
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geomType)
|
||||
{
|
||||
RigReservoir* reservoir = NULL;
|
||||
if (m_reservoirView != NULL && m_reservoirView->eclipseCase())
|
||||
{
|
||||
reservoir = m_reservoirView->eclipseCase()->reservoirData();
|
||||
}
|
||||
|
||||
if (geomType == PROPERTY_FILTERED)
|
||||
{
|
||||
for (size_t i = 0; i < m_propFilteredGeometryFramesNeedsRegen.size(); ++i)
|
||||
{
|
||||
m_propFilteredGeometryFramesNeedsRegen[i] = true;
|
||||
if (m_propFilteredGeometryFrames[i].notNull())
|
||||
{
|
||||
m_propFilteredGeometryFrames[i]->clearAndSetReservoir(reservoir);
|
||||
m_propFilteredGeometryFrames[i]->setTransform(m_scaleTransform.p());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (geomType == PROPERTY_FILTERED_WELL_CELLS)
|
||||
{
|
||||
for (size_t i = 0; i < m_propFilteredWellGeometryFramesNeedsRegen.size(); ++i)
|
||||
{
|
||||
m_propFilteredWellGeometryFramesNeedsRegen[i] = true;
|
||||
if (m_propFilteredWellGeometryFrames[i].notNull())
|
||||
{
|
||||
m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(reservoir);
|
||||
m_propFilteredWellGeometryFrames[i]->setTransform(m_scaleTransform.p());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_geometriesNeedsRegen[geomType] = true;
|
||||
m_geometries[geomType].clearAndSetReservoir(reservoir);
|
||||
m_geometries[geomType].setTransform(m_scaleTransform.p());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::clearGeometryCache()
|
||||
{
|
||||
clearGeometryCache(ACTIVE);
|
||||
clearGeometryCache(ALL_WELL_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS);
|
||||
clearGeometryCache(INACTIVE);
|
||||
clearGeometryCache(RANGE_FILTERED);
|
||||
clearGeometryCache(RANGE_FILTERED_WELL_CELLS);
|
||||
clearGeometryCache(RANGE_FILTERED_INACTIVE);
|
||||
clearGeometryCache(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
clearGeometryCache(PROPERTY_FILTERED);
|
||||
clearGeometryCache(PROPERTY_FILTERED_WELL_CELLS);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::appendStaticGeometryPartsToModel(cvf::ModelBasicList* model, ReservoirGeometryCacheType geometryType,
|
||||
const std::vector<size_t>& gridIndices)
|
||||
{
|
||||
if (m_geometriesNeedsRegen[geometryType])
|
||||
{
|
||||
createGeometry( geometryType);
|
||||
}
|
||||
m_geometries[geometryType].appendPartsToModel(model, gridIndices);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, ReservoirGeometryCacheType geometryType,
|
||||
size_t frameIndex, const std::vector<size_t>& gridIndices)
|
||||
{
|
||||
if (geometryType == PROPERTY_FILTERED)
|
||||
{
|
||||
if (frameIndex >= m_propFilteredGeometryFramesNeedsRegen.size() || m_propFilteredGeometryFramesNeedsRegen[frameIndex])
|
||||
{
|
||||
createPropertyFilteredGeometry(frameIndex);
|
||||
}
|
||||
m_propFilteredGeometryFrames[frameIndex]->appendPartsToModel(model, gridIndices);
|
||||
}
|
||||
else if (geometryType == PROPERTY_FILTERED_WELL_CELLS)
|
||||
{
|
||||
if (frameIndex >= m_propFilteredWellGeometryFramesNeedsRegen.size() || m_propFilteredWellGeometryFramesNeedsRegen[frameIndex])
|
||||
{
|
||||
createPropertyFilteredWellGeometry(frameIndex);
|
||||
}
|
||||
m_propFilteredWellGeometryFrames[frameIndex]->appendPartsToModel(model, gridIndices);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::createGeometry(ReservoirGeometryCacheType geometryType)
|
||||
{
|
||||
RigReservoir* res = m_reservoirView->eclipseCase()->reservoirData();
|
||||
m_geometries[geometryType].clearAndSetReservoir(res);
|
||||
m_geometries[geometryType].setTransform(m_scaleTransform.p());
|
||||
std::vector<RigGridBase*> grids;
|
||||
res->allGrids(&grids);
|
||||
|
||||
for (size_t i = 0; i < grids.size(); ++i)
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> cellVisibility = m_geometries[geometryType].cellVisibility(i);
|
||||
computeVisibility(cellVisibility.p(), geometryType, grids[i], i);
|
||||
|
||||
m_geometries[geometryType].setCellVisibility(i, cellVisibility.p());
|
||||
}
|
||||
|
||||
m_geometriesNeedsRegen[geometryType] = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, ReservoirGeometryCacheType geometryType, RigGridBase* grid, size_t gridIdx)
|
||||
{
|
||||
switch (geometryType)
|
||||
{
|
||||
case ACTIVE:
|
||||
computeNativeVisibility(cellVisibility, grid, false, false, true, m_reservoirView->showMainGrid() );
|
||||
break;
|
||||
case ALL_WELL_CELLS:
|
||||
computeAllWellCellsVisibility(cellVisibility, grid);
|
||||
break;
|
||||
case VISIBLE_WELL_CELLS:
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> allWellCellsVisibility;
|
||||
if (m_geometriesNeedsRegen[ALL_WELL_CELLS]) createGeometry(ALL_WELL_CELLS);
|
||||
|
||||
allWellCellsVisibility = m_geometries[ALL_WELL_CELLS].cellVisibility(gridIdx);
|
||||
|
||||
m_reservoirView->calculateVisibleWellCellsIncFence(cellVisibility, grid);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int cellIdx = 0; cellIdx < static_cast<int>(cellVisibility->size()); ++cellIdx)
|
||||
{
|
||||
(*cellVisibility)[cellIdx] = (*allWellCellsVisibility)[cellIdx] && (*cellVisibility)[cellIdx];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VISIBLE_WELL_FENCE_CELLS:
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> allWellCellsVisibility;
|
||||
if (m_geometriesNeedsRegen[ALL_WELL_CELLS]) createGeometry(ALL_WELL_CELLS);
|
||||
|
||||
allWellCellsVisibility = m_geometries[ALL_WELL_CELLS].cellVisibility(gridIdx);
|
||||
|
||||
m_reservoirView->calculateVisibleWellCellsIncFence(cellVisibility, grid);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int cellIdx = 0; cellIdx < static_cast<int>(cellVisibility->size()); ++cellIdx)
|
||||
{
|
||||
(*cellVisibility)[cellIdx] = !(*allWellCellsVisibility)[cellIdx] && (*cellVisibility)[cellIdx];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case INACTIVE:
|
||||
computeNativeVisibility(cellVisibility, grid, m_reservoirView->showInvalidCells(), true, false, m_reservoirView->showMainGrid());
|
||||
break;
|
||||
case RANGE_FILTERED:
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> nativeVisibility;
|
||||
if (m_geometriesNeedsRegen[ACTIVE]) createGeometry(ACTIVE);
|
||||
|
||||
nativeVisibility = m_geometries[ACTIVE].cellVisibility(gridIdx);
|
||||
computeRangeVisibility(cellVisibility, grid, nativeVisibility.p(), m_reservoirView->rangeFilterCollection());
|
||||
}
|
||||
break;
|
||||
case RANGE_FILTERED_INACTIVE:
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> nativeVisibility;
|
||||
if (m_geometriesNeedsRegen[INACTIVE]) createGeometry(INACTIVE);
|
||||
|
||||
nativeVisibility = m_geometries[INACTIVE].cellVisibility(gridIdx);
|
||||
computeRangeVisibility(cellVisibility, grid, nativeVisibility.p(), m_reservoirView->rangeFilterCollection());
|
||||
}
|
||||
break;
|
||||
case RANGE_FILTERED_WELL_CELLS:
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> nativeVisibility;
|
||||
if (m_geometriesNeedsRegen[ALL_WELL_CELLS]) createGeometry(ALL_WELL_CELLS);
|
||||
|
||||
nativeVisibility = m_geometries[ALL_WELL_CELLS].cellVisibility(gridIdx);
|
||||
computeRangeVisibility(cellVisibility, grid, nativeVisibility.p(), m_reservoirView->rangeFilterCollection());
|
||||
}
|
||||
break;
|
||||
case VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER:
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> visibleWellCells;
|
||||
cvf::ref<cvf::UByteArray> rangeFilteredWellCells;
|
||||
|
||||
if (m_geometriesNeedsRegen[VISIBLE_WELL_CELLS]) createGeometry(VISIBLE_WELL_CELLS);
|
||||
if (m_geometriesNeedsRegen[RANGE_FILTERED_WELL_CELLS]) createGeometry(RANGE_FILTERED_WELL_CELLS);
|
||||
|
||||
visibleWellCells = m_geometries[VISIBLE_WELL_CELLS].cellVisibility(gridIdx);
|
||||
rangeFilteredWellCells = m_geometries[RANGE_FILTERED_WELL_CELLS].cellVisibility(gridIdx);
|
||||
|
||||
cellVisibility->resize(visibleWellCells->size());
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int cellIdx = 0; cellIdx < static_cast<int>(cellVisibility->size()); ++cellIdx)
|
||||
{
|
||||
(*cellVisibility)[cellIdx] = (*visibleWellCells)[cellIdx] && !(*rangeFilteredWellCells)[cellIdx];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER:
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> visibleWellCells;
|
||||
cvf::ref<cvf::UByteArray> rangeFilteredWellCells;
|
||||
|
||||
if (m_geometriesNeedsRegen[VISIBLE_WELL_FENCE_CELLS]) createGeometry(VISIBLE_WELL_FENCE_CELLS);
|
||||
if (m_geometriesNeedsRegen[RANGE_FILTERED]) createGeometry(RANGE_FILTERED);
|
||||
|
||||
visibleWellCells = m_geometries[VISIBLE_WELL_FENCE_CELLS].cellVisibility(gridIdx);
|
||||
rangeFilteredWellCells = m_geometries[RANGE_FILTERED].cellVisibility(gridIdx);
|
||||
|
||||
cellVisibility->resize(visibleWellCells->size());
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int cellIdx = 0; cellIdx < static_cast<int>(cellVisibility->size()); ++cellIdx)
|
||||
{
|
||||
(*cellVisibility)[cellIdx] = (*visibleWellCells)[cellIdx] && !(*rangeFilteredWellCells)[cellIdx];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CVF_ASSERT(false); // Call special function for property filtered stuff
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::createPropertyFilteredGeometry(size_t frameIndex)
|
||||
{
|
||||
RigReservoir* res = m_reservoirView->eclipseCase()->reservoirData();
|
||||
|
||||
if ( frameIndex >= m_propFilteredGeometryFrames.size())
|
||||
{
|
||||
m_propFilteredGeometryFrames.resize(frameIndex + 1);
|
||||
m_propFilteredGeometryFramesNeedsRegen.resize(frameIndex + 1, true);
|
||||
}
|
||||
if ( m_propFilteredGeometryFrames[frameIndex].isNull()) m_propFilteredGeometryFrames[frameIndex] = new RivReservoirPartMgr;
|
||||
m_propFilteredGeometryFrames[frameIndex]->clearAndSetReservoir(res);
|
||||
m_propFilteredGeometryFrames[frameIndex]->setTransform(m_scaleTransform.p());
|
||||
std::vector<RigGridBase*> grids;
|
||||
res->allGrids(&grids);
|
||||
|
||||
bool hasActiveRangeFilters = m_reservoirView->rangeFilterCollection()->hasActiveFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells();
|
||||
|
||||
for (size_t i = 0; i < grids.size(); ++i)
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> cellVisibility = m_propFilteredGeometryFrames[frameIndex]->cellVisibility(i);
|
||||
cvf::ref<cvf::UByteArray> rangeVisibility;
|
||||
cvf::ref<cvf::UByteArray> fenceVisibility;
|
||||
|
||||
if (m_geometriesNeedsRegen[RANGE_FILTERED]) createGeometry(RANGE_FILTERED);
|
||||
if (m_geometriesNeedsRegen[VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER]) createGeometry(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
|
||||
rangeVisibility = m_geometries[RANGE_FILTERED].cellVisibility(i);
|
||||
fenceVisibility = m_geometries[VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility(i);
|
||||
|
||||
cellVisibility->resize(rangeVisibility->size());
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int cellIdx = 0; cellIdx < static_cast<int>(cellVisibility->size()); ++cellIdx)
|
||||
{
|
||||
(*cellVisibility)[cellIdx] = (!hasActiveRangeFilters && !grids[i]->cell(cellIdx).isWellCell()) || (*rangeVisibility)[cellIdx] || (*fenceVisibility)[cellIdx];
|
||||
}
|
||||
computePropertyVisibility(cellVisibility.p(), grids[i], frameIndex, cellVisibility.p(), m_reservoirView->propertyFilterCollection());
|
||||
|
||||
m_propFilteredGeometryFrames[frameIndex]->setCellVisibility(i, cellVisibility.p());
|
||||
}
|
||||
|
||||
m_propFilteredGeometryFramesNeedsRegen[frameIndex] = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameIndex)
|
||||
{
|
||||
RigReservoir* res = m_reservoirView->eclipseCase()->reservoirData();
|
||||
|
||||
if ( frameIndex >= m_propFilteredWellGeometryFrames.size())
|
||||
{
|
||||
m_propFilteredWellGeometryFrames.resize(frameIndex + 1);
|
||||
m_propFilteredWellGeometryFramesNeedsRegen.resize(frameIndex + 1, true);
|
||||
}
|
||||
|
||||
if ( m_propFilteredWellGeometryFrames[frameIndex].isNull()) m_propFilteredWellGeometryFrames[frameIndex] = new RivReservoirPartMgr;
|
||||
|
||||
m_propFilteredWellGeometryFrames[frameIndex]->clearAndSetReservoir(res);
|
||||
m_propFilteredWellGeometryFrames[frameIndex]->setTransform(m_scaleTransform.p());
|
||||
|
||||
std::vector<RigGridBase*> grids;
|
||||
res->allGrids(&grids);
|
||||
|
||||
bool hasActiveRangeFilters = m_reservoirView->rangeFilterCollection()->hasActiveFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells();
|
||||
|
||||
for (size_t i = 0; i < grids.size(); ++i)
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> cellVisibility = m_propFilteredWellGeometryFrames[frameIndex]->cellVisibility(i);
|
||||
cvf::ref<cvf::UByteArray> rangeVisibility;
|
||||
cvf::ref<cvf::UByteArray> wellCellsOutsideVisibility;
|
||||
|
||||
if (m_geometriesNeedsRegen[RANGE_FILTERED_WELL_CELLS]) createGeometry(RANGE_FILTERED_WELL_CELLS);
|
||||
rangeVisibility = m_geometries[RANGE_FILTERED_WELL_CELLS].cellVisibility(i);
|
||||
|
||||
if (m_geometriesNeedsRegen[VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER]) createGeometry(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER);
|
||||
wellCellsOutsideVisibility = m_geometries[VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility(i);
|
||||
|
||||
cellVisibility->resize(rangeVisibility->size());
|
||||
#pragma omp parallel for
|
||||
for (int cellIdx = 0; cellIdx < static_cast<int>(cellVisibility->size()); ++cellIdx)
|
||||
{
|
||||
(*cellVisibility)[cellIdx] = (!hasActiveRangeFilters && grids[i]->cell(cellIdx).isWellCell()) || (*rangeVisibility)[cellIdx] || (*wellCellsOutsideVisibility)[cellIdx];
|
||||
}
|
||||
computePropertyVisibility(cellVisibility.p(), grids[i], frameIndex, cellVisibility.p(), m_reservoirView->propertyFilterCollection());
|
||||
m_propFilteredWellGeometryFrames[frameIndex]->setCellVisibility(i, cellVisibility.p());
|
||||
}
|
||||
|
||||
m_propFilteredWellGeometryFramesNeedsRegen[frameIndex] = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Evaluate visibility based on cell state
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid,
|
||||
bool invalidCellsIsVisible,
|
||||
bool inactiveCellsIsVisible,
|
||||
bool activeCellsIsVisible,
|
||||
bool mainGridIsVisible)
|
||||
{
|
||||
CVF_ASSERT(cellVisibility != NULL);
|
||||
CVF_ASSERT(grid != NULL);
|
||||
cellVisibility->resize(grid->cellCount());
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int cellIndex = 0; cellIndex < static_cast<int>(grid->cellCount()); cellIndex++)
|
||||
{
|
||||
const RigCell& cell = grid->cell(cellIndex);
|
||||
|
||||
if ( !invalidCellsIsVisible && cell.isInvalid()
|
||||
|| !inactiveCellsIsVisible && !cell.active()
|
||||
|| !activeCellsIsVisible && cell.active()
|
||||
|| mainGridIsVisible && (cell.subGrid() != NULL)
|
||||
|| cell.isWellCell()
|
||||
)
|
||||
{
|
||||
(*cellVisibility)[cellIndex] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*cellVisibility)[cellIndex] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Evaluate Well cell visibility based on cell state
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::computeAllWellCellsVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid )
|
||||
{
|
||||
CVF_ASSERT(cellVisibility != NULL);
|
||||
CVF_ASSERT(grid != NULL);
|
||||
cellVisibility->resize(grid->cellCount());
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int cellIndex = 0; cellIndex < static_cast<int>(grid->cellCount()); cellIndex++)
|
||||
{
|
||||
const RigCell& cell = grid->cell(cellIndex);
|
||||
|
||||
if ( cell.isWellCell() )
|
||||
{
|
||||
(*cellVisibility)[cellIndex] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*cellVisibility)[cellIndex] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::computeRangeVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid,
|
||||
const cvf::UByteArray* nativeVisibility, const RimCellRangeFilterCollection* rangeFilterColl)
|
||||
{
|
||||
CVF_ASSERT(cellVisibility != NULL);
|
||||
CVF_ASSERT(nativeVisibility != NULL);
|
||||
CVF_ASSERT(rangeFilterColl != NULL);
|
||||
|
||||
CVF_ASSERT(grid != NULL);
|
||||
CVF_ASSERT(nativeVisibility->size() == grid->cellCount());
|
||||
|
||||
|
||||
if (rangeFilterColl->hasActiveFilters())
|
||||
{
|
||||
if (cellVisibility != nativeVisibility) (*cellVisibility) = (*nativeVisibility);
|
||||
|
||||
// Build range filter for current grid
|
||||
cvf::CellRangeFilter mainGridCellRangeFilter;
|
||||
rangeFilterColl->compoundCellRangeFilter(&mainGridCellRangeFilter);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int cellIndex = 0; cellIndex < static_cast<int>(grid->cellCount()); cellIndex++)
|
||||
{
|
||||
if ( (*nativeVisibility)[cellIndex] )
|
||||
{
|
||||
const RigCell& cell = grid->cell(cellIndex);
|
||||
size_t mainGridCellIndex = cell.mainGridCellIndex();
|
||||
size_t mainGridI;
|
||||
size_t mainGridJ;
|
||||
size_t mainGridK;
|
||||
|
||||
grid->mainGrid()->ijkFromCellIndex(mainGridCellIndex, &mainGridI, &mainGridJ, &mainGridK);
|
||||
(*cellVisibility)[cellIndex] = !mainGridCellRangeFilter.isCellRejected(mainGridI, mainGridJ, mainGridK);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cellVisibility->resize(grid->cellCount());
|
||||
cellVisibility->setAll(false);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid, size_t timeStepIndex,
|
||||
const cvf::UByteArray* rangeFilterVisibility, RimCellPropertyFilterCollection* propFilterColl)
|
||||
{
|
||||
CVF_ASSERT(cellVisibility != NULL);
|
||||
CVF_ASSERT(rangeFilterVisibility != NULL);
|
||||
CVF_ASSERT(propFilterColl != NULL);
|
||||
|
||||
CVF_ASSERT(grid->cellCount() > 0);
|
||||
CVF_ASSERT(rangeFilterVisibility->size() == grid->cellCount());
|
||||
|
||||
// Copy if not equal
|
||||
if (cellVisibility != rangeFilterVisibility ) (*cellVisibility) = *rangeFilterVisibility;
|
||||
|
||||
if (propFilterColl->hasActiveFilters())
|
||||
{
|
||||
std::list< caf::PdmPointer< RimCellPropertyFilter > >::const_iterator pfIt;
|
||||
for (pfIt = propFilterColl->propertyFilters().begin(); pfIt != propFilterColl->propertyFilters().end(); ++pfIt)
|
||||
{
|
||||
if ((*pfIt)->active()&& (*pfIt)->resultDefinition->hasResult())
|
||||
{
|
||||
const double lowerBound = (*pfIt)->lowerBound();
|
||||
const double upperBound = (*pfIt)->upperBound();
|
||||
|
||||
const std::vector< std::vector<double> >& scalarResultTimeSteps = grid->mainGrid()->results()->cellScalarResults((*pfIt)->resultDefinition->gridScalarIndex());
|
||||
const std::vector< double >* scalarResult = NULL;
|
||||
|
||||
if ((*pfIt)->resultDefinition()->hasDynamicResult())
|
||||
{
|
||||
scalarResult = &(scalarResultTimeSteps[timeStepIndex]);
|
||||
}
|
||||
else if ((*pfIt)->resultDefinition()->hasStaticResult())
|
||||
{
|
||||
scalarResult = &(scalarResultTimeSteps[0]);
|
||||
}
|
||||
|
||||
const RimCellFilter::FilterModeType filterType = (*pfIt)->filterMode();
|
||||
|
||||
#pragma omp parallel for schedule(dynamic)
|
||||
for (int cellIndex = 0; cellIndex < static_cast<int>(grid->cellCount()); cellIndex++)
|
||||
{
|
||||
if ( (*cellVisibility)[cellIndex] )
|
||||
{
|
||||
size_t resultIndex = grid->cell(cellIndex).globalActiveIndex();
|
||||
double value = HUGE_VAL;
|
||||
if (resultIndex != cvf::UNDEFINED_SIZE_T) value = (*scalarResult)[resultIndex];
|
||||
|
||||
if (lowerBound <= value && value <= upperBound)
|
||||
{
|
||||
if (filterType == RimCellFilter::EXCLUDE)
|
||||
{
|
||||
(*cellVisibility)[cellIndex] = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filterType == RimCellFilter::INCLUDE)
|
||||
{
|
||||
(*cellVisibility)[cellIndex] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::updateCellColor(ReservoirGeometryCacheType geometryType, size_t timeStepIndex, cvf::Color4f color)
|
||||
{
|
||||
if (geometryType == PROPERTY_FILTERED)
|
||||
{
|
||||
m_propFilteredGeometryFrames[timeStepIndex]->updateCellColor(color );
|
||||
}
|
||||
else if (geometryType == PROPERTY_FILTERED_WELL_CELLS)
|
||||
{
|
||||
m_propFilteredWellGeometryFrames[timeStepIndex]->updateCellColor(color );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_geometries[geometryType].updateCellColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::updateCellColor(ReservoirGeometryCacheType geometryType, cvf::Color4f color)
|
||||
{
|
||||
//CVF_ASSERT(geometryType != PROPERTY_FILTERED);
|
||||
//CVF_ASSERT(geometryType != PROPERTY_FILTERED_WELL_CELLS);
|
||||
|
||||
updateCellColor(geometryType, 0 , color);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::updateCellResultColor(ReservoirGeometryCacheType geometryType, size_t timeStepIndex, RimResultSlot* cellResultSlot)
|
||||
{
|
||||
if (geometryType == PROPERTY_FILTERED)
|
||||
{
|
||||
m_propFilteredGeometryFrames[timeStepIndex]->updateCellResultColor(timeStepIndex, cellResultSlot);
|
||||
}
|
||||
else if (geometryType == PROPERTY_FILTERED_WELL_CELLS)
|
||||
{
|
||||
m_propFilteredWellGeometryFrames[timeStepIndex]->updateCellResultColor(timeStepIndex, cellResultSlot);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_geometries[geometryType].updateCellResultColor(timeStepIndex, cellResultSlot);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirViewPartMgr::updateCellEdgeResultColor(ReservoirGeometryCacheType geometryType, size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot)
|
||||
{
|
||||
if (geometryType == PROPERTY_FILTERED)
|
||||
{
|
||||
m_propFilteredGeometryFrames[timeStepIndex]->updateCellEdgeResultColor( timeStepIndex, cellResultSlot, cellEdgeResultSlot );
|
||||
}
|
||||
else if (geometryType == PROPERTY_FILTERED_WELL_CELLS)
|
||||
{
|
||||
m_propFilteredWellGeometryFrames[timeStepIndex]->updateCellEdgeResultColor( timeStepIndex, cellResultSlot, cellEdgeResultSlot );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_geometries[geometryType].updateCellEdgeResultColor(timeStepIndex, cellResultSlot, cellEdgeResultSlot );
|
||||
}
|
||||
}
|
||||
101
ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h
Normal file
101
ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include "RivReservoirPartMgr.h"
|
||||
#include "cvfTransform.h"
|
||||
#include "RimReservoirView.h"
|
||||
#include "cafFixedArray.h"
|
||||
#include "cvfArray.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
class RimReservoirView;
|
||||
class RigGridBase;
|
||||
class RimCellRangeFilterCollection;
|
||||
class RimCellPropertyFilterCollection;
|
||||
|
||||
class RivReservoirViewPartMgr: public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivReservoirViewPartMgr(RimReservoirView * resv);
|
||||
|
||||
cvf::Transform* scaleTransform() { return m_scaleTransform.p();}
|
||||
void setScaleTransform(cvf::Mat4d scale) { m_scaleTransform->setWorldTransform(scale);}
|
||||
|
||||
enum ReservoirGeometryCacheType
|
||||
{
|
||||
ACTIVE,
|
||||
ALL_WELL_CELLS,
|
||||
VISIBLE_WELL_CELLS,
|
||||
VISIBLE_WELL_FENCE_CELLS,
|
||||
INACTIVE,
|
||||
RANGE_FILTERED,
|
||||
RANGE_FILTERED_INACTIVE,
|
||||
RANGE_FILTERED_WELL_CELLS,
|
||||
VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER,
|
||||
VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER,
|
||||
PROPERTY_FILTERED,
|
||||
PROPERTY_FILTERED_WELL_CELLS // Includes RANGE_FILTERED_WELL_CELLS and VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER and VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER
|
||||
};
|
||||
|
||||
void clearGeometryCache();
|
||||
void scheduleGeometryRegen(ReservoirGeometryCacheType geometryType);
|
||||
|
||||
void appendStaticGeometryPartsToModel (cvf::ModelBasicList* model, ReservoirGeometryCacheType geometryType, const std::vector<size_t>& gridIndices);
|
||||
void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, ReservoirGeometryCacheType geometryType, size_t frameIndex, const std::vector<size_t>& gridIndices);
|
||||
|
||||
void updateCellColor (ReservoirGeometryCacheType geometryType, cvf::Color4f color);
|
||||
void updateCellColor (ReservoirGeometryCacheType geometryType, size_t timeStepIndex,
|
||||
cvf::Color4f color);
|
||||
void updateCellResultColor (ReservoirGeometryCacheType geometryType, size_t timeStepIndex,
|
||||
RimResultSlot* cellResultSlot);
|
||||
void updateCellEdgeResultColor(ReservoirGeometryCacheType geometryType, size_t timeStepIndex,
|
||||
RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot);
|
||||
|
||||
private:
|
||||
void createGeometry(ReservoirGeometryCacheType geometryType);
|
||||
void computeVisibility(cvf::UByteArray* cellVisibility, ReservoirGeometryCacheType geometryType, RigGridBase* grid, size_t gridIdx);
|
||||
|
||||
void createPropertyFilteredGeometry(size_t frameIndex);
|
||||
void createPropertyFilteredWellGeometry(size_t frameIndex);
|
||||
|
||||
void clearGeometryCache(ReservoirGeometryCacheType geomType);
|
||||
|
||||
|
||||
static void computeNativeVisibility (cvf::UByteArray* cellVisibility, const RigGridBase* grid, bool invalidCellsIsVisible, bool inactiveCellsIsVisible, bool activeCellsIsVisible, bool mainGridIsVisible);
|
||||
static void computeRangeVisibility (cvf::UByteArray* cellVisibility, const RigGridBase* grid, const cvf::UByteArray* nativeVisibility, const RimCellRangeFilterCollection* rangeFilterColl);
|
||||
static void computePropertyVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid, size_t timeStepIndex, const cvf::UByteArray* rangeFilterVisibility, RimCellPropertyFilterCollection* propFilterColl);
|
||||
static void computeAllWellCellsVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid );
|
||||
|
||||
private:
|
||||
|
||||
caf::FixedArray<RivReservoirPartMgr, PROPERTY_FILTERED> m_geometries;
|
||||
caf::FixedArray<bool, PROPERTY_FILTERED> m_geometriesNeedsRegen;
|
||||
|
||||
cvf::Collection<RivReservoirPartMgr> m_propFilteredGeometryFrames;
|
||||
std::vector<uchar> m_propFilteredGeometryFramesNeedsRegen;
|
||||
|
||||
cvf::Collection<RivReservoirPartMgr> m_propFilteredWellGeometryFrames;
|
||||
std::vector<uchar> m_propFilteredWellGeometryFramesNeedsRegen;
|
||||
|
||||
|
||||
|
||||
cvf::ref<cvf::Transform> m_scaleTransform;
|
||||
caf::PdmPointer<RimReservoirView> m_reservoirView;
|
||||
|
||||
};
|
||||
280
ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp
Normal file
280
ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp
Normal file
@@ -0,0 +1,280 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#include "cvfLibCore.h"
|
||||
|
||||
#include "cvfModelBasicList.h"
|
||||
#include "cvfTransform.h"
|
||||
#include "cvfPart.h"
|
||||
#include "cvfArrowGenerator.h"
|
||||
#include "cafEffectGenerator.h"
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfPrimitiveSetIndexedUShort.h"
|
||||
#include "cvfGeometryBuilderFaceList.h"
|
||||
#include "cvfDrawableText.h"
|
||||
#include "cvfFixedAtlasFont.h"
|
||||
#include "cvfqtUtils.h"
|
||||
|
||||
#include "RimReservoirView.h"
|
||||
|
||||
#include "RigReservoir.h"
|
||||
#include "RigCell.h"
|
||||
|
||||
#include "RivPipeGeometryGenerator.h"
|
||||
#include "RivWellHeadPartMgr.h"
|
||||
#include "RivWellPipesPartMgr.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivWellHeadPartMgr::RivWellHeadPartMgr(RimReservoirView* reservoirView, RimWell* well)
|
||||
{
|
||||
m_rimReservoirView = reservoirView;
|
||||
m_rimWell = well;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivWellHeadPartMgr::~RivWellHeadPartMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex)
|
||||
{
|
||||
m_wellHeadParts.clear();
|
||||
|
||||
if (m_rimReservoirView.isNull()) return;
|
||||
|
||||
RigReservoir* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData();
|
||||
|
||||
RimWell* well = m_rimWell;
|
||||
|
||||
RigWellResults* wellResults = well->wellResults();
|
||||
|
||||
if (wellResults->m_staticWellCells.m_wellResultBranches.size() == 0)
|
||||
{
|
||||
wellResults->computeStaticWellCellPath();
|
||||
}
|
||||
if (wellResults->m_staticWellCells.m_wellResultBranches.size() == 0) return;
|
||||
|
||||
if (!wellResults->hasWellResult(frameIndex)) return;
|
||||
|
||||
const RigWellResultFrame& wellResultFrame = wellResults->wellResultFrame(frameIndex);
|
||||
|
||||
const RigCell& whCell = rigReservoir->cellFromWellResultCell(wellResultFrame.m_wellHead);
|
||||
|
||||
double characteristicCellSize = rigReservoir->mainGrid()->characteristicCellSize();
|
||||
|
||||
// Match this position with pipe start position in RivWellPipesPartMgr::calculateWellPipeCenterline()
|
||||
cvf::Vec3d whStartPos = whCell.faceCenter(cvf::StructGridInterface::NEG_K);
|
||||
whStartPos -= rigReservoir->mainGrid()->displayModelOffset();
|
||||
whStartPos.transformPoint(m_scaleTransform->worldTransform());
|
||||
|
||||
cvf::Vec3d whEndPos = whStartPos;
|
||||
whEndPos.z() += characteristicCellSize * m_rimReservoirView->wellCollection()->wellHeadScaleFactor();
|
||||
|
||||
cvf::Vec3d arrowPosition = whEndPos;
|
||||
arrowPosition.z() += 2.0;
|
||||
|
||||
// Well head pipe geometry
|
||||
{
|
||||
cvf::ref<cvf::Vec3dArray> wellHeadPipeCoords = new cvf::Vec3dArray;
|
||||
wellHeadPipeCoords->resize(2);
|
||||
wellHeadPipeCoords->set(0, whStartPos);
|
||||
wellHeadPipeCoords->set(1, whEndPos);
|
||||
|
||||
cvf::ref<RivPipeGeometryGenerator> pipeGeomGenerator = new RivPipeGeometryGenerator;
|
||||
pipeGeomGenerator->setPipeCenterCoords(wellHeadPipeCoords.p());
|
||||
pipeGeomGenerator->setPipeColor(well->wellPipeColor());
|
||||
pipeGeomGenerator->setCrossSectionVertexCount(12);
|
||||
|
||||
double pipeRadius = m_rimReservoirView->wellCollection()->pipeRadiusScaleFactor() * m_rimWell->pipeRadiusScaleFactor() * characteristicCellSize;
|
||||
pipeGeomGenerator->setRadius(pipeRadius);
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> pipeSurface = pipeGeomGenerator->createPipeSurface();
|
||||
cvf::ref<cvf::DrawableGeo> centerLineDrawable = pipeGeomGenerator->createCenterLine();
|
||||
|
||||
if (pipeSurface.notNull())
|
||||
{
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setDrawable(pipeSurface.p());
|
||||
|
||||
caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(well->wellPipeColor()), true);
|
||||
cvf::ref<cvf::Effect> eff = surfaceGen.generateEffect();
|
||||
|
||||
part->setEffect(eff.p());
|
||||
|
||||
m_wellHeadParts.push_back(part.p());
|
||||
}
|
||||
|
||||
if (centerLineDrawable.notNull())
|
||||
{
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setDrawable(centerLineDrawable.p());
|
||||
|
||||
caf::MeshEffectGenerator meshGen(well->wellPipeColor());
|
||||
cvf::ref<cvf::Effect> eff = meshGen.generateEffect();
|
||||
|
||||
part->setEffect(eff.p());
|
||||
|
||||
m_wellHeadParts.push_back(part.p());
|
||||
}
|
||||
}
|
||||
|
||||
double arrowLength = characteristicCellSize * m_rimReservoirView->wellCollection()->wellHeadScaleFactor();
|
||||
cvf::Vec3d textPosition = arrowPosition;
|
||||
textPosition.z() += 1.2 * arrowLength;
|
||||
|
||||
cvf::Mat4f matr;
|
||||
if (wellResultFrame.m_productionType != RigWellResultFrame::PRODUCER)
|
||||
{
|
||||
matr = cvf::Mat4f::fromRotation(cvf::Vec3f(1.0f, 0.0f, 0.0f), cvf::Math::toRadians(180.0f));
|
||||
}
|
||||
|
||||
double ijScaleFactor = arrowLength / 6;
|
||||
matr(0, 0) *= ijScaleFactor;
|
||||
matr(1, 1) *= ijScaleFactor;
|
||||
matr(2, 2) *= arrowLength;
|
||||
|
||||
if (wellResultFrame.m_productionType != RigWellResultFrame::PRODUCER)
|
||||
{
|
||||
arrowPosition.z() += arrowLength;
|
||||
}
|
||||
|
||||
matr.setTranslation(cvf::Vec3f(arrowPosition));
|
||||
|
||||
cvf::GeometryBuilderFaceList builder;
|
||||
cvf::ArrowGenerator gen;
|
||||
gen.setShaftRelativeRadius(0.5f);
|
||||
gen.setHeadRelativeRadius(1.0f);
|
||||
gen.setHeadRelativeLength(0.4f);
|
||||
gen.generate(&builder);
|
||||
|
||||
cvf::ref<cvf::Vec3fArray> vertices = builder.vertices();
|
||||
cvf::ref<cvf::UIntArray> faceList = builder.faceList();
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < vertices->size(); i++)
|
||||
{
|
||||
cvf::Vec3f v = vertices->get(i);
|
||||
v.transformPoint(matr);
|
||||
vertices->set(i, v);
|
||||
}
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo1 = new cvf::DrawableGeo;
|
||||
geo1->setVertexArray(vertices.p());
|
||||
geo1->setFromFaceList(*faceList);
|
||||
geo1->computeNormals();
|
||||
|
||||
|
||||
{
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setDrawable(geo1.p());
|
||||
|
||||
cvf::Color4f headColor(cvf::Color3::GRAY);
|
||||
if (wellResultFrame.m_isOpen)
|
||||
{
|
||||
if (wellResultFrame.m_productionType == RigWellResultFrame::PRODUCER)
|
||||
{
|
||||
headColor = cvf::Color4f(cvf::Color3::GREEN);
|
||||
}
|
||||
else if (wellResultFrame.m_productionType == RigWellResultFrame::OIL_INJECTOR)
|
||||
{
|
||||
headColor = cvf::Color4f(cvf::Color3::ORANGE);
|
||||
}
|
||||
else if (wellResultFrame.m_productionType == RigWellResultFrame::GAS_INJECTOR)
|
||||
{
|
||||
headColor = cvf::Color4f(cvf::Color3::RED);
|
||||
}
|
||||
else if (wellResultFrame.m_productionType == RigWellResultFrame::WATER_INJECTOR)
|
||||
{
|
||||
headColor = cvf::Color4f(cvf::Color3::BLUE);
|
||||
}
|
||||
}
|
||||
|
||||
caf::SurfaceEffectGenerator surfaceGen(headColor, true);
|
||||
cvf::ref<cvf::Effect> eff = surfaceGen.generateEffect();
|
||||
|
||||
part->setEffect(eff.p());
|
||||
m_wellHeadParts.push_back(part.p());
|
||||
}
|
||||
|
||||
if (m_rimReservoirView->wellCollection()->showWellLabel() && well->showWellLabel())
|
||||
{
|
||||
cvf::ref<cvf::DrawableText> drawableText = new cvf::DrawableText;
|
||||
drawableText->setFont(new cvf::FixedAtlasFont(cvf::FixedAtlasFont::LARGE));
|
||||
drawableText->setCheckPosVisible(false);
|
||||
drawableText->setDrawBorder(false);
|
||||
drawableText->setDrawBackground(false);
|
||||
drawableText->setVerticalAlignment(cvf::TextDrawer::CENTER);
|
||||
drawableText->setTextColor(cvf::Color3::WHITE);
|
||||
|
||||
cvf::String cvfString = cvfqt::Utils::fromQString(well->name());
|
||||
|
||||
cvf::Vec3f textCoord(textPosition);
|
||||
drawableText->addText(cvfString, textCoord);
|
||||
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setDrawable(drawableText.p());
|
||||
|
||||
cvf::ref<cvf::Effect> eff = new cvf::Effect;
|
||||
|
||||
part->setEffect(eff.p());
|
||||
part->setPriority(1);
|
||||
|
||||
m_wellHeadParts.push_back(part.p());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivWellHeadPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex)
|
||||
{
|
||||
if (m_rimReservoirView.isNull()) return;
|
||||
if (m_rimWell.isNull()) return;
|
||||
|
||||
if ( m_rimReservoirView->wellCollection()->wellPipeVisibility() != RimWellCollection::FORCE_ALL_ON
|
||||
&& m_rimWell->showWellPipes() == false) return;
|
||||
|
||||
if (m_rimReservoirView->wellCollection()->showWellHead() == false) return;
|
||||
|
||||
if ( m_rimWell->wellResults()->firstResultTimeStep() == cvf::UNDEFINED_SIZE_T
|
||||
|| frameIndex < m_rimWell->wellResults()->firstResultTimeStep() )
|
||||
return;
|
||||
|
||||
buildWellHeadParts(frameIndex);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < m_wellHeadParts.size(); i++)
|
||||
{
|
||||
model->addPart(m_wellHeadParts.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
51
ApplicationCode/ModelVisualization/RivWellHeadPartMgr.h
Normal file
51
ApplicationCode/ModelVisualization/RivWellHeadPartMgr.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class Part;
|
||||
class ModelBasicList;
|
||||
class Transform;
|
||||
}
|
||||
|
||||
class RimWell;
|
||||
|
||||
class RivWellHeadPartMgr : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivWellHeadPartMgr(RimReservoirView* reservoirView, RimWell* well);
|
||||
~RivWellHeadPartMgr();
|
||||
|
||||
void setScaleTransform(cvf::Transform * scaleTransform) { m_scaleTransform = scaleTransform;}
|
||||
|
||||
void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex);
|
||||
|
||||
|
||||
private:
|
||||
void buildWellHeadParts(size_t frameIndex);
|
||||
|
||||
|
||||
private:
|
||||
caf::PdmPointer<RimReservoirView> m_rimReservoirView;
|
||||
caf::PdmPointer<RimWell> m_rimWell;
|
||||
|
||||
cvf::ref<cvf::Transform> m_scaleTransform;
|
||||
cvf::Collection< cvf::Part > m_wellHeadParts;
|
||||
};
|
||||
468
ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp
Normal file
468
ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp
Normal file
@@ -0,0 +1,468 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "cvfLibCore.h"
|
||||
|
||||
#include "RimReservoir.h"
|
||||
#include "RigReservoir.h"
|
||||
#include "RivWellPipesPartMgr.h"
|
||||
#include "RigCell.h"
|
||||
#include "RivPipeGeometryGenerator.h"
|
||||
#include "cvfModelBasicList.h"
|
||||
#include "cvfTransform.h"
|
||||
#include "cvfPart.h"
|
||||
#include "cvfScalarMapperDiscreteLinear.h"
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfRay.h"
|
||||
#include "cafEffectGenerator.h"
|
||||
#include "RimReservoirView.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivWellPipesPartMgr::RivWellPipesPartMgr(RimReservoirView* reservoirView, RimWell* well)
|
||||
{
|
||||
m_rimReservoirView = reservoirView;
|
||||
m_rimWell = well;
|
||||
m_needsTransformUpdate = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivWellPipesPartMgr::~RivWellPipesPartMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivWellPipesPartMgr::buildWellPipeParts()
|
||||
{
|
||||
if (m_rimReservoirView.isNull()) return;
|
||||
|
||||
m_wellBranches.clear();
|
||||
|
||||
std::vector< size_t > pipeBranchIds;
|
||||
std::vector< std::vector <cvf::Vec3d> > pipeBranchesCLCoords;
|
||||
std::vector< std::vector <CellId> > pipeBranchesCellIds;
|
||||
|
||||
calculateWellPipeCenterline( pipeBranchIds, pipeBranchesCLCoords, pipeBranchesCellIds);
|
||||
|
||||
double characteristicCellSize = m_rimReservoirView->eclipseCase()->reservoirData()->mainGrid()->characteristicCellSize();
|
||||
double pipeRadius = m_rimReservoirView->wellCollection()->pipeRadiusScaleFactor() *m_rimWell->pipeRadiusScaleFactor() * characteristicCellSize;
|
||||
|
||||
for (size_t brIdx = 0; brIdx < pipeBranchIds.size(); ++brIdx)
|
||||
{
|
||||
m_wellBranches.push_back(RivPipeBranchData());
|
||||
RivPipeBranchData& pbd = m_wellBranches.back();
|
||||
|
||||
pbd.m_branchId = pipeBranchIds[brIdx];
|
||||
pbd.m_cellIds = pipeBranchesCellIds[brIdx];
|
||||
|
||||
pbd.m_pipeGeomGenerator = new RivPipeGeometryGenerator;
|
||||
|
||||
pbd.m_pipeGeomGenerator->setRadius(pipeRadius);
|
||||
pbd.m_pipeGeomGenerator->setCrossSectionVertexCount(12);
|
||||
pbd.m_pipeGeomGenerator->setPipeColor( m_rimWell->wellPipeColor());
|
||||
|
||||
cvf::ref<cvf::Vec3dArray> cvfCoords = new cvf::Vec3dArray;
|
||||
cvfCoords->assign(pipeBranchesCLCoords[brIdx]);
|
||||
|
||||
// Scale the centerline coordinates using the Z-scale transform of the grid and correct for the display offset.
|
||||
const RigMainGrid* mainGrid = m_rimReservoirView->eclipseCase()->reservoirData()->mainGrid();
|
||||
|
||||
for (size_t cIdx = 0; cIdx < cvfCoords->size(); ++cIdx)
|
||||
{
|
||||
cvf::Vec4d transfCoord = m_scaleTransform->worldTransform()* cvf::Vec4d((*cvfCoords)[cIdx] - mainGrid->displayModelOffset(), 1);
|
||||
(*cvfCoords)[cIdx][0] = transfCoord[0];
|
||||
(*cvfCoords)[cIdx][1] = transfCoord[1];
|
||||
(*cvfCoords)[cIdx][2] = transfCoord[2];
|
||||
}
|
||||
|
||||
pbd.m_pipeGeomGenerator->setPipeCenterCoords(cvfCoords.p());
|
||||
pbd.m_surfaceDrawable = pbd.m_pipeGeomGenerator->createPipeSurface();
|
||||
pbd.m_centerLineDrawable = pbd.m_pipeGeomGenerator->createCenterLine();
|
||||
|
||||
if (pbd.m_surfaceDrawable.notNull())
|
||||
{
|
||||
pbd.m_surfacePart = new cvf::Part;
|
||||
pbd.m_surfacePart->setDrawable(pbd.m_surfaceDrawable.p());
|
||||
|
||||
caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(m_rimWell->wellPipeColor()), true);
|
||||
cvf::ref<cvf::Effect> eff = surfaceGen.generateEffect();
|
||||
|
||||
pbd.m_surfacePart->setEffect(eff.p());
|
||||
}
|
||||
|
||||
if (pbd.m_centerLineDrawable.notNull())
|
||||
{
|
||||
pbd.m_centerLinePart = new cvf::Part;
|
||||
pbd.m_centerLinePart->setDrawable(pbd.m_centerLineDrawable.p());
|
||||
|
||||
caf::MeshEffectGenerator gen(m_rimWell->wellPipeColor());
|
||||
cvf::ref<cvf::Effect> eff = gen.generateEffect();
|
||||
|
||||
pbd.m_centerLinePart->setEffect(eff.p());
|
||||
}
|
||||
}
|
||||
|
||||
m_needsTransformUpdate = false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< size_t >& pipeBranchIds,
|
||||
std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
|
||||
std::vector< std::vector <CellId> >& pipeBranchesCellIds) const
|
||||
{
|
||||
CVF_ASSERT(m_rimWell.notNull());
|
||||
CVF_ASSERT(m_rimReservoirView.notNull());
|
||||
|
||||
RigReservoir* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData();
|
||||
RigWellResults* wellResults = m_rimWell->wellResults();
|
||||
|
||||
const RigWellResultFrame& staticWellFrame = m_rimWell->wellResults()->m_staticWellCells;
|
||||
|
||||
// Make sure we have computed the static representation of the well
|
||||
if (staticWellFrame.m_wellResultBranches.size() == 0)
|
||||
{
|
||||
wellResults->computeStaticWellCellPath();
|
||||
}
|
||||
if (staticWellFrame.m_wellResultBranches.size() == 0) return;
|
||||
|
||||
// Initialize the return arrays
|
||||
pipeBranchIds.clear();
|
||||
pipeBranchesCLCoords.clear();
|
||||
pipeBranchesCellIds.clear();
|
||||
|
||||
// Well head
|
||||
// Match this position with well head position in RivWellHeadPartMgr::buildWellHeadParts()
|
||||
const RigCell& whCell = rigReservoir->cellFromWellResultCell(staticWellFrame.m_wellHead);
|
||||
cvf::Vec3d whStartPos = whCell.faceCenter(cvf::StructGridInterface::NEG_K);
|
||||
const RigWellResultCell* whResCell = &(staticWellFrame.m_wellHead);
|
||||
|
||||
// Loop over all the well branches
|
||||
const std::vector<RigWellResultBranch>& resBranches = staticWellFrame.m_wellResultBranches;
|
||||
|
||||
for (size_t brIdx = 0; brIdx < resBranches.size(); brIdx++)
|
||||
{
|
||||
if (resBranches[brIdx].m_wellCells.size() == 0) continue; // Skip empty branches. Do not know why they exist, but they make problems.
|
||||
|
||||
// Create a new branch
|
||||
pipeBranchIds.push_back(resBranches[brIdx].m_branchNumber);
|
||||
pipeBranchesCLCoords.push_back(std::vector<cvf::Vec3d>());
|
||||
pipeBranchesCellIds.push_back(std::vector <CellId>());
|
||||
|
||||
// We start by entering the first cell (the wellhead)
|
||||
const RigWellResultCell* prevResCell = whResCell;
|
||||
pipeBranchesCLCoords.back().push_back(whStartPos);
|
||||
pipeBranchesCellIds.back().push_back(CellId(prevResCell->m_gridIndex, prevResCell->m_gridCellIndex));
|
||||
|
||||
// Add extra coordinate between cell face and cell center
|
||||
// to make sure the well pipe terminated in a segment parallel to z-axis
|
||||
cvf::Vec3d whIntermediate = whStartPos;
|
||||
whIntermediate.z() = (whStartPos.z() + whCell.center().z()) / 2.0;
|
||||
pipeBranchesCLCoords.back().push_back(whIntermediate);
|
||||
pipeBranchesCellIds.back().push_back(CellId(prevResCell->m_gridIndex, prevResCell->m_gridCellIndex));
|
||||
|
||||
|
||||
// Loop over all the resultCells in the branch
|
||||
const std::vector<RigWellResultCell>& resBranchCells = resBranches[brIdx].m_wellCells;
|
||||
|
||||
for (size_t cIdx = 0; cIdx < resBranchCells.size(); cIdx++)
|
||||
{
|
||||
std::vector<cvf::Vec3d>& branchCLCoords = pipeBranchesCLCoords.back();
|
||||
std::vector<CellId>& branchCellIds = pipeBranchesCellIds.back();
|
||||
|
||||
const RigWellResultCell& resCell = resBranchCells[cIdx];
|
||||
const RigCell& cell = rigReservoir->cellFromWellResultCell(resCell);
|
||||
|
||||
// Check if this and the previous cells has shared faces
|
||||
|
||||
cvf::StructGridInterface::FaceType sharedFace;
|
||||
if (rigReservoir->findSharedSourceFace(sharedFace, resCell, *prevResCell))
|
||||
{
|
||||
branchCLCoords.push_back(cell.faceCenter(sharedFace));
|
||||
branchCellIds.push_back(CellId(resCell.m_gridIndex, resCell.m_gridCellIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
// This and the previous cell does not share a face. We need to go out of the previous cell, before entering this.
|
||||
const RigCell& prevCell = rigReservoir->cellFromWellResultCell(*prevResCell);
|
||||
cvf::Vec3d centerPrevCell = prevCell.center();
|
||||
cvf::Vec3d centerThisCell = cell.center();
|
||||
|
||||
// First make sure this cell is not starting a new "display" branch
|
||||
if ( (prevResCell == whResCell) || (centerThisCell-centerPrevCell).lengthSquared() <= (centerThisCell - whStartPos).lengthSquared())
|
||||
{
|
||||
// Create ray and intersect with cells
|
||||
|
||||
cvf::Ray rayToThisCell;
|
||||
rayToThisCell.setOrigin(centerPrevCell);
|
||||
rayToThisCell.setDirection((centerThisCell - centerPrevCell).getNormalized());
|
||||
|
||||
cvf::Vec3d outOfPrevCell(centerPrevCell);
|
||||
cvf::Vec3d intoThisCell(centerThisCell);
|
||||
|
||||
bool intersectionOk = prevCell.firstIntersectionPoint(rayToThisCell, &outOfPrevCell);
|
||||
//CVF_ASSERT(intersectionOk);
|
||||
intersectionOk = cell.firstIntersectionPoint(rayToThisCell, &intoThisCell);
|
||||
//CVF_ASSERT(intersectionOk);
|
||||
if ((intoThisCell - outOfPrevCell).lengthSquared() > 1e-3)
|
||||
{
|
||||
branchCLCoords.push_back(outOfPrevCell);
|
||||
branchCellIds.push_back(CellId(cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T));
|
||||
}
|
||||
branchCLCoords.push_back(intoThisCell);
|
||||
branchCellIds.push_back(CellId(resCell.m_gridIndex, resCell.m_gridCellIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
// This cell is further from the previous cell than from the well head,
|
||||
// thus we interpret it as a new branch.
|
||||
|
||||
// First finish the current branch
|
||||
branchCLCoords.push_back(branchCLCoords.back() + 1.5*(centerPrevCell - branchCLCoords.back()) );
|
||||
|
||||
// Create new display branch
|
||||
pipeBranchIds.push_back(resBranches[brIdx].m_branchNumber);
|
||||
pipeBranchesCLCoords.push_back(std::vector<cvf::Vec3d>());
|
||||
pipeBranchesCellIds.push_back(std::vector <CellId>());
|
||||
|
||||
// Start the new branch by entering the first cell (the wellhead) and intermediate
|
||||
prevResCell = whResCell;
|
||||
pipeBranchesCLCoords.back().push_back(whStartPos);
|
||||
pipeBranchesCellIds.back().push_back(CellId(prevResCell->m_gridIndex, prevResCell->m_gridCellIndex));
|
||||
|
||||
// Include intermediate
|
||||
pipeBranchesCLCoords.back().push_back(whIntermediate);
|
||||
pipeBranchesCellIds.back().push_back(CellId(prevResCell->m_gridIndex, prevResCell->m_gridCellIndex));
|
||||
|
||||
// Well now we need to step one back to take this cell again, but in the new branch.
|
||||
cIdx--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
prevResCell = &resCell;
|
||||
|
||||
// If we are looking at last cell, add the point 0.5 past the center of that cell
|
||||
if (cIdx == resBranchCells.size() -1)
|
||||
{
|
||||
branchCLCoords.push_back(branchCLCoords.back() + 1.5*(cell.center() - branchCLCoords.back()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CVF_ASSERT(pipeBranchesCellIds.size() == pipeBranchesCLCoords.size());
|
||||
for (size_t i = 0 ; i < pipeBranchesCellIds.size() ; ++i)
|
||||
{
|
||||
CVF_ASSERT(pipeBranchesCellIds[i].size() == pipeBranchesCLCoords[i].size()-1);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivWellPipesPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex)
|
||||
{
|
||||
if (m_rimReservoirView.isNull()) return;
|
||||
if (m_rimWell.isNull()) return;
|
||||
|
||||
if ( m_rimReservoirView->wellCollection()->wellPipeVisibility() != RimWellCollection::FORCE_ALL_ON
|
||||
&& m_rimWell->showWellPipes() == false) return;
|
||||
|
||||
if ( m_rimWell->wellResults()->firstResultTimeStep() == cvf::UNDEFINED_SIZE_T
|
||||
|| frameIndex < m_rimWell->wellResults()->firstResultTimeStep() )
|
||||
return;
|
||||
|
||||
if (m_needsTransformUpdate) buildWellPipeParts();
|
||||
|
||||
std::list<RivPipeBranchData>::iterator it;
|
||||
for (it = m_wellBranches.begin(); it != m_wellBranches.end(); it++)
|
||||
{
|
||||
if (it->m_surfacePart.notNull())
|
||||
{
|
||||
model->addPart(it->m_surfacePart.p());
|
||||
}
|
||||
if (it->m_centerLinePart.notNull())
|
||||
{
|
||||
model->addPart(it->m_centerLinePart.p());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivWellPipesPartMgr::updatePipeResultColor(size_t frameIndex)
|
||||
{
|
||||
if (m_rimWell == NULL) return;
|
||||
|
||||
RigWellResults* wRes = m_rimWell->wellResults();
|
||||
if (wRes == NULL) return;
|
||||
|
||||
if (frameIndex < wRes->firstResultTimeStep()) return; // Or reset colors or something
|
||||
|
||||
// Setup a scalar mapper
|
||||
cvf::ref<cvf::ScalarMapperDiscreteLinear> scalarMapper = new cvf::ScalarMapperDiscreteLinear;
|
||||
cvf::Color3ubArray legendColors;
|
||||
legendColors.resize(4);
|
||||
legendColors[0] = cvf::Color3::GRAY;
|
||||
legendColors[1] = cvf::Color3::GREEN;
|
||||
legendColors[2] = cvf::Color3::BLUE;
|
||||
legendColors[3] = cvf::Color3::RED;
|
||||
scalarMapper->setColors(legendColors);
|
||||
scalarMapper->setRange(0.0 , 4.0);
|
||||
scalarMapper->setLevelsFromColorCount(4);
|
||||
|
||||
const double closed = -0.1, producing = 1.5, water = 2.5, hcInjection = 3.5; // Closed set to -0.1 instead of 0.5 to workaround bug in the scalar mapper.
|
||||
|
||||
std::list<RivPipeBranchData>::iterator brIt;
|
||||
const RigWellResultFrame& wResFrame = wRes->wellResultFrame(frameIndex);
|
||||
|
||||
std::vector<double> wellCellStates;
|
||||
|
||||
for (brIt = m_wellBranches.begin(); brIt != m_wellBranches.end(); ++brIt)
|
||||
{
|
||||
size_t branchId = brIt->m_branchId;
|
||||
|
||||
// find corresponding result branch
|
||||
size_t i;
|
||||
for ( i = 0; i < wResFrame.m_wellResultBranches.size(); ++i)
|
||||
{
|
||||
if (wResFrame.m_wellResultBranches[i].m_branchNumber == branchId) break;
|
||||
}
|
||||
|
||||
// Initialize well states to "closed" state
|
||||
wellCellStates.clear();
|
||||
wellCellStates.resize(brIt->m_cellIds.size(), closed);
|
||||
|
||||
// Find result values
|
||||
if (i >= wResFrame.m_wellResultBranches.size())
|
||||
{
|
||||
// Branch not found in results. Do nothing. Keep the "closed" states
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::vector<RigWellResultCell>& resBranch = wResFrame.m_wellResultBranches[i].m_wellCells;
|
||||
const std::vector <CellId>& cellIds = brIt->m_cellIds;
|
||||
|
||||
// Find cellIds[wcIdx] in resBranch
|
||||
// ifFound then give color from cell state
|
||||
// else give closed color
|
||||
|
||||
// The search can be simplified to comparing the current element against
|
||||
// the first unmatched element in the result branch vector since the result is (supposed) to be
|
||||
// a subset of the complete branch where all elements have the same order
|
||||
|
||||
size_t rcIdx = 0; // index to first unmatched element in results
|
||||
for (size_t wcIdx = 0; wcIdx < cellIds.size(); ++wcIdx)
|
||||
{
|
||||
if (rcIdx >= resBranch.size())
|
||||
{
|
||||
// We are beyond the result cells. This well cell is closed.
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( cellIds[wcIdx].gridIndex == resBranch[rcIdx].m_gridIndex
|
||||
&& cellIds[wcIdx].cellIndex == resBranch[rcIdx].m_gridCellIndex)
|
||||
{
|
||||
double cellState = closed;
|
||||
|
||||
if (resBranch[rcIdx].m_isOpen)
|
||||
{
|
||||
switch (wResFrame.m_productionType)
|
||||
{
|
||||
case RigWellResultFrame::PRODUCER:
|
||||
cellState = producing;
|
||||
break;
|
||||
case RigWellResultFrame::OIL_INJECTOR:
|
||||
cellState = hcInjection;
|
||||
break;
|
||||
case RigWellResultFrame::GAS_INJECTOR:
|
||||
cellState = hcInjection;
|
||||
break;
|
||||
case RigWellResultFrame::WATER_INJECTOR:
|
||||
cellState = water;
|
||||
break;
|
||||
case RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE:
|
||||
cellState = closed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wellCellStates[wcIdx] = cellState;
|
||||
rcIdx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find or create texture coords array for pipe surface
|
||||
|
||||
if (brIt->m_surfaceDrawable.notNull())
|
||||
{
|
||||
cvf::ref<cvf::Vec2fArray> surfTexCoords = const_cast<cvf::Vec2fArray*>(brIt->m_surfaceDrawable->textureCoordArray());
|
||||
|
||||
if (surfTexCoords.isNull())
|
||||
{
|
||||
surfTexCoords = new cvf::Vec2fArray;
|
||||
}
|
||||
|
||||
brIt->m_pipeGeomGenerator->pipeSurfaceTextureCoords( surfTexCoords.p(), wellCellStates, scalarMapper.p());
|
||||
brIt->m_surfaceDrawable->setTextureCoordArray( surfTexCoords.p());
|
||||
|
||||
caf::ScalarMapperEffectGenerator surfEffGen(scalarMapper.p(), true);
|
||||
cvf::ref<cvf::Effect> seff = surfEffGen.generateEffect();
|
||||
|
||||
brIt->m_surfacePart->setEffect(seff.p());
|
||||
}
|
||||
|
||||
// Find or create texture coords array for pipe center line
|
||||
if (brIt->m_centerLineDrawable.notNull())
|
||||
{
|
||||
cvf::ref<cvf::Vec2fArray> lineTexCoords = const_cast<cvf::Vec2fArray*>(brIt->m_centerLineDrawable->textureCoordArray());
|
||||
|
||||
if (lineTexCoords.isNull())
|
||||
{
|
||||
lineTexCoords = new cvf::Vec2fArray;
|
||||
}
|
||||
|
||||
// Calculate new texture coordinates
|
||||
brIt->m_pipeGeomGenerator->centerlineTextureCoords( lineTexCoords.p(), wellCellStates, scalarMapper.p());
|
||||
|
||||
// Set the new texture coordinates
|
||||
|
||||
brIt->m_centerLineDrawable->setTextureCoordArray( lineTexCoords.p());
|
||||
|
||||
// Set effects
|
||||
|
||||
caf::ScalarMapperMeshEffectGenerator meshEffGen(scalarMapper.p());
|
||||
cvf::ref<cvf::Effect> meff = meshEffGen.generateEffect();
|
||||
|
||||
brIt->m_centerLinePart->setEffect(meff.p());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
95
ApplicationCode/ModelVisualization/RivWellPipesPartMgr.h
Normal file
95
ApplicationCode/ModelVisualization/RivWellPipesPartMgr.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmPointer.h"
|
||||
#include <list>
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class Part;
|
||||
class ModelBasicList;
|
||||
class Transform;
|
||||
}
|
||||
|
||||
class RivPipeGeometryGenerator;
|
||||
class RimReservoirView;
|
||||
class RimWell;
|
||||
|
||||
class RivWellPipesPartMgr : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivWellPipesPartMgr(RimReservoirView* reservoirView, RimWell* well);
|
||||
~RivWellPipesPartMgr();
|
||||
|
||||
void setScaleTransform(cvf::Transform * scaleTransform) { m_scaleTransform = scaleTransform; scheduleGeometryRegen();}
|
||||
|
||||
void scheduleGeometryRegen() { m_needsTransformUpdate = true; }
|
||||
|
||||
void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex);
|
||||
void updatePipeResultColor(size_t frameIndex);
|
||||
|
||||
|
||||
private:
|
||||
caf::PdmPointer<RimReservoirView> m_rimReservoirView;
|
||||
caf::PdmPointer<RimWell> m_rimWell;
|
||||
|
||||
cvf::ref<cvf::Transform> m_scaleTransform;
|
||||
bool m_needsTransformUpdate;
|
||||
|
||||
void buildWellPipeParts();
|
||||
class CellId
|
||||
{
|
||||
public:
|
||||
CellId() :
|
||||
gridIndex(cvf::UNDEFINED_SIZE_T),
|
||||
cellIndex(cvf::UNDEFINED_SIZE_T)
|
||||
{ }
|
||||
|
||||
CellId(size_t gidx, size_t cIdx) :
|
||||
gridIndex(gidx),
|
||||
cellIndex(cIdx)
|
||||
{ }
|
||||
|
||||
size_t gridIndex;
|
||||
size_t cellIndex;
|
||||
};
|
||||
|
||||
//void calculateWellPipeCenterline(std::vector<cvf::Vec3d>& coords) const;
|
||||
|
||||
void calculateWellPipeCenterline(std::vector< size_t >& pipeBranchIds,
|
||||
std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
|
||||
std::vector< std::vector <CellId> >& pipeBranchesCellIds ) const;
|
||||
|
||||
struct RivPipeBranchData
|
||||
{
|
||||
size_t m_branchId;
|
||||
std::vector <CellId> m_cellIds;
|
||||
cvf::ref<RivPipeGeometryGenerator> m_pipeGeomGenerator;
|
||||
|
||||
cvf::ref<cvf::Part> m_surfacePart;
|
||||
cvf::ref<cvf::DrawableGeo> m_surfaceDrawable;
|
||||
cvf::ref<cvf::Part> m_centerLinePart;
|
||||
cvf::ref<cvf::DrawableGeo> m_centerLineDrawable;
|
||||
|
||||
};
|
||||
|
||||
std::list<RivPipeBranchData> m_wellBranches;
|
||||
cvf::Collection< cvf::Part > m_wellPipeParts;
|
||||
};
|
||||
59
ApplicationCode/ProjectDataModel/RimCalcScript.cpp
Normal file
59
ApplicationCode/ProjectDataModel/RimCalcScript.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "RimCalcScript.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimCalcScript, "CalcScript");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCalcScript::RimCalcScript()
|
||||
{
|
||||
CAF_PDM_InitObject("CalcScript", ":/octave.png", "Calc Script", "");
|
||||
|
||||
CAF_PDM_InitField(&absolutePath, "AbsolutePath", QString(), "Location", "", "" ,"");
|
||||
CAF_PDM_InitField(&content, "Content", QString(), "Directory", "", "" ,"");
|
||||
content.setHidden(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCalcScript::~RimCalcScript()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCalcScript::readContentFromFile()
|
||||
{
|
||||
QFile file(absolutePath);
|
||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
QString fileContent = file.readAll();
|
||||
|
||||
content = fileContent;
|
||||
}
|
||||
}
|
||||
|
||||
40
ApplicationCode/ProjectDataModel/RimCalcScript.h
Normal file
40
ApplicationCode/ProjectDataModel/RimCalcScript.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCalcScript : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimCalcScript();
|
||||
virtual ~RimCalcScript();
|
||||
|
||||
void readContentFromFile();
|
||||
|
||||
caf::PdmField<QString> absolutePath;
|
||||
caf::PdmField<QString> content;
|
||||
};
|
||||
311
ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp
Normal file
311
ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp
Normal file
@@ -0,0 +1,311 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimCellEdgeResultSlot.h"
|
||||
#include "RimLegendConfig.h"
|
||||
#include "RimReservoirView.h"
|
||||
#include "RimReservoir.h"
|
||||
#include "RimReservoirView.h"
|
||||
#include "RigReservoirCellResults.h"
|
||||
#include "RigReservoir.h"
|
||||
#include "RifReaderInterface.h"
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimCellEdgeResultSlot, "CellEdgeResultSlot");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellEdgeResultSlot::RimCellEdgeResultSlot()
|
||||
{
|
||||
CAF_PDM_InitObject("Cell Edge Result", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&resultVariable, "CellEdgeVariable", "Result variable", ":/Default.png", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&legendConfig, "LegendDefinition", "Legend Definition", ":/Legend.png", "", "");
|
||||
|
||||
legendConfig = new RimLegendConfig();
|
||||
|
||||
m_ignoredResultScalar = cvf::UNDEFINED_DOUBLE;
|
||||
resetResultIndices();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellEdgeResultSlot::~RimCellEdgeResultSlot()
|
||||
{
|
||||
delete legendConfig();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellEdgeResultSlot::setReservoirView(RimReservoirView* ownerReservoirView)
|
||||
{
|
||||
m_reservoirView = ownerReservoirView;
|
||||
this->legendConfig()->setReservoirView(ownerReservoirView);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellEdgeResultSlot::loadResult()
|
||||
{
|
||||
resetResultIndices();
|
||||
QStringList vars = findResultVariableNames();
|
||||
updateIgnoredScalarValue();
|
||||
int i;
|
||||
for (i = 0; i < vars.size(); ++i)
|
||||
{
|
||||
size_t resultindex = gridCellResults()->loadResultIntoGrid(RimDefines::STATIC_NATIVE, vars[i]);
|
||||
int cubeFaceIdx;
|
||||
for (cubeFaceIdx = 0; cubeFaceIdx < 6; ++cubeFaceIdx)
|
||||
{
|
||||
QString varEnd = EdgeFaceEnum::textFromIndex(cubeFaceIdx);
|
||||
|
||||
if (vars[i].endsWith(varEnd))
|
||||
{
|
||||
m_resultNameToIndexPairs[cubeFaceIdx] = std::make_pair(vars[i], resultindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellEdgeResultSlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (changedField == &resultVariable)
|
||||
{
|
||||
loadResult();
|
||||
}
|
||||
|
||||
if (m_reservoirView) m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void RimCellEdgeResultSlot::EdgeFaceEnum::setUp()
|
||||
{
|
||||
addItem(RimCellEdgeResultSlot::X, "X", "");
|
||||
addItem(RimCellEdgeResultSlot::NEG_X, "X-", "");
|
||||
addItem(RimCellEdgeResultSlot::Y, "Y", "");
|
||||
addItem(RimCellEdgeResultSlot::NEG_Y, "Y-", "");
|
||||
addItem(RimCellEdgeResultSlot::Z, "Z", "");
|
||||
addItem(RimCellEdgeResultSlot::NEG_Z, "Z-", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
QList<caf::PdmOptionItemInfo> RimCellEdgeResultSlot::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
|
||||
{
|
||||
if (fieldNeedingOptions == &resultVariable)
|
||||
{
|
||||
if (fileReaderinterface())
|
||||
{
|
||||
QStringList varList;
|
||||
varList = fileReaderinterface()->staticResults();
|
||||
|
||||
QList<caf::PdmOptionItemInfo> optionList;
|
||||
|
||||
std::map<QString, caf::fvector<QString, 6> > varBaseNameToVarsMap;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < varList.size(); ++i)
|
||||
{
|
||||
size_t cubeFaceIdx;
|
||||
for (cubeFaceIdx = 0; cubeFaceIdx < EdgeFaceEnum::size(); ++cubeFaceIdx)
|
||||
{
|
||||
QString varEnd = EdgeFaceEnum::textFromIndex(cubeFaceIdx);
|
||||
if (varList[i].endsWith(varEnd))
|
||||
{
|
||||
QStringList splits = varList[i].split(varEnd);
|
||||
QString variableBasename = splits.front();
|
||||
varBaseNameToVarsMap[variableBasename][cubeFaceIdx] = varList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::map<QString, caf::fvector<QString, 6> >::iterator it;
|
||||
|
||||
for (it = varBaseNameToVarsMap.begin(); it != varBaseNameToVarsMap.end(); ++it)
|
||||
{
|
||||
QString optionUiName = it->first;
|
||||
optionUiName += " (";
|
||||
int cubeFaceIdx;
|
||||
bool firstText = true;
|
||||
for (cubeFaceIdx = 0; cubeFaceIdx < 6; ++cubeFaceIdx)
|
||||
{
|
||||
if (!it->second.v[cubeFaceIdx].isEmpty())
|
||||
{
|
||||
if (firstText)
|
||||
{
|
||||
optionUiName += it->second.v[cubeFaceIdx];
|
||||
firstText = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
optionUiName += QString(", ") + it->second.v[cubeFaceIdx];
|
||||
}
|
||||
}
|
||||
}
|
||||
optionUiName += ")";
|
||||
|
||||
optionList.push_back(caf::PdmOptionItemInfo( optionUiName, QVariant(it->first)));
|
||||
|
||||
}
|
||||
|
||||
optionList.push_front(caf::PdmOptionItemInfo( "None", "" ));
|
||||
|
||||
if (useOptionsOnly) *useOptionsOnly = true;
|
||||
|
||||
return optionList;
|
||||
}
|
||||
}
|
||||
|
||||
return QList<caf::PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RimCellEdgeResultSlot::findResultVariableNames()
|
||||
{
|
||||
QStringList varNames;
|
||||
|
||||
if (fileReaderinterface() && !resultVariable().isEmpty())
|
||||
{
|
||||
QStringList varList;
|
||||
varList = fileReaderinterface()->staticResults();
|
||||
int i;
|
||||
for (i = 0; i < varList.size(); ++i)
|
||||
{
|
||||
if (varList[i].contains(resultVariable))
|
||||
{
|
||||
varNames.append(varList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return varNames;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigReservoirCellResults* RimCellEdgeResultSlot::gridCellResults()
|
||||
{
|
||||
CVF_ASSERT(m_reservoirView != NULL
|
||||
&& m_reservoirView->eclipseCase()
|
||||
&& m_reservoirView->eclipseCase()->reservoirData()
|
||||
&& m_reservoirView->eclipseCase()->reservoirData()->mainGrid());
|
||||
|
||||
return m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->results();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderInterface* RimCellEdgeResultSlot::fileReaderinterface()
|
||||
{
|
||||
if (m_reservoirView && m_reservoirView->eclipseCase())
|
||||
{
|
||||
return m_reservoirView->eclipseCase()->fileInterface();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellEdgeResultSlot::gridScalarIndices(size_t resultIndices[6])
|
||||
{
|
||||
int cubeFaceIndex;
|
||||
for (cubeFaceIndex = 0; cubeFaceIndex < 6; ++cubeFaceIndex)
|
||||
{
|
||||
resultIndices[cubeFaceIndex] = m_resultNameToIndexPairs[cubeFaceIndex].second;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellEdgeResultSlot::gridScalarResultNames(QStringList* resultNames)
|
||||
{
|
||||
CVF_ASSERT(resultNames);
|
||||
|
||||
int cubeFaceIndex;
|
||||
for (cubeFaceIndex = 0; cubeFaceIndex < 6; ++cubeFaceIndex)
|
||||
{
|
||||
resultNames->push_back(m_resultNameToIndexPairs[cubeFaceIndex].first);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellEdgeResultSlot::resetResultIndices()
|
||||
{
|
||||
int cubeFaceIndex;
|
||||
for (cubeFaceIndex = 0; cubeFaceIndex < 6; ++cubeFaceIndex)
|
||||
{
|
||||
m_resultNameToIndexPairs[cubeFaceIndex].second = cvf::UNDEFINED_SIZE_T;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCellEdgeResultSlot::hasResult() const
|
||||
{
|
||||
bool hasResult = false;
|
||||
int cubeFaceIndex;
|
||||
for (cubeFaceIndex = 0; cubeFaceIndex < 6; ++cubeFaceIndex)
|
||||
{
|
||||
hasResult |= ((m_resultNameToIndexPairs[cubeFaceIndex].second) != cvf::UNDEFINED_SIZE_T);
|
||||
}
|
||||
|
||||
return hasResult;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellEdgeResultSlot::updateIgnoredScalarValue()
|
||||
{
|
||||
if (resultVariable == "MULT")
|
||||
{
|
||||
m_ignoredResultScalar = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ignoredResultScalar = cvf::UNDEFINED_DOUBLE;
|
||||
}
|
||||
}
|
||||
|
||||
88
ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h
Normal file
88
ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "RimLegendConfig.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include "RimDefines.h"
|
||||
|
||||
class RigReservoirCellResults;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <typename T, size_t vectorSize>
|
||||
class fvector
|
||||
{
|
||||
public:
|
||||
T v[vectorSize];
|
||||
T& operator[] (size_t idx) { return v[idx]; }
|
||||
const T& operator[] (size_t idx) const { return v[idx]; }
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCellEdgeResultSlot : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimCellEdgeResultSlot();
|
||||
virtual ~RimCellEdgeResultSlot();
|
||||
|
||||
enum EdgeFaceType
|
||||
{
|
||||
X, NEG_X,
|
||||
Y, NEG_Y,
|
||||
Z, NEG_Z
|
||||
};
|
||||
|
||||
typedef caf::AppEnum<RimCellEdgeResultSlot::EdgeFaceType> EdgeFaceEnum;
|
||||
|
||||
void setReservoirView(RimReservoirView* ownerReservoirView);
|
||||
|
||||
caf::PdmField<QString> resultVariable;
|
||||
caf::PdmField<RimLegendConfig*> legendConfig;
|
||||
double ignoredScalarValue() { return m_ignoredResultScalar; }
|
||||
void gridScalarIndices(size_t resultIndices[6]);
|
||||
void gridScalarResultNames(QStringList* resultNames);
|
||||
void loadResult();
|
||||
bool hasResult() const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly );
|
||||
QStringList findResultVariableNames();
|
||||
|
||||
private:
|
||||
RigReservoirCellResults* gridCellResults();
|
||||
RifReaderInterface* fileReaderinterface();
|
||||
|
||||
void resetResultIndices();
|
||||
void updateIgnoredScalarValue();
|
||||
protected:
|
||||
caf::fvector<std::pair<QString, size_t>, 6 > m_resultNameToIndexPairs;
|
||||
caf::PdmPointer<RimReservoirView> m_reservoirView;
|
||||
double m_ignoredResultScalar;
|
||||
};
|
||||
|
||||
106
ApplicationCode/ProjectDataModel/RimCellFilter.cpp
Normal file
106
ApplicationCode/ProjectDataModel/RimCellFilter.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "RimCellFilter.h"
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void caf::AppEnum< RimCellFilter::FilterModeType>::setUp()
|
||||
{
|
||||
addItem(RimCellFilter::INCLUDE, "INCLUDE", "Include");
|
||||
addItem(RimCellFilter::EXCLUDE, "EXCLUDE", "Exclude");
|
||||
setDefault(RimCellFilter::INCLUDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimCellFilter, "CellFilter");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellFilter::RimCellFilter()
|
||||
{
|
||||
CAF_PDM_InitObject("Cell Filter", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&name, "UserDescription", QString("Filter Name"), "Name", "", "", "");
|
||||
CAF_PDM_InitField(&active, "Active", true, "Active", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&filterMode, "FilterType", "Filter Type", "", "", "");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellFilter::~RimCellFilter()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimCellFilter::userDescriptionField()
|
||||
{
|
||||
return &name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellFilter::updateIconState()
|
||||
{
|
||||
// Reset dynamic icon
|
||||
this->setUiIcon(QIcon());
|
||||
// Get static one
|
||||
QIcon icon = this->uiIcon();
|
||||
|
||||
// Get a pixmap, and modify it
|
||||
|
||||
QPixmap icPixmap;
|
||||
icPixmap = icon.pixmap(16, 16, QIcon::Normal);
|
||||
|
||||
QPixmap sign;
|
||||
if (filterMode() == INCLUDE)
|
||||
{
|
||||
sign.load(":/Plus.png");
|
||||
}
|
||||
else
|
||||
{
|
||||
sign.load(":/Minus.png");
|
||||
}
|
||||
|
||||
{
|
||||
QPainter painter(&icPixmap);
|
||||
painter.drawPixmap(0,0, sign);
|
||||
}
|
||||
|
||||
if (!active)
|
||||
{
|
||||
QIcon temp(icPixmap);
|
||||
icPixmap = temp.pixmap(16, 16, QIcon::Disabled);
|
||||
}
|
||||
|
||||
QIcon newIcon(icPixmap);
|
||||
this->setUiIcon(newIcon);
|
||||
}
|
||||
52
ApplicationCode/ProjectDataModel/RimCellFilter.h
Normal file
52
ApplicationCode/ProjectDataModel/RimCellFilter.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include "cafAppEnum.h"
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCellFilter : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
enum FilterModeType
|
||||
{
|
||||
INCLUDE,
|
||||
EXCLUDE
|
||||
};
|
||||
|
||||
RimCellFilter();
|
||||
virtual ~RimCellFilter();
|
||||
|
||||
caf::PdmField<QString> name;
|
||||
caf::PdmField<bool> active;
|
||||
caf::PdmField< caf::AppEnum< FilterModeType > > filterMode;
|
||||
|
||||
void updateIconState();
|
||||
|
||||
protected:
|
||||
virtual caf::PdmFieldHandle* userDescriptionField();
|
||||
};
|
||||
206
ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp
Normal file
206
ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimReservoirView.h"
|
||||
#include "RimCellPropertyFilter.h"
|
||||
#include "RimCellPropertyFilterCollection.h"
|
||||
#include "RigGridBase.h"
|
||||
#include "RigReservoirCellResults.h"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void caf::AppEnum< RimCellPropertyFilter::EvaluationRegionType>::setUp()
|
||||
{
|
||||
addItem(RimCellPropertyFilter::RANGE_FILTER_REGION, "RANGE_FILTER_REGION", "Range filter cells");
|
||||
addItem(RimCellPropertyFilter::GLOBAL_REGION, "GLOBAL_REGION", "All cells");
|
||||
setDefault(RimCellPropertyFilter::RANGE_FILTER_REGION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimCellPropertyFilter, "CellPropertyFilter");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellPropertyFilter::RimCellPropertyFilter()
|
||||
: m_parentContainer(NULL)
|
||||
{
|
||||
CAF_PDM_InitObject("Cell Property Filter", ":/CellFilter_Values.png", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&evaluationRegion, "EvaluationRegion", "Evaluation region", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&resultDefinition, "ResultDefinition", "Result definition", "", "", "");
|
||||
resultDefinition = new RimResultDefinition();
|
||||
resultDefinition.setHidden(true);
|
||||
|
||||
CAF_PDM_InitField(&lowerBound, "LowerBound", 0.0, "Min", "", "", "");
|
||||
CAF_PDM_InitField(&upperBound, "UpperBound", 0.0, "Max", "", "", "");
|
||||
|
||||
updateIconState();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellPropertyFilter::~RimCellPropertyFilter()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellPropertyFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (changedField == &name)
|
||||
{
|
||||
}
|
||||
else if (&resultDefinition == changedField)
|
||||
{
|
||||
setDefaultValues();
|
||||
m_parentContainer->fieldChangedByUi(changedField, oldValue, newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_parentContainer->fieldChangedByUi(changedField, oldValue, newValue);
|
||||
this->updateIconState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCellPropertyFilter::isCellRejected(const RigGridBase* grid, size_t timeStepIndex, size_t cellIndex) const
|
||||
{
|
||||
CVF_ASSERT(grid);
|
||||
|
||||
if (resultDefinition->gridScalarIndex() == cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t resultIndex = 0;
|
||||
if (resultDefinition->hasDynamicResult())
|
||||
{
|
||||
resultIndex = timeStepIndex;
|
||||
}
|
||||
|
||||
double scalarValue = grid->cellScalar(resultIndex, resultDefinition->gridScalarIndex(), cellIndex);
|
||||
bool rejected = false;
|
||||
if (scalarValue < lowerBound || scalarValue > upperBound)
|
||||
{
|
||||
rejected = true;
|
||||
}
|
||||
|
||||
if (filterMode == INCLUDE)
|
||||
{
|
||||
return rejected;
|
||||
}
|
||||
else
|
||||
{
|
||||
return !rejected;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::CellRangeFilter::CellStateType RimCellPropertyFilter::cellFilterState(const RigGridBase* grid, size_t timeStepIndex, size_t cellIndex) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(grid);
|
||||
CVF_TIGHT_ASSERT(resultDefinition->gridScalarIndex() != cvf::UNDEFINED_SIZE_T);
|
||||
|
||||
size_t tStepIdx = 0;
|
||||
if (resultDefinition->hasDynamicResult())
|
||||
{
|
||||
tStepIdx = timeStepIndex;
|
||||
}
|
||||
|
||||
double scalarValue = grid->cellScalar(tStepIdx, resultDefinition->gridScalarIndex(), cellIndex);
|
||||
|
||||
if ( lowerBound <= scalarValue && scalarValue <= upperBound)
|
||||
{
|
||||
if (filterMode == INCLUDE) return cvf::CellRangeFilter::INCLUDED;
|
||||
else return cvf::CellRangeFilter::EXCLUDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return cvf::CellRangeFilter::NOT_INCLUDED;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimCellPropertyFilter::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
|
||||
{
|
||||
return resultDefinition->calculateValueOptions(fieldNeedingOptions, useOptionsOnly);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellPropertyFilter::setParentContainer(RimCellPropertyFilterCollection* parentContainer)
|
||||
{
|
||||
m_parentContainer = parentContainer;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellPropertyFilterCollection* RimCellPropertyFilter::parentContainer()
|
||||
{
|
||||
return m_parentContainer;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellPropertyFilter::setDefaultValues()
|
||||
{
|
||||
CVF_ASSERT(m_parentContainer);
|
||||
|
||||
double min = 0.0;
|
||||
double max = 0.0;
|
||||
|
||||
size_t scalarIndex = resultDefinition->gridScalarIndex();
|
||||
if (scalarIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
RigReservoirCellResults* results = m_parentContainer->reservoirView()->gridCellResults();
|
||||
if (results)
|
||||
{
|
||||
results->minMaxCellScalarValues(scalarIndex, min, max);
|
||||
}
|
||||
}
|
||||
|
||||
lowerBound = min;
|
||||
lowerBound.setUiName(QString("Min (%1)").arg(min));
|
||||
|
||||
upperBound = max;
|
||||
upperBound.setUiName(QString("Max (%1)").arg(max));
|
||||
}
|
||||
|
||||
81
ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h
Normal file
81
ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmDocument.h"
|
||||
#include "cafAppEnum.h"
|
||||
|
||||
#include "RimDefines.h"
|
||||
#include "RimCellFilter.h"
|
||||
#include "cvfStructGridGeometryGenerator.h"
|
||||
|
||||
class RimReservoirView;
|
||||
class RimCellPropertyFilterCollection;
|
||||
class RimResultDefinition;
|
||||
|
||||
class RigGridBase;
|
||||
class RigReservoirCellResults;
|
||||
namespace cvf
|
||||
{
|
||||
//enum CellRangeFilter::CellStateType;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCellPropertyFilter : public RimCellFilter
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
enum EvaluationRegionType
|
||||
{
|
||||
RANGE_FILTER_REGION,
|
||||
GLOBAL_REGION
|
||||
};
|
||||
|
||||
public:
|
||||
RimCellPropertyFilter();
|
||||
virtual ~RimCellPropertyFilter();
|
||||
|
||||
void setParentContainer(RimCellPropertyFilterCollection* parentContainer);
|
||||
RimCellPropertyFilterCollection* parentContainer();
|
||||
void setDefaultValues();
|
||||
|
||||
caf::PdmField<RimResultDefinition*> resultDefinition;
|
||||
|
||||
caf::PdmField<double> lowerBound;
|
||||
caf::PdmField<double> upperBound;
|
||||
caf::PdmField< caf::AppEnum< EvaluationRegionType > > evaluationRegion;
|
||||
|
||||
bool isCellRejected(const RigGridBase* grid, size_t timeStepIndex, size_t cellIndex) const;
|
||||
cvf::CellRangeFilter::CellStateType cellFilterState(const RigGridBase* grid, size_t timeStepIndex, size_t cellIndex) const;
|
||||
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
|
||||
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly );
|
||||
|
||||
private:
|
||||
RimCellPropertyFilterCollection* m_parentContainer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimCellPropertyFilterCollection.h"
|
||||
|
||||
#include "RimReservoirView.h"
|
||||
#include "RigGridBase.h"
|
||||
#include "RigReservoirCellResults.h"
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimCellPropertyFilterCollection, "CellPropertyFilters");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellPropertyFilterCollection::RimCellPropertyFilterCollection()
|
||||
{
|
||||
CAF_PDM_InitObject("Cell Property Filters", ":/CellFilter_Values.png", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&propertyFilters, "PropertyFilters", "Property Filters", "", "", "");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellPropertyFilterCollection::~RimCellPropertyFilterCollection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellPropertyFilterCollection::setReservoirView(RimReservoirView* reservoirView)
|
||||
{
|
||||
m_reservoirView = reservoirView;
|
||||
|
||||
std::list< caf::PdmPointer< RimCellPropertyFilter > >::iterator it;
|
||||
for (it = propertyFilters.v().begin(); it != propertyFilters.v().end(); ++it)
|
||||
{
|
||||
RimCellPropertyFilter* propertyFilter = *it;
|
||||
|
||||
propertyFilter->resultDefinition->setReservoirView(m_reservoirView.p());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimReservoirView* RimCellPropertyFilterCollection::reservoirView()
|
||||
{
|
||||
CVF_ASSERT(!m_reservoirView.isNull());
|
||||
return m_reservoirView;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellPropertyFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
m_reservoirView->fieldChangedByUi(&(m_reservoirView->propertyFilterCollection), oldValue, newValue);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellPropertyFilter* RimCellPropertyFilterCollection::createAndAppendPropertyFilter()
|
||||
{
|
||||
RimCellPropertyFilter* propertyFilter = new RimCellPropertyFilter();
|
||||
|
||||
propertyFilter->resultDefinition->setReservoirView(m_reservoirView.p());
|
||||
|
||||
propertyFilter->setParentContainer(this);
|
||||
propertyFilters.v().push_back(propertyFilter);
|
||||
|
||||
propertyFilter->resultDefinition->resultVariable = m_reservoirView->cellResult->resultVariable;
|
||||
propertyFilter->resultDefinition->resultType = m_reservoirView->cellResult->resultType;
|
||||
propertyFilter->resultDefinition->loadResult();
|
||||
propertyFilter->setDefaultValues();
|
||||
|
||||
propertyFilter->name = QString("New Filter (%1)").arg(propertyFilters().size());
|
||||
|
||||
|
||||
return propertyFilter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCellPropertyFilterCollection::isCellRejected(const RigGridBase* grid, size_t timeStepIndex, size_t cellIndex) const
|
||||
{
|
||||
std::list< caf::PdmPointer< RimCellPropertyFilter > >::const_iterator it;
|
||||
if (propertyFilters.v().empty()) return false;
|
||||
|
||||
bool rejectCell = true;
|
||||
for (it = propertyFilters.v().begin(); it != propertyFilters.v().end(); ++it)
|
||||
{
|
||||
if (!(*it)->isCellRejected(grid, timeStepIndex, cellIndex))
|
||||
{
|
||||
rejectCell = false;
|
||||
}
|
||||
}
|
||||
|
||||
return rejectCell;
|
||||
}
|
||||
|
||||
cvf::CellRangeFilter::CellStateType RimCellPropertyFilterCollection::cellFilterState(const RigGridBase* grid, cvf::CellRangeFilter::CellStateType rangeCellState, size_t timeStepIndex, size_t cellIndex) const
|
||||
{
|
||||
bool included = false;
|
||||
|
||||
std::list< caf::PdmPointer< RimCellPropertyFilter > >::const_iterator it;
|
||||
for (it = propertyFilters.v().begin(); it != propertyFilters.v().end(); ++it)
|
||||
{
|
||||
RimCellPropertyFilter* propertyFilter = *it;
|
||||
CVF_ASSERT(propertyFilter);
|
||||
|
||||
if (propertyFilter->active() && propertyFilter->resultDefinition->hasResult())
|
||||
{
|
||||
// No property filter evaluation outside evaluation region
|
||||
if (propertyFilter->evaluationRegion == RimCellPropertyFilter::RANGE_FILTER_REGION && rangeCellState != cvf::CellRangeFilter::INCLUDED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool rejected = propertyFilter->isCellRejected(grid, timeStepIndex, cellIndex);
|
||||
|
||||
if (propertyFilter->filterMode == RimCellFilter::EXCLUDE)
|
||||
{
|
||||
if (rejected)
|
||||
{
|
||||
// Reject from exclude filters will always win
|
||||
return cvf::CellRangeFilter::EXCLUDED;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rejected)
|
||||
{
|
||||
included = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return included ? cvf::CellRangeFilter::INCLUDED : cvf::CellRangeFilter::EXCLUDED;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellPropertyFilterCollection::loadAndInitializePropertyFilters()
|
||||
{
|
||||
std::list< caf::PdmPointer< RimCellPropertyFilter > >::iterator it;
|
||||
for (it = propertyFilters.v().begin(); it != propertyFilters.v().end(); ++it)
|
||||
{
|
||||
RimCellPropertyFilter* propertyFilter = *it;
|
||||
|
||||
propertyFilter->setParentContainer(this);
|
||||
|
||||
propertyFilter->resultDefinition->setReservoirView(m_reservoirView.p());
|
||||
propertyFilter->resultDefinition->loadResult();
|
||||
propertyFilter->updateIconState();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellPropertyFilterCollection::initAfterRead()
|
||||
{
|
||||
loadAndInitializePropertyFilters();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellPropertyFilterCollection::remove(RimCellPropertyFilter* propertyFilter)
|
||||
{
|
||||
propertyFilters.v().remove(propertyFilter);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCellPropertyFilterCollection::hasActiveFilters() const
|
||||
{
|
||||
std::list< caf::PdmPointer< RimCellPropertyFilter > >::const_iterator it;
|
||||
for (it = propertyFilters.v().begin(); it != propertyFilters.v().end(); ++it)
|
||||
{
|
||||
if ((*it)->active() && (*it)->resultDefinition->hasResult()) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns whether any of the active property filters are based on a dynamic result
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCellPropertyFilterCollection::hasActiveDynamicFilters() const
|
||||
{
|
||||
std::list< caf::PdmPointer< RimCellPropertyFilter > >::const_iterator it;
|
||||
for (it = propertyFilters.v().begin(); it != propertyFilters.v().end(); ++it)
|
||||
{
|
||||
if ((*it)->active() && (*it)->resultDefinition->hasDynamicResult()) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimCellPropertyFilter.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCellPropertyFilterCollection : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimCellPropertyFilterCollection();
|
||||
virtual ~RimCellPropertyFilterCollection();
|
||||
|
||||
|
||||
// Fields:
|
||||
caf::PdmField< std::list< caf::PdmPointer< RimCellPropertyFilter > > > propertyFilters;
|
||||
|
||||
// Methods
|
||||
RimCellPropertyFilter* createAndAppendPropertyFilter();
|
||||
void remove(RimCellPropertyFilter* propertyFilter);
|
||||
|
||||
bool isCellRejected(const RigGridBase* grid, size_t timeStepIndex, size_t cellIndex) const;
|
||||
cvf::CellRangeFilter::CellStateType cellFilterState(const RigGridBase* grid, cvf::CellRangeFilter::CellStateType rangeCellState, size_t timeStepIndex, size_t cellIndex) const;
|
||||
|
||||
bool hasActiveFilters() const;
|
||||
bool hasActiveDynamicFilters() const;
|
||||
|
||||
void setReservoirView(RimReservoirView* reservoirView);
|
||||
RimReservoirView* reservoirView();
|
||||
|
||||
void loadAndInitializePropertyFilters();
|
||||
|
||||
// Overridden methods
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
|
||||
protected:
|
||||
// Overridden methods
|
||||
virtual void initAfterRead();
|
||||
|
||||
private:
|
||||
caf::PdmPointer<RimReservoirView> m_reservoirView;
|
||||
};
|
||||
147
ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp
Normal file
147
ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimCellRangeFilter.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimReservoirView.h"
|
||||
#include "RigReservoir.h"
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimCellRangeFilter, "CellRangeFilter");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellRangeFilter::RimCellRangeFilter()
|
||||
: m_parentContainer(NULL)
|
||||
{
|
||||
CAF_PDM_InitObject("Cell Range Filter", ":/CellFilter_Range.png", "", "");
|
||||
|
||||
CAF_PDM_InitField(&startIndexI, "StartIndexI", 1, "Start index I", "", "","");
|
||||
CAF_PDM_InitField(&cellCountI, "CellCountI", 1, "Cell Count I", "", "","");
|
||||
CAF_PDM_InitField(&startIndexJ, "StartIndexJ", 1, "Start index J", "", "","");
|
||||
CAF_PDM_InitField(&cellCountJ, "CellCountJ", 1, "Cell Count J", "", "","");
|
||||
CAF_PDM_InitField(&startIndexK, "StartIndexK", 1, "Start index K", "", "","");
|
||||
CAF_PDM_InitField(&cellCountK, "CellCountK", 1, "Cell Count K", "", "","");
|
||||
updateIconState();
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellRangeFilter::~RimCellRangeFilter()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellRangeFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (changedField != &name)
|
||||
{
|
||||
computeAndSetValidValues();
|
||||
|
||||
CVF_ASSERT(m_parentContainer);
|
||||
m_parentContainer->fieldChangedByUi(changedField, oldValue, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellRangeFilter::setParentContainer(RimCellRangeFilterCollection* parentContainer)
|
||||
{
|
||||
m_parentContainer = parentContainer;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellRangeFilter::computeAndSetValidValues()
|
||||
{
|
||||
CVF_ASSERT(m_parentContainer);
|
||||
|
||||
RigMainGrid* mainGrid = m_parentContainer->mainGrid();
|
||||
if (mainGrid && mainGrid->cellCount() > 0 )
|
||||
{
|
||||
cellCountI = cvf::Math::clamp(cellCountI.v(), 1, static_cast<int>(mainGrid->cellCountI()));
|
||||
startIndexI = cvf::Math::clamp(startIndexI.v(), 1, static_cast<int>(mainGrid->cellCountI()));
|
||||
|
||||
cellCountJ = cvf::Math::clamp(cellCountJ.v(), 1, static_cast<int>(mainGrid->cellCountJ()));
|
||||
startIndexJ = cvf::Math::clamp(startIndexJ.v(), 1, static_cast<int>(mainGrid->cellCountJ()));
|
||||
|
||||
cellCountK = cvf::Math::clamp(cellCountK.v(), 1, static_cast<int>(mainGrid->cellCountK()));
|
||||
startIndexK = cvf::Math::clamp(startIndexK.v(), 1, static_cast<int>(mainGrid->cellCountK()));
|
||||
}
|
||||
this->updateIconState();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellRangeFilter::setDefaultValues()
|
||||
{
|
||||
CVF_ASSERT(m_parentContainer);
|
||||
|
||||
RigMainGrid* mainGrid = m_parentContainer->mainGrid();
|
||||
if (mainGrid)
|
||||
{
|
||||
cvf::Vec3st min, max;
|
||||
mainGrid->activeCellsBoundingBox(min, max);
|
||||
|
||||
// Adjust to Eclipse indexing
|
||||
min.x() = min.x() + 1;
|
||||
min.y() = min.y() + 1;
|
||||
min.z() = min.z() + 1;
|
||||
|
||||
max.x() = max.x() + 1;
|
||||
max.y() = max.y() + 1;
|
||||
max.z() = max.z() + 1;
|
||||
|
||||
startIndexI = min.x();
|
||||
startIndexI.setUiName(QString("I Start (%1)").arg(min.x()));
|
||||
|
||||
startIndexJ = min.y();
|
||||
startIndexJ.setUiName(QString("J Start (%1)").arg(min.y()));
|
||||
|
||||
startIndexK = min.z();
|
||||
startIndexK.setUiName(QString("K Start (%1)").arg(min.z()));
|
||||
|
||||
cellCountI = max.x() - min.x() + 1;
|
||||
cellCountI.setUiName(QString(" Width (%1)").arg(max.x() - min.x() + 1));
|
||||
|
||||
cellCountJ = max.y() - min.y() + 1;
|
||||
cellCountJ.setUiName(QString(" Width (%1)").arg(max.y() - min.y() + 1));
|
||||
|
||||
cellCountK = max.z() - min.z() + 1;
|
||||
cellCountK.setUiName(QString(" Width (%1)").arg(max.z() - min.z() + 1));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellRangeFilterCollection* RimCellRangeFilter::parentContainer()
|
||||
{
|
||||
return m_parentContainer;
|
||||
}
|
||||
|
||||
66
ApplicationCode/ProjectDataModel/RimCellRangeFilter.h
Normal file
66
ApplicationCode/ProjectDataModel/RimCellRangeFilter.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include "RimCellFilter.h"
|
||||
|
||||
class RimReservoirView;
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class CellRangeFilter;
|
||||
}
|
||||
|
||||
class RimCellRangeFilterCollection;
|
||||
class RigMainGrid;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCellRangeFilter : public RimCellFilter
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimCellRangeFilter();
|
||||
virtual ~RimCellRangeFilter();
|
||||
|
||||
void setParentContainer(RimCellRangeFilterCollection* parentContainer);
|
||||
RimCellRangeFilterCollection* parentContainer();
|
||||
void setDefaultValues();
|
||||
|
||||
caf::PdmField<int> startIndexI; // Eclipse indexing, first index is 1
|
||||
caf::PdmField<int> startIndexJ; // Eclipse indexing, first index is 1
|
||||
caf::PdmField<int> startIndexK; // Eclipse indexing, first index is 1
|
||||
caf::PdmField<int> cellCountI;
|
||||
caf::PdmField<int> cellCountJ;
|
||||
caf::PdmField<int> cellCountK;
|
||||
|
||||
void computeAndSetValidValues();
|
||||
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
|
||||
private:
|
||||
RimCellRangeFilterCollection* m_parentContainer;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
|
||||
#include "RimReservoirView.h"
|
||||
#include "RigReservoir.h"
|
||||
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimCellRangeFilterCollection, "CellRangeFilterCollection");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellRangeFilterCollection::RimCellRangeFilterCollection()
|
||||
{
|
||||
CAF_PDM_InitObject("Cell Range Filters", ":/CellFilter_Range.png", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&rangeFilters, "RangeFilters", "Range Filters", "", "", "");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellRangeFilterCollection::~RimCellRangeFilterCollection()
|
||||
{
|
||||
std::list< caf::PdmPointer< RimCellRangeFilter > >::const_iterator it;
|
||||
for (it = rangeFilters.v().begin(); it != rangeFilters.v().end(); ++it)
|
||||
{
|
||||
delete it->p();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellRangeFilterCollection::setReservoirView(RimReservoirView* reservoirView)
|
||||
{
|
||||
m_reservoirView = reservoirView;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// RimCellRangeFilter is using Eclipse 1-based indexing, adjust filter values before
|
||||
// populating cvf::CellRangeFilter (which is 0-based)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellRangeFilterCollection::compoundCellRangeFilter(cvf::CellRangeFilter* cellRangeFilter) const
|
||||
{
|
||||
CVF_ASSERT(cellRangeFilter);
|
||||
|
||||
std::list< caf::PdmPointer<RimCellRangeFilter> >::const_iterator it;
|
||||
for (it = rangeFilters.v().begin(); it != rangeFilters.v().end(); it++)
|
||||
{
|
||||
RimCellRangeFilter* rangeFilter = *it;
|
||||
|
||||
if (rangeFilter && rangeFilter->active)
|
||||
{
|
||||
if (rangeFilter->filterMode == RimCellFilter::INCLUDE)
|
||||
{
|
||||
cellRangeFilter->addCellIncludeRange(
|
||||
rangeFilter->startIndexI - 1,
|
||||
rangeFilter->startIndexJ - 1,
|
||||
rangeFilter->startIndexK - 1,
|
||||
rangeFilter->startIndexI - 1 + rangeFilter->cellCountI,
|
||||
rangeFilter->startIndexJ - 1 + rangeFilter->cellCountJ,
|
||||
rangeFilter->startIndexK - 1 + rangeFilter->cellCountK);
|
||||
}
|
||||
else
|
||||
{
|
||||
cellRangeFilter->addCellExcludeRange(
|
||||
rangeFilter->startIndexI - 1,
|
||||
rangeFilter->startIndexJ - 1,
|
||||
rangeFilter->startIndexK - 1,
|
||||
rangeFilter->startIndexI - 1 + rangeFilter->cellCountI,
|
||||
rangeFilter->startIndexJ - 1 + rangeFilter->cellCountJ,
|
||||
rangeFilter->startIndexK - 1 + rangeFilter->cellCountK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCellRangeFilterCollection::hasIncludeFilter() const
|
||||
{
|
||||
std::list< caf::PdmPointer<RimCellRangeFilter> >::const_iterator it;
|
||||
for (it = rangeFilters.v().begin(); it != rangeFilters.v().end(); it++)
|
||||
{
|
||||
RimCellRangeFilter* rangeFilter = *it;
|
||||
if (rangeFilter->active && rangeFilter->filterMode() == RimCellFilter::INCLUDE)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigMainGrid* RimCellRangeFilterCollection::mainGrid() const
|
||||
{
|
||||
if (m_reservoirView &&
|
||||
m_reservoirView->eclipseCase() &&
|
||||
m_reservoirView->eclipseCase()->reservoirData() &&
|
||||
m_reservoirView->eclipseCase()->reservoirData()->mainGrid())
|
||||
{
|
||||
|
||||
RigMainGrid* mainGrid = m_reservoirView->eclipseCase()->reservoirData()->mainGrid();
|
||||
|
||||
return mainGrid;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellRangeFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
// cvf::Trace::show("RimCellRangeFilterCollection::fieldChangedByUi");
|
||||
|
||||
m_reservoirView->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED);
|
||||
m_reservoirView->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED_INACTIVE);
|
||||
|
||||
if (m_reservoirView) m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellRangeFilter* RimCellRangeFilterCollection::createAndAppendRangeFilter()
|
||||
{
|
||||
RimCellRangeFilter* rangeFilter = new RimCellRangeFilter();
|
||||
rangeFilter->setParentContainer(this);
|
||||
rangeFilter->setDefaultValues();
|
||||
|
||||
rangeFilters.v().push_back(rangeFilter);
|
||||
|
||||
rangeFilter->name = QString("New Filter (%1)").arg(rangeFilters().size());
|
||||
|
||||
return rangeFilter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimReservoirView* RimCellRangeFilterCollection::reservoirView()
|
||||
{
|
||||
return m_reservoirView;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellRangeFilterCollection::initAfterRead()
|
||||
{
|
||||
std::list< caf::PdmPointer<RimCellRangeFilter> >::iterator it;
|
||||
for (it = rangeFilters.v().begin(); it != rangeFilters.v().end(); it++)
|
||||
{
|
||||
RimCellRangeFilter* rangeFilter = *it;
|
||||
rangeFilter->setParentContainer(this);
|
||||
rangeFilter->updateIconState();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellRangeFilterCollection::remove(RimCellRangeFilter* rangeFilter)
|
||||
{
|
||||
rangeFilters.v().remove(rangeFilter);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCellRangeFilterCollection::hasActiveFilters() const
|
||||
{
|
||||
std::list< caf::PdmPointer< RimCellRangeFilter > >::const_iterator it;
|
||||
for (it = rangeFilters.v().begin(); it != rangeFilters.v().end(); ++it)
|
||||
{
|
||||
if ((*it)->active()) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimCellRangeFilter.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCellRangeFilterCollection : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimCellRangeFilterCollection();
|
||||
virtual ~RimCellRangeFilterCollection();
|
||||
|
||||
// Fields
|
||||
caf::PdmField< std::list< caf::PdmPointer< RimCellRangeFilter > > > rangeFilters;
|
||||
|
||||
// Methods
|
||||
RimCellRangeFilter* createAndAppendRangeFilter();
|
||||
void remove(RimCellRangeFilter* rangeFilter);
|
||||
|
||||
bool hasIncludeFilter() const;
|
||||
void compoundCellRangeFilter(cvf::CellRangeFilter* cellRangeFilter) const;
|
||||
bool hasActiveFilters() const;
|
||||
|
||||
void setReservoirView(RimReservoirView* reservoirView);
|
||||
RimReservoirView* reservoirView();
|
||||
RigMainGrid* mainGrid() const;
|
||||
|
||||
// Overridden methods
|
||||
virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue );
|
||||
|
||||
protected:
|
||||
// Overridden methods
|
||||
virtual void initAfterRead();
|
||||
|
||||
private:
|
||||
RimReservoirView* m_reservoirView;
|
||||
};
|
||||
38
ApplicationCode/ProjectDataModel/RimDefines.cpp
Normal file
38
ApplicationCode/ProjectDataModel/RimDefines.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimDefines.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include "RifReaderInterface.h"
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void caf::AppEnum< RimDefines::ResultCatType >::setUp()
|
||||
{
|
||||
addItem(RimDefines::DYNAMIC_NATIVE, "DYNAMIC_NATIVE", "Dynamic");
|
||||
addItem(RimDefines::STATIC_NATIVE, "STATIC_NATIVE", "Static");
|
||||
addItem(RimDefines::GENERATED, "Generated", "Generated");
|
||||
|
||||
setDefault(RimDefines::DYNAMIC_NATIVE);
|
||||
}
|
||||
}
|
||||
|
||||
39
ApplicationCode/ProjectDataModel/RimDefines.h
Normal file
39
ApplicationCode/ProjectDataModel/RimDefines.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
#include <QList>
|
||||
|
||||
class RifReaderInterface;
|
||||
|
||||
|
||||
class RimDefines
|
||||
{
|
||||
|
||||
public:
|
||||
enum ResultCatType
|
||||
{
|
||||
DYNAMIC_NATIVE,
|
||||
STATIC_NATIVE,
|
||||
GENERATED
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
416
ApplicationCode/ProjectDataModel/RimLegendConfig.cpp
Normal file
416
ApplicationCode/ProjectDataModel/RimLegendConfig.cpp
Normal file
@@ -0,0 +1,416 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimLegendConfig.h"
|
||||
#include "RimReservoirView.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimLegendConfig, "Legend");
|
||||
|
||||
namespace caf {
|
||||
template<>
|
||||
void AppEnum<RimLegendConfig::RangeModeType>::setUp()
|
||||
{
|
||||
addItem(RimLegendConfig::AUTOMATIC_ALLTIMESTEPS, "AUTOMATIC_ALLTIMESTEPS", "Global range");
|
||||
addItem(RimLegendConfig::AUTOMATIC_CURRENT_TIMESTEP,"AUTOMATIC_CURRENT_TIMESTEP", "Local range");
|
||||
addItem(RimLegendConfig::USER_DEFINED, "USER_DEFINED_MAX_MIN", "User defined range");
|
||||
setDefault(RimLegendConfig::AUTOMATIC_ALLTIMESTEPS);
|
||||
}
|
||||
}
|
||||
|
||||
namespace caf {
|
||||
template<>
|
||||
void RimLegendConfig::ColorRangeEnum::setUp()
|
||||
{
|
||||
addItem(RimLegendConfig::NORMAL, "NORMAL", "Full color, Red on top");
|
||||
addItem(RimLegendConfig::OPPOSITE_NORMAL,"OPPOSITE_NORMAL", "Full color, Blue on top");
|
||||
addItem(RimLegendConfig::WHITE_PINK, "WHITE_PIMK", "White to pink");
|
||||
addItem(RimLegendConfig::PINK_WHITE, "PINK_WHITE", "Pink to white");
|
||||
addItem(RimLegendConfig::WHITE_BLACK, "WHITE_BLACK", "White to black");
|
||||
addItem(RimLegendConfig::BLACK_WHITE, "BLACK_WHITE", "Black to white");
|
||||
setDefault(RimLegendConfig::NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
namespace caf {
|
||||
template<>
|
||||
void RimLegendConfig::MappingEnum::setUp()
|
||||
{
|
||||
addItem(RimLegendConfig::LINEAR_DISCRETE, "LinearDiscrete", "Discrete Linear");
|
||||
addItem(RimLegendConfig::LINEAR_CONTINUOUS, "LinearContinuous", "Continuous Linear");
|
||||
addItem(RimLegendConfig::LOG10_CONTINUOUS, "Log10Continuous", "Continuous Logarithmic");
|
||||
setDefault(RimLegendConfig::LINEAR_CONTINUOUS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimLegendConfig::RimLegendConfig()
|
||||
: m_globalAutoMax(cvf::UNDEFINED_DOUBLE),
|
||||
m_globalAutoMin(cvf::UNDEFINED_DOUBLE),
|
||||
m_localAutoMax(cvf::UNDEFINED_DOUBLE),
|
||||
m_localAutoMin(cvf::UNDEFINED_DOUBLE)
|
||||
{
|
||||
CAF_PDM_InitObject("Legend Definition", ":/Legend.png", "", "");
|
||||
CAF_PDM_InitField(&m_numLevels, "NumberOfLevels", 8, "Number of levels", "", "","");
|
||||
CAF_PDM_InitField(&m_precision, "Precision", 6, "Precision", "", "","");
|
||||
CAF_PDM_InitField(&m_colorRangeMode, "ColorRangeMode", ColorRangeEnum(NORMAL) , "Color range", "", "", "");
|
||||
CAF_PDM_InitField(&m_mappingMode, "MappingMode", MappingEnum(LINEAR_CONTINUOUS) , "Mapping", "", "", "");
|
||||
CAF_PDM_InitField(&m_rangeMode, "RangeType", caf::AppEnum<RimLegendConfig::RangeModeType>(AUTOMATIC_ALLTIMESTEPS), "Legend range type", "", "Switches between automatic and user defined range on the legend", "");
|
||||
CAF_PDM_InitField(&m_userDefinedMaxValue, "UserDefinedMax", 1.0, "Max", "", "Min value of the legend", "");
|
||||
CAF_PDM_InitField(&m_userDefinedMinValue, "UserDefinedMin", 0.0, "Min", "", "Max value of the legend", "");
|
||||
CAF_PDM_InitField(&resultVariableName, "ResultVariableUsage", QString(""), "", "", "", "");
|
||||
resultVariableName.setHidden(true);
|
||||
|
||||
m_linDiscreteScalarMapper = new cvf::ScalarMapperUniformLevels;
|
||||
m_linDiscreteScalarMapper->setTextureSize(1024);
|
||||
|
||||
m_logSmoothScalarMapper = new cvf::ScalarMapperContinuousLog;
|
||||
m_linSmoothScalarMapper = new cvf::ScalarMapperContinuousLinear;
|
||||
|
||||
m_currentScalarMapper = m_linDiscreteScalarMapper;
|
||||
|
||||
|
||||
cvf::FixedAtlasFont* font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD);
|
||||
m_legend = new cvf::OverlayColorLegend(font);
|
||||
m_position = cvf::Vec2ui(20, 50);
|
||||
|
||||
updateFieldVisibility();
|
||||
updateLegend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimLegendConfig::~RimLegendConfig()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimLegendConfig::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (changedField == &m_numLevels)
|
||||
{
|
||||
int upperLimit = std::numeric_limits<int>::max();
|
||||
m_numLevels = cvf::Math::clamp(m_numLevels.v(), 1, upperLimit);
|
||||
}
|
||||
else if (changedField == &m_rangeMode)
|
||||
{
|
||||
if (m_rangeMode == USER_DEFINED)
|
||||
{
|
||||
if (m_userDefinedMaxValue == m_userDefinedMaxValue.defaultValue() && m_globalAutoMax != cvf::UNDEFINED_DOUBLE)
|
||||
{
|
||||
m_userDefinedMaxValue = adjust(m_globalAutoMax, m_precision);
|
||||
}
|
||||
if (m_userDefinedMinValue == m_userDefinedMinValue.defaultValue() && m_globalAutoMin != cvf::UNDEFINED_DOUBLE)
|
||||
{
|
||||
m_userDefinedMinValue = adjust(m_globalAutoMin, m_precision);
|
||||
}
|
||||
}
|
||||
|
||||
updateFieldVisibility();
|
||||
}
|
||||
|
||||
updateLegend();
|
||||
|
||||
if (m_reservoirView) m_reservoirView->updateCurrentTimeStepAndRedraw();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimLegendConfig::updateLegend()
|
||||
{
|
||||
double adjustedMin = cvf::UNDEFINED_DOUBLE;
|
||||
double adjustedMax = cvf::UNDEFINED_DOUBLE;
|
||||
|
||||
if (m_rangeMode == AUTOMATIC_ALLTIMESTEPS)
|
||||
{
|
||||
adjustedMin = adjust(m_globalAutoMin, m_precision);
|
||||
adjustedMax = adjust(m_globalAutoMax, m_precision);
|
||||
}
|
||||
else if (m_rangeMode == AUTOMATIC_CURRENT_TIMESTEP)
|
||||
{
|
||||
adjustedMin = adjust(m_localAutoMin, m_precision);
|
||||
adjustedMax = adjust(m_localAutoMax, m_precision);
|
||||
}
|
||||
else
|
||||
{
|
||||
adjustedMin = adjust(m_userDefinedMinValue, m_precision);
|
||||
adjustedMax = adjust(m_userDefinedMaxValue, m_precision);
|
||||
}
|
||||
|
||||
m_linDiscreteScalarMapper->setRange(adjustedMin, adjustedMax);
|
||||
m_logSmoothScalarMapper->setRange(adjustedMin, adjustedMax);
|
||||
m_linSmoothScalarMapper->setRange(adjustedMin, adjustedMax);
|
||||
|
||||
cvf::Color3ubArray legendColors;
|
||||
switch (m_colorRangeMode())
|
||||
{
|
||||
case NORMAL:
|
||||
{
|
||||
legendColors.reserve(5);
|
||||
legendColors.add(cvf::Color3ub( 0, 0, 255));
|
||||
legendColors.add(cvf::Color3ub( 0, 255, 255));
|
||||
legendColors.add(cvf::Color3ub( 0, 255, 0));
|
||||
legendColors.add(cvf::Color3ub(255, 255, 0));
|
||||
legendColors.add(cvf::Color3ub(255, 0, 0));
|
||||
|
||||
m_linDiscreteScalarMapper->setColors(cvf::ScalarMapper::NORMAL, m_numLevels);
|
||||
}
|
||||
break;
|
||||
case OPPOSITE_NORMAL:
|
||||
{
|
||||
legendColors.reserve(5);
|
||||
legendColors.add(cvf::Color3ub(255, 0, 0));
|
||||
legendColors.add(cvf::Color3ub(255, 255, 0));
|
||||
legendColors.add(cvf::Color3ub( 0, 255, 0));
|
||||
legendColors.add(cvf::Color3ub( 0, 255, 255));
|
||||
legendColors.add(cvf::Color3ub( 0, 0, 255));
|
||||
|
||||
m_linDiscreteScalarMapper->setColors(legendColors); // Todo: Change legend type to new
|
||||
}
|
||||
break; case BLACK_WHITE:
|
||||
case WHITE_BLACK:
|
||||
{
|
||||
legendColors.reserve(2);
|
||||
if (m_colorRangeMode() == BLACK_WHITE)
|
||||
{
|
||||
legendColors.add(cvf::Color3ub::BLACK);
|
||||
legendColors.add(cvf::Color3ub::WHITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
legendColors.add(cvf::Color3ub::WHITE);
|
||||
legendColors.add(cvf::Color3ub::BLACK);
|
||||
}
|
||||
cvf::ref<cvf::Color3ubArray> interpolated = interpolateColorArray(legendColors, m_numLevels);
|
||||
m_linDiscreteScalarMapper->setColors(*(interpolated.p()));
|
||||
}
|
||||
break;
|
||||
case PINK_WHITE:
|
||||
case WHITE_PINK:
|
||||
{
|
||||
legendColors.reserve(2);
|
||||
if (m_colorRangeMode() == PINK_WHITE)
|
||||
{
|
||||
legendColors.add(cvf::Color3ub::DEEP_PINK);
|
||||
legendColors.add(cvf::Color3ub::WHITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
legendColors.add(cvf::Color3ub::WHITE);
|
||||
legendColors.add(cvf::Color3ub::DEEP_PINK);
|
||||
}
|
||||
cvf::ref<cvf::Color3ubArray> interpolated = interpolateColorArray(legendColors, m_numLevels);
|
||||
m_linDiscreteScalarMapper->setColors(*(interpolated.p()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_logSmoothScalarMapper->setColors(legendColors);
|
||||
m_linSmoothScalarMapper->setColors(legendColors);
|
||||
|
||||
m_logSmoothScalarMapper->setMajorLevelCount(m_numLevels, true);
|
||||
m_linSmoothScalarMapper->setMajorLevelCount(m_numLevels, true);
|
||||
|
||||
switch(m_mappingMode())
|
||||
{
|
||||
case LINEAR_DISCRETE:
|
||||
m_currentScalarMapper = m_linDiscreteScalarMapper.p();
|
||||
break;
|
||||
case LINEAR_CONTINUOUS:
|
||||
m_currentScalarMapper = m_linSmoothScalarMapper.p();
|
||||
break;
|
||||
case LOG10_CONTINUOUS:
|
||||
m_currentScalarMapper = m_logSmoothScalarMapper.p();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_legend->setScalarMapper(m_currentScalarMapper.p());
|
||||
|
||||
|
||||
if (m_globalAutoMax != cvf::UNDEFINED_DOUBLE )
|
||||
{
|
||||
m_userDefinedMaxValue.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax, 'g', m_precision) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_userDefinedMaxValue.setUiName(QString());
|
||||
}
|
||||
|
||||
if (m_globalAutoMin != cvf::UNDEFINED_DOUBLE )
|
||||
{
|
||||
m_userDefinedMinValue.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin, 'g', m_precision) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_userDefinedMinValue.setUiName(QString());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimLegendConfig::setAutomaticRanges(double globalMin, double globalMax, double localMin, double localMax)
|
||||
{
|
||||
m_globalAutoMin = adjust(globalMin, m_precision);
|
||||
m_globalAutoMax = adjust(globalMax, m_precision);
|
||||
|
||||
m_localAutoMin = adjust(localMin, m_precision);
|
||||
m_localAutoMax = adjust(localMax, m_precision);
|
||||
|
||||
updateLegend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimLegendConfig::initAfterRead()
|
||||
{
|
||||
updateFieldVisibility();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimLegendConfig::updateFieldVisibility()
|
||||
{
|
||||
if (m_rangeMode == USER_DEFINED)
|
||||
{
|
||||
m_userDefinedMaxValue.setHidden(false);
|
||||
m_userDefinedMinValue.setHidden(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_userDefinedMaxValue.setHidden(true);
|
||||
m_userDefinedMinValue.setHidden(true);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimLegendConfig::setColorRangeMode(ColorRangesType colorMode)
|
||||
{
|
||||
m_colorRangeMode = colorMode;
|
||||
updateLegend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::Color3ubArray> RimLegendConfig::interpolateColorArray(const cvf::Color3ubArray& colorArray, cvf::uint targetColorCount)
|
||||
{
|
||||
uint inputColorCount = static_cast<uint>(colorArray.size());
|
||||
CVF_ASSERT(inputColorCount > 1);
|
||||
CVF_ASSERT(targetColorCount > 1);
|
||||
|
||||
cvf::ref<cvf::Color3ubArray> colors = new cvf::Color3ubArray;
|
||||
colors->reserve(targetColorCount);
|
||||
|
||||
const uint inputLevelCount = inputColorCount - 1;
|
||||
const uint outputLevelCount = targetColorCount - 1;
|
||||
|
||||
uint outputLevelIdx;
|
||||
for (outputLevelIdx = 0; outputLevelIdx < outputLevelCount; outputLevelIdx++)
|
||||
{
|
||||
double dblInputLevelIndex = inputLevelCount * (outputLevelIdx / static_cast<double>(outputLevelCount));
|
||||
|
||||
const uint inputLevelIndex = static_cast<uint>(dblInputLevelIndex);
|
||||
CVF_ASSERT(inputLevelIndex < inputLevelCount);
|
||||
|
||||
double t = dblInputLevelIndex - inputLevelIndex;
|
||||
CVF_ASSERT(t >= 0 && t <= 1.0);
|
||||
|
||||
cvf::Color3ub c1 = colorArray[inputLevelIndex];
|
||||
cvf::Color3ub c2 = colorArray[inputLevelIndex + 1];
|
||||
|
||||
int r = static_cast<int>(c1.r() + t*(c2.r() - c1.r()) + 0.5);
|
||||
int g = static_cast<int>(c1.g() + t*(c2.g() - c1.g()) + 0.5);
|
||||
int b = static_cast<int>(c1.b() + t*(c2.b() - c1.b()) + 0.5);
|
||||
|
||||
r = cvf::Math::clamp(r, 0, 255);
|
||||
g = cvf::Math::clamp(g, 0, 255);
|
||||
b = cvf::Math::clamp(b, 0, 255);
|
||||
|
||||
cvf::Color3ub col((cvf::ubyte)r, (cvf::ubyte)g, (cvf::ubyte)b);
|
||||
colors->add(col);
|
||||
}
|
||||
|
||||
colors->add(colorArray[colorArray.size() - 1]);
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimLegendConfig::setPosition(cvf::Vec2ui position)
|
||||
{
|
||||
m_position = position;
|
||||
updateLegend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimLegendConfig::recreateLegend()
|
||||
{
|
||||
// Due to possible visualization bug, we need to recreate the legend if the last viewer
|
||||
// has been removed, (and thus the opengl resources has been deleted) The text in
|
||||
// the legend disappeared because of this, so workaround: recreate the legend when needed:
|
||||
|
||||
cvf::FixedAtlasFont* font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD);
|
||||
m_legend = new cvf::OverlayColorLegend(font);
|
||||
|
||||
updateLegend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Adjust double value to given precision
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimLegendConfig::adjust(double domainValue, double precision)
|
||||
{
|
||||
double decadeValue = cvf::Math::abs(domainValue);
|
||||
double threshold = 1e-6;
|
||||
if (decadeValue < threshold)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
double logDecValue = log10(decadeValue);
|
||||
logDecValue = cvf::Math::ceil(logDecValue);
|
||||
|
||||
double factor = pow(10.0, precision - logDecValue);
|
||||
|
||||
double tmp = domainValue * factor;
|
||||
double integerPart;
|
||||
modf(tmp, &integerPart);
|
||||
|
||||
double newDomainValue = integerPart / factor;
|
||||
|
||||
return newDomainValue;
|
||||
}
|
||||
|
||||
116
ApplicationCode/ProjectDataModel/RimLegendConfig.h
Normal file
116
ApplicationCode/ProjectDataModel/RimLegendConfig.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include "cvfScalarMapperContinuousLog.h"
|
||||
#include "cvfScalarMapperContinuousLinear.h"
|
||||
#include "cvfOverlayColorLegend.h"
|
||||
#include "cvfScalarMapperUniformLevels.h"
|
||||
|
||||
class RimReservoirView;
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimLegendConfig: public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimLegendConfig();
|
||||
virtual ~RimLegendConfig();
|
||||
|
||||
void setReservoirView(RimReservoirView* ownerReservoirView) {m_reservoirView = ownerReservoirView; }
|
||||
|
||||
caf::PdmField<QString> resultVariableName; // Used internally to describe the variable this legend setup is used for
|
||||
|
||||
enum RangeModeType
|
||||
{
|
||||
AUTOMATIC_ALLTIMESTEPS,
|
||||
AUTOMATIC_CURRENT_TIMESTEP,
|
||||
USER_DEFINED
|
||||
};
|
||||
|
||||
enum ColorRangesType
|
||||
{
|
||||
NORMAL,
|
||||
OPPOSITE_NORMAL,
|
||||
WHITE_PINK,
|
||||
PINK_WHITE,
|
||||
WHITE_BLACK,
|
||||
BLACK_WHITE
|
||||
};
|
||||
|
||||
typedef caf::AppEnum<ColorRangesType> ColorRangeEnum;
|
||||
|
||||
enum MappingType
|
||||
{
|
||||
LINEAR_DISCRETE,
|
||||
LINEAR_CONTINUOUS,
|
||||
LOG10_CONTINUOUS
|
||||
};
|
||||
|
||||
typedef caf::AppEnum<MappingType> MappingEnum;
|
||||
void recreateLegend();
|
||||
void setColorRangeMode(ColorRangesType colorMode);
|
||||
void setAutomaticRanges(double globalMin, double globalMax, double localMin, double localMax);
|
||||
void setPosition(cvf::Vec2ui position);
|
||||
|
||||
cvf::ScalarMapper* scalarMapper() { return m_currentScalarMapper.p(); }
|
||||
cvf::OverlayColorLegend* legend() { return m_legend.p(); }
|
||||
void updateLegend();
|
||||
|
||||
protected:
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
virtual void initAfterRead();
|
||||
private:
|
||||
void updateFieldVisibility();
|
||||
cvf::ref<cvf::Color3ubArray> interpolateColorArray(const cvf::Color3ubArray& colorArray, cvf::uint targetColorCount);
|
||||
double adjust(double value, double precision);
|
||||
|
||||
private:
|
||||
caf::PdmPointer<RimReservoirView> m_reservoirView;
|
||||
|
||||
cvf::ref<cvf::ScalarMapperUniformLevels> m_linDiscreteScalarMapper;
|
||||
cvf::ref<cvf::ScalarMapperContinuousLog> m_logSmoothScalarMapper;
|
||||
cvf::ref<cvf::ScalarMapperContinuousLinear> m_linSmoothScalarMapper;
|
||||
cvf::ref<cvf::LegendScalarMapper> m_currentScalarMapper;
|
||||
|
||||
cvf::ref<cvf::OverlayColorLegend> m_legend;
|
||||
|
||||
double m_globalAutoMax;
|
||||
double m_globalAutoMin;
|
||||
double m_localAutoMax;
|
||||
double m_localAutoMin;
|
||||
|
||||
cvf::Vec2ui m_position;
|
||||
|
||||
// Fields
|
||||
caf::PdmField<int> m_numLevels;
|
||||
caf::PdmField<int> m_precision;
|
||||
caf::PdmField<caf::AppEnum<RangeModeType> > m_rangeMode;
|
||||
caf::PdmField<double> m_userDefinedMaxValue;
|
||||
caf::PdmField<double> m_userDefinedMinValue;
|
||||
caf::PdmField<caf::AppEnum<ColorRangesType> > m_colorRangeMode;
|
||||
caf::PdmField<caf::AppEnum<MappingType> > m_mappingMode;
|
||||
|
||||
};
|
||||
115
ApplicationCode/ProjectDataModel/RimProject.cpp
Normal file
115
ApplicationCode/ProjectDataModel/RimProject.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimProject.h"
|
||||
#include "RIApplication.h"
|
||||
#include "RIVersionInfo.h"
|
||||
#include "RimScriptCollection.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimProject, "ResInsightProject");
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimProject::RimProject(void)
|
||||
{
|
||||
CAF_PDM_InitFieldNoDefault(&m_projectFileVersionString, "ProjectFileVersionString", "", "", "", "");
|
||||
m_projectFileVersionString.setHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&reservoirs, "Reservoirs", "", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&scriptCollection, "ScriptCollection", "Scripts", ":/Default.png", "", "");
|
||||
|
||||
scriptCollection = new RimScriptCollection();
|
||||
scriptCollection->directory.setHidden(true);
|
||||
|
||||
initAfterRead();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimProject::~RimProject(void)
|
||||
{
|
||||
if (scriptCollection()) delete scriptCollection();
|
||||
|
||||
reservoirs.deleteChildren();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimProject::close()
|
||||
{
|
||||
reservoirs.deleteChildren();
|
||||
|
||||
fileName = "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimProject::initAfterRead()
|
||||
{
|
||||
//
|
||||
// TODO : Must store content of scripts in project file and notify user if stored content is different from disk on execute and edit
|
||||
//
|
||||
RIApplication* app = RIApplication::instance();
|
||||
QString scriptDirectory = app->scriptDirectory();
|
||||
|
||||
this->setUserScriptPath(scriptDirectory);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimProject::setupBeforeSave()
|
||||
{
|
||||
m_projectFileVersionString = STRPRODUCTVER;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimProject::setUserScriptPath(const QString& scriptDirectory)
|
||||
{
|
||||
scriptCollection->calcScripts().deleteChildren();
|
||||
scriptCollection->subDirectories().deleteChildren();
|
||||
|
||||
|
||||
QDir dir(scriptDirectory);
|
||||
if (!scriptDirectory.isEmpty() && dir.exists())
|
||||
{
|
||||
RimScriptCollection* sharedScriptLocation = new RimScriptCollection;
|
||||
sharedScriptLocation->directory = scriptDirectory;
|
||||
sharedScriptLocation->setUiName(dir.dirName());
|
||||
|
||||
sharedScriptLocation->readContentFromDisc();
|
||||
|
||||
scriptCollection->subDirectories.push_back(sharedScriptLocation);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimProject::projectFileVersionString() const
|
||||
{
|
||||
return m_projectFileVersionString;
|
||||
}
|
||||
55
ApplicationCode/ProjectDataModel/RimProject.h
Normal file
55
ApplicationCode/ProjectDataModel/RimProject.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmDocument.h"
|
||||
#include "RimScriptCollection.h"
|
||||
|
||||
class RimReservoir;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimProject : public caf::PdmDocument
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
caf::PdmPointersField<RimReservoir*> reservoirs;
|
||||
caf::PdmField<RimScriptCollection*> scriptCollection;
|
||||
|
||||
void setUserScriptPath(const QString& path);
|
||||
//void updateProjectScriptPath();
|
||||
|
||||
QString projectFileVersionString() const;
|
||||
|
||||
RimProject(void);
|
||||
virtual ~RimProject(void);
|
||||
|
||||
void close();
|
||||
|
||||
protected:
|
||||
// Overridden methods
|
||||
virtual void initAfterRead();
|
||||
virtual void setupBeforeSave();
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_projectFileVersionString;
|
||||
};
|
||||
276
ApplicationCode/ProjectDataModel/RimReservoir.cpp
Normal file
276
ApplicationCode/ProjectDataModel/RimReservoir.cpp
Normal file
@@ -0,0 +1,276 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RifReaderInterfaceEcl.h"
|
||||
#include "RimReservoir.h"
|
||||
#include "RigReservoir.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigReservoirCellResults.h"
|
||||
|
||||
#include "RimWell.h"
|
||||
#include "RimWellCollection.h"
|
||||
#include "RimReservoirView.h"
|
||||
|
||||
#include "cvfAssert.h"
|
||||
|
||||
#include <QString>
|
||||
#include "RifReaderInterfaceMock.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimReservoir, "EclipseCase");
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimReservoir::RimReservoir()
|
||||
{
|
||||
m_rigReservoir = NULL;
|
||||
m_fileInterface = NULL;
|
||||
|
||||
CAF_PDM_InitObject("Reservoir", ":/AppLogo48x48.png", "", "");
|
||||
CAF_PDM_InitField(&caseName, "CaseName", QString(), "Case name", "", "" ,"");
|
||||
CAF_PDM_InitField(&caseDirectory, "CaseFolder", QString(), "Directory", "", "" ,"");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&reservoirViews, "ReservoirViews", "", "", "", "");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimReservoir::RimReservoir(RigReservoir* reservoir)
|
||||
{
|
||||
m_rigReservoir = reservoir;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigReservoir* RimReservoir::reservoirData()
|
||||
{
|
||||
return m_rigReservoir.p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RigReservoir* RimReservoir::reservoirData() const
|
||||
{
|
||||
return m_rigReservoir.p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderInterface* RimReservoir::fileInterface()
|
||||
{
|
||||
return m_fileInterface.p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RifReaderInterface* RimReservoir::fileInterface() const
|
||||
{
|
||||
return m_fileInterface.p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimReservoir::openEclipseGridFile()
|
||||
{
|
||||
// Early exit if reservoir data is created
|
||||
if (m_rigReservoir.notNull()) return true;
|
||||
|
||||
if (caseName().contains("Mock Debug Model"))
|
||||
{
|
||||
this->createMockModel(this->caseName());
|
||||
}
|
||||
else
|
||||
{
|
||||
QString fullCaseName = caseName + ".EGRID";
|
||||
|
||||
QDir dir(caseDirectory.v());
|
||||
if (!dir.exists(fullCaseName))
|
||||
{
|
||||
fullCaseName = caseName + ".GRID";
|
||||
if (!dir.exists(fullCaseName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString fname = dir.absoluteFilePath(fullCaseName);
|
||||
|
||||
RigReservoir* reservoir = new RigReservoir;
|
||||
m_fileInterface = new RifReaderInterfaceECL;
|
||||
if (!m_fileInterface->open(fname, reservoir))
|
||||
{
|
||||
delete reservoir;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_rigReservoir = reservoir;
|
||||
}
|
||||
|
||||
CVF_ASSERT(m_rigReservoir.notNull());
|
||||
CVF_ASSERT(m_fileInterface.notNull());
|
||||
|
||||
m_rigReservoir->mainGrid()->results()->setReaderInterface(m_fileInterface.p());
|
||||
m_rigReservoir->computeFaults();
|
||||
m_rigReservoir->mainGrid()->computeCachedData();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimReservoir::createMockModel(QString modelName)
|
||||
{
|
||||
cvf::ref<RifReaderInterfaceMock> mockFileInterface = new RifReaderInterfaceMock;
|
||||
cvf::ref<RigReservoir> reservoir = new RigReservoir;
|
||||
|
||||
if (modelName == "Mock Debug Model Simple")
|
||||
{
|
||||
// Create the mock file interface and and RigSerervoir and set them up.
|
||||
mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(20, 20, 20));
|
||||
mockFileInterface->setGridPointDimensions(cvf::Vec3st(4, 5, 6));
|
||||
mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 2, 2), cvf::Vec3st(0, 2, 2), cvf::Vec3st(3, 3, 3));
|
||||
|
||||
mockFileInterface->open("", reservoir.p());
|
||||
{
|
||||
size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4);
|
||||
reservoir->mainGrid()->cell(idx).setActive(false);
|
||||
}
|
||||
|
||||
{
|
||||
size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3);
|
||||
reservoir->mainGrid()->cell(idx).setActive(false);
|
||||
}
|
||||
}
|
||||
else if (modelName == "Mock Debug Model With Results")
|
||||
{
|
||||
mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(-20, -20, -20));
|
||||
mockFileInterface->setGridPointDimensions(cvf::Vec3st(5, 10, 20));
|
||||
mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 3, 3), cvf::Vec3st(1, 4, 9), cvf::Vec3st(2, 2, 2));
|
||||
mockFileInterface->setResultInfo(3, 10);
|
||||
|
||||
mockFileInterface->open("", reservoir.p());
|
||||
|
||||
// Make a fault
|
||||
cvf::Vec3d& tmp = reservoir->mainGrid()->nodes()[1];
|
||||
tmp += cvf::Vec3d(1, 0, 0);
|
||||
}
|
||||
else if (modelName =="Mock Debug Model Large With Results")
|
||||
{
|
||||
double startX = 0;
|
||||
double startY = 0;
|
||||
double startZ = 0;
|
||||
|
||||
double widthX = 6000;
|
||||
double widthY = 12000;
|
||||
double widthZ = 500;
|
||||
|
||||
double offsetX = 0;
|
||||
double offsetY = 0;
|
||||
double offsetZ = 0;
|
||||
|
||||
// Test code to simulate UTM coordinates
|
||||
offsetX = 400000;
|
||||
offsetY = 6000000;
|
||||
offsetZ = 0;
|
||||
|
||||
|
||||
mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ));
|
||||
mockFileInterface->setGridPointDimensions(cvf::Vec3st(50, 100, 200));
|
||||
mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 30, 30), cvf::Vec3st(1, 40, 90), cvf::Vec3st(2, 2, 2));
|
||||
mockFileInterface->setResultInfo(3, 10);
|
||||
|
||||
mockFileInterface->open("", reservoir.p());
|
||||
|
||||
}
|
||||
|
||||
m_rigReservoir = reservoir;
|
||||
m_fileInterface = mockFileInterface;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimReservoir::initAfterRead()
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < reservoirViews().size(); j++)
|
||||
{
|
||||
RimReservoirView* riv = reservoirViews()[j];
|
||||
CVF_ASSERT(riv);
|
||||
|
||||
riv->setEclipseCase(this);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimReservoir::~RimReservoir()
|
||||
{
|
||||
reservoirViews.deleteChildren();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimReservoirView* RimReservoir::createAndAddReservoirView()
|
||||
{
|
||||
RimReservoirView* riv = new RimReservoirView();
|
||||
riv->setEclipseCase(this);
|
||||
|
||||
size_t i = reservoirViews().size();
|
||||
riv->name = QString("View %1").arg(i + 1);
|
||||
|
||||
reservoirViews().push_back(riv);
|
||||
|
||||
return riv;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// TODO: Move this functionality to PdmPointersField
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimReservoir::removeReservoirView(RimReservoirView* reservoirView)
|
||||
{
|
||||
std::vector<size_t> indices;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < reservoirViews().size(); i++)
|
||||
{
|
||||
if (reservoirViews()[i] == reservoirView)
|
||||
{
|
||||
indices.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
// NB! Make sure the ordering goes from large to low index
|
||||
while (!indices.empty())
|
||||
{
|
||||
reservoirViews().erase(indices.back());
|
||||
indices.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
79
ApplicationCode/ProjectDataModel/RimReservoir.h
Normal file
79
ApplicationCode/ProjectDataModel/RimReservoir.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include "RimWellCollection.h"
|
||||
|
||||
class QString;
|
||||
class RigReservoir;
|
||||
class RifReaderInterface;
|
||||
class RimWellCollection;
|
||||
class RigGridBase;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RimReservoir : public caf::PdmObject, public cvf::Object
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimReservoir();
|
||||
RimReservoir(RigReservoir* reservoir);
|
||||
virtual ~RimReservoir();
|
||||
|
||||
bool openEclipseGridFile();
|
||||
|
||||
RigReservoir* reservoirData();
|
||||
const RigReservoir* reservoirData() const;
|
||||
|
||||
RifReaderInterface* fileInterface();
|
||||
const RifReaderInterface* fileInterface() const;
|
||||
|
||||
RimReservoirView* createAndAddReservoirView();
|
||||
void removeReservoirView(RimReservoirView* reservoirView);
|
||||
|
||||
// Fields:
|
||||
caf::PdmField<QString> caseName;
|
||||
caf::PdmField<QString> caseDirectory;
|
||||
|
||||
caf::PdmPointersField<RimReservoirView*> reservoirViews;
|
||||
|
||||
virtual caf::PdmFieldHandle* userDescriptionField() { return &caseName;}
|
||||
|
||||
protected:
|
||||
// Overridden methods
|
||||
virtual void initAfterRead();
|
||||
|
||||
private:
|
||||
void createMockModel(QString modelName);
|
||||
|
||||
private:
|
||||
cvf::ref<RigReservoir> m_rigReservoir;
|
||||
cvf::ref<RifReaderInterface> m_fileInterface;
|
||||
|
||||
};
|
||||
|
||||
1204
ApplicationCode/ProjectDataModel/RimReservoirView.cpp
Normal file
1204
ApplicationCode/ProjectDataModel/RimReservoirView.cpp
Normal file
File diff suppressed because it is too large
Load Diff
178
ApplicationCode/ProjectDataModel/RimReservoirView.h
Normal file
178
ApplicationCode/ProjectDataModel/RimReservoirView.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafAppEnum.h"
|
||||
|
||||
#include <QPointer>
|
||||
#include <QString>
|
||||
|
||||
#include "RimReservoir.h"
|
||||
#include "RimResultSlot.h"
|
||||
#include "RimCellEdgeResultSlot.h"
|
||||
#include "RimCellRangeFilter.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimCellPropertyFilter.h"
|
||||
#include "RimCellPropertyFilterCollection.h"
|
||||
|
||||
#include "cvfMatrix4.h"
|
||||
#include "cvfStructGridGeometryGenerator.h"
|
||||
|
||||
#include "RivReservoirViewPartMgr.h"
|
||||
#include "RivReservoirPipesPartMgr.h"
|
||||
|
||||
class RIViewer;
|
||||
class RigGridBase;
|
||||
class RigGridCellFaceVisibilityFilter;
|
||||
class RimReservoir;
|
||||
class RivReservoirViewPartMgr;
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class Transform;
|
||||
class ScalarMapperUniformLevels;
|
||||
class ModelBasicList;
|
||||
}
|
||||
|
||||
|
||||
enum ViewState
|
||||
{
|
||||
GEOMETRY_ONLY,
|
||||
STATIC_RESULT,
|
||||
DYNAMIC_RESULT,
|
||||
CELL_FACE_COMBINED_RESULT
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimReservoirView : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimReservoirView(void);
|
||||
virtual ~RimReservoirView(void);
|
||||
|
||||
enum MeshModeType
|
||||
{
|
||||
FULL_MESH,
|
||||
NO_MESH
|
||||
};
|
||||
|
||||
enum SurfaceModeType
|
||||
{
|
||||
SURFACE,
|
||||
FAULTS,
|
||||
NO_SURFACE
|
||||
};
|
||||
|
||||
// Public fields:
|
||||
|
||||
caf::PdmField<RimResultSlot*> cellResult;
|
||||
caf::PdmField<RimCellEdgeResultSlot*> cellEdgeResult;
|
||||
|
||||
caf::PdmField<double> scaleZ;
|
||||
caf::PdmField<bool> showWindow;
|
||||
caf::PdmField<QString> name;
|
||||
|
||||
// Visibility
|
||||
caf::PdmField<bool> showInvalidCells;
|
||||
caf::PdmField<bool> showInactiveCells;
|
||||
caf::PdmField<bool> showMainGrid;
|
||||
|
||||
caf::PdmField<RimWellCollection*> wellCollection;
|
||||
|
||||
caf::PdmField<RimCellRangeFilterCollection*> rangeFilterCollection;
|
||||
caf::PdmField<RimCellPropertyFilterCollection*> propertyFilterCollection;
|
||||
|
||||
caf::PdmField< caf::AppEnum< MeshModeType > > meshMode;
|
||||
caf::PdmField< caf::AppEnum< SurfaceModeType > > surfaceMode;
|
||||
|
||||
// Animation
|
||||
caf::PdmField<int> maximumFrameRate;
|
||||
caf::PdmField<bool> animationMode;
|
||||
|
||||
int currentTimeStep() { return m_currentTimeStep;}
|
||||
void setCurrentTimeStep(int frameIdx);
|
||||
void updateCurrentTimeStepAndRedraw();
|
||||
void endAnimation();
|
||||
|
||||
// 3D Viewer
|
||||
// Cam pos should be a field, but is not yet supported bu caf::Pdm
|
||||
cvf::Mat4d cameraPosition;
|
||||
void setDefaultView();
|
||||
|
||||
RIViewer* viewer();
|
||||
void updateViewerWidget();
|
||||
void updateViewerWidgetWindowTitle();
|
||||
|
||||
// Picking info
|
||||
bool pickInfo(size_t gridIndex, size_t cellIndex, const cvf::Vec3d& point, QString* pickInfoText) const;
|
||||
void appendCellResultInfo(size_t gridIndex, size_t cellIndex, QString* resultInfoText) const;
|
||||
|
||||
RigReservoirCellResults* gridCellResults();
|
||||
|
||||
void setEclipseCase(RimReservoir* reservoir);
|
||||
RimReservoir* eclipseCase();
|
||||
|
||||
void calculateVisibleWellCellsIncFence(cvf::UByteArray* visibleCells, RigGridBase * grid);
|
||||
|
||||
|
||||
// Display model generation
|
||||
public:
|
||||
void loadDataAndUpdate();
|
||||
void createDisplayModelAndRedraw();
|
||||
void scheduleGeometryRegen(unsigned short geometryType);
|
||||
void schedulePipeGeometryRegen();
|
||||
|
||||
// Overridden PDM methods:
|
||||
public:
|
||||
virtual caf::PdmFieldHandle* userDescriptionField() { return &name;}
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
protected:
|
||||
virtual void initAfterRead();
|
||||
virtual void setupBeforeSave();
|
||||
|
||||
|
||||
private:
|
||||
void syncronizeWellsWithResults();
|
||||
|
||||
private:
|
||||
caf::PdmField<int> m_currentTimeStep;
|
||||
QPointer<RIViewer> m_viewer;
|
||||
caf::PdmPointer<RimReservoir> m_reservoir;
|
||||
|
||||
|
||||
// Display model generation
|
||||
private:
|
||||
void createDisplayModel();
|
||||
void updateDisplayModelVisibility();
|
||||
void updateCurrentTimeStep();
|
||||
void indicesToVisibleGrids(std::vector<size_t>* gridIndices);
|
||||
void updateScaleTransform();
|
||||
void updateStaticCellColors();
|
||||
void updateStaticCellColors(unsigned short geometryType);
|
||||
void updateLegends();
|
||||
|
||||
|
||||
cvf::ref<RivReservoirViewPartMgr> m_geometry;
|
||||
cvf::ref<RivReservoirPipesPartMgr> m_pipesPartManager;
|
||||
};
|
||||
|
||||
212
ApplicationCode/ProjectDataModel/RimResultDefinition.cpp
Normal file
212
ApplicationCode/ProjectDataModel/RimResultDefinition.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimResultDefinition.h"
|
||||
|
||||
#include "RimReservoirView.h"
|
||||
#include "RimReservoir.h"
|
||||
#include "RigReservoirCellResults.h"
|
||||
#include "RigReservoir.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RifReaderInterface.h"
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimResultDefinition, "ResultDefinition");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimResultDefinition::RimResultDefinition()
|
||||
: m_gridScalarResultIndex(cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
CAF_PDM_InitObject("Result Definition", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&resultType, "ResultType","Result type", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&resultVariable, "ResultVariable","Variable", "", "", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimResultDefinition::~RimResultDefinition()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimResultDefinition::setReservoirView(RimReservoirView* ownerReservoirView)
|
||||
{
|
||||
m_reservoirView = ownerReservoirView;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (changedField == &resultType)
|
||||
{
|
||||
resultVariable = "";
|
||||
}
|
||||
|
||||
loadResult();
|
||||
|
||||
// Notify the parent objects that this object has changed
|
||||
// In this case the RimCellPropertyFilter.
|
||||
// The RimReservoirView can also be a parent, but the call should have no effect there
|
||||
|
||||
std::vector<caf::PdmFieldHandle*> parentFields;
|
||||
this->parentFields(parentFields);
|
||||
for (size_t i = 0; i < parentFields.size(); ++i)
|
||||
{
|
||||
parentFields[i]->ownerObject()->fieldChangedByUi(parentFields[i], QVariant(), QVariant());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimResultDefinition::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
|
||||
{
|
||||
if (fieldNeedingOptions == &resultVariable)
|
||||
{
|
||||
if (m_reservoirView &&
|
||||
m_reservoirView->eclipseCase() &&
|
||||
m_reservoirView->eclipseCase()->fileInterface())
|
||||
{
|
||||
RifReaderInterface* readerInterface = m_reservoirView->eclipseCase()->fileInterface();
|
||||
CVF_ASSERT(readerInterface);
|
||||
|
||||
QStringList varList;
|
||||
if (resultType() == RimDefines::DYNAMIC_NATIVE)
|
||||
{
|
||||
varList = readerInterface->dynamicResults();
|
||||
|
||||
if (!varList.contains("SOIL", Qt::CaseInsensitive))
|
||||
{
|
||||
// SOIL will be computed in RigReservoirCellResults::loadOrComputeSOIL() if SGAS and SWAT is present
|
||||
if (varList.contains("SGAS", Qt::CaseInsensitive) && varList.contains("SWAT", Qt::CaseInsensitive))
|
||||
{
|
||||
varList.push_back("SOIL");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (resultType == RimDefines::STATIC_NATIVE)
|
||||
{
|
||||
varList = readerInterface->staticResults();
|
||||
}
|
||||
else if (resultType == RimDefines::GENERATED)
|
||||
{
|
||||
varList = m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->results()->resultNames(resultType());
|
||||
}
|
||||
|
||||
QList<caf::PdmOptionItemInfo> optionList;
|
||||
int i;
|
||||
for (i = 0; i < varList.size(); ++i)
|
||||
{
|
||||
optionList.push_back(caf::PdmOptionItemInfo( varList[i], varList[i]));
|
||||
}
|
||||
optionList.push_front(caf::PdmOptionItemInfo( "None", "" ));
|
||||
|
||||
if (useOptionsOnly) *useOptionsOnly = true;
|
||||
|
||||
return optionList;
|
||||
}
|
||||
}
|
||||
|
||||
return QList<caf::PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RimResultDefinition::gridScalarIndex() const
|
||||
{
|
||||
if (m_gridScalarResultIndex == cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults();
|
||||
if (gridCellResults) m_gridScalarResultIndex = gridCellResults->findGridScalarIndex(resultType(), resultVariable());
|
||||
}
|
||||
return m_gridScalarResultIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimResultDefinition::loadResult()
|
||||
{
|
||||
RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults();
|
||||
if (gridCellResults)
|
||||
{
|
||||
m_gridScalarResultIndex = gridCellResults->loadResultIntoGrid(resultType(), resultVariable);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gridScalarResultIndex = cvf::UNDEFINED_SIZE_T;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimResultDefinition::hasStaticResult() const
|
||||
{
|
||||
const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults();
|
||||
if (hasResult() && gridCellResults->timeStepCount(m_gridScalarResultIndex) == 1 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimResultDefinition::hasResult() const
|
||||
{
|
||||
if (m_gridScalarResultIndex != cvf::UNDEFINED_SIZE_T) return true;
|
||||
|
||||
const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults();
|
||||
if (gridCellResults)
|
||||
{
|
||||
m_gridScalarResultIndex = gridCellResults->findGridScalarIndex(resultType(), resultVariable());
|
||||
return m_gridScalarResultIndex != cvf::UNDEFINED_SIZE_T;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimResultDefinition::hasDynamicResult() const
|
||||
{
|
||||
const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults();
|
||||
if (hasResult() && gridCellResults->timeStepCount(m_gridScalarResultIndex) > 1 )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
66
ApplicationCode/ProjectDataModel/RimResultDefinition.h
Normal file
66
ApplicationCode/ProjectDataModel/RimResultDefinition.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "RimDefines.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
|
||||
class RimReservoirView;
|
||||
class RigReservoirCellResults;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimResultDefinition : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimResultDefinition();
|
||||
virtual ~RimResultDefinition();
|
||||
|
||||
virtual void setReservoirView(RimReservoirView* ownerReservoirView);
|
||||
|
||||
caf::PdmField< caf::AppEnum< RimDefines::ResultCatType > > resultType;
|
||||
caf::PdmField<QString> resultVariable;
|
||||
|
||||
void loadResult();
|
||||
size_t gridScalarIndex() const;
|
||||
bool hasStaticResult() const;
|
||||
bool hasDynamicResult() const;
|
||||
bool hasResult() const;
|
||||
|
||||
|
||||
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
|
||||
protected:
|
||||
|
||||
mutable size_t m_gridScalarResultIndex;
|
||||
|
||||
caf::PdmPointer<RimReservoirView> m_reservoirView;
|
||||
};
|
||||
|
||||
135
ApplicationCode/ProjectDataModel/RimResultSlot.cpp
Normal file
135
ApplicationCode/ProjectDataModel/RimResultSlot.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimResultSlot.h"
|
||||
#include "RimLegendConfig.h"
|
||||
#include "RimReservoirView.h"
|
||||
#include "RimReservoir.h"
|
||||
#include "RIMainWindow.h"
|
||||
#include "RimUiTreeModelPdm.h"
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimResultSlot, "ResultSlot");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimResultSlot::RimResultSlot()
|
||||
{
|
||||
CAF_PDM_InitObject("Result Slot", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&legendConfig, "LegendDefinition", "Legend Definition", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_legendConfigData, "ResultVarLegendDefinitionList", "", "", "", "");
|
||||
m_legendConfigData.setHidden(true);
|
||||
|
||||
legendConfig = new RimLegendConfig();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimResultSlot::~RimResultSlot()
|
||||
{
|
||||
delete legendConfig();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimResultSlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (changedField == &resultVariable)
|
||||
{
|
||||
if (oldValue != newValue)
|
||||
{
|
||||
changeLegendConfig(this->resultVariable());
|
||||
}
|
||||
|
||||
if (newValue != "None") if (m_reservoirView) m_reservoirView->animationMode = true;
|
||||
}
|
||||
|
||||
RimResultDefinition::fieldChangedByUi(changedField, oldValue, newValue);
|
||||
|
||||
if (m_reservoirView) m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimResultSlot::changeLegendConfig(QString resultVarNameOfNewLegend)
|
||||
{
|
||||
if (this->legendConfig()->resultVariableName() == resultVarNameOfNewLegend) return;
|
||||
|
||||
std::list<caf::PdmPointer<RimLegendConfig> >::iterator it;
|
||||
bool found = false;
|
||||
for (it = m_legendConfigData.v().begin(); it != m_legendConfigData.v().end(); ++it)
|
||||
{
|
||||
if ((*it)->resultVariableName() == resultVarNameOfNewLegend)
|
||||
{
|
||||
RimLegendConfig* newLegend = *it;
|
||||
|
||||
m_legendConfigData.v().erase(it);
|
||||
m_legendConfigData.v().push_back(this->legendConfig());
|
||||
this->legendConfig = newLegend;
|
||||
RIMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Not found ?
|
||||
if (!found)
|
||||
{
|
||||
RimLegendConfig* newLegend = new RimLegendConfig;
|
||||
newLegend->setReservoirView(m_reservoirView);
|
||||
newLegend->resultVariableName = resultVarNameOfNewLegend;
|
||||
m_legendConfigData.v().push_back(this->legendConfig());
|
||||
this->legendConfig = newLegend;
|
||||
RIMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimResultSlot::initAfterRead()
|
||||
{
|
||||
RimResultDefinition::initAfterRead();
|
||||
|
||||
if (this->legendConfig()->resultVariableName == "")
|
||||
{
|
||||
this->legendConfig()->resultVariableName = this->resultVariable();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimResultSlot::setReservoirView(RimReservoirView* ownerReservoirView)
|
||||
{
|
||||
m_reservoirView = ownerReservoirView;
|
||||
this->legendConfig()->setReservoirView(ownerReservoirView);
|
||||
std::list<caf::PdmPointer<RimLegendConfig> >::iterator it;
|
||||
for (it = m_legendConfigData.v().begin(); it != m_legendConfigData.v().end(); ++it)
|
||||
{
|
||||
(*it)->setReservoirView(ownerReservoirView);
|
||||
}
|
||||
}
|
||||
52
ApplicationCode/ProjectDataModel/RimResultSlot.h
Normal file
52
ApplicationCode/ProjectDataModel/RimResultSlot.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "RimLegendConfig.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include "RimDefines.h"
|
||||
#include "RimResultDefinition.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimResultSlot : public RimResultDefinition
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimResultSlot();
|
||||
virtual ~RimResultSlot();
|
||||
|
||||
virtual void setReservoirView(RimReservoirView* ownerReservoirView);
|
||||
caf::PdmField<RimLegendConfig*> legendConfig;
|
||||
|
||||
// Overridden methods
|
||||
virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue );
|
||||
protected:
|
||||
virtual void initAfterRead();
|
||||
|
||||
private:
|
||||
void changeLegendConfig(QString resultVarNameOfNewLegend);
|
||||
|
||||
caf::PdmField<std::list<caf::PdmPointer<RimLegendConfig> > > m_legendConfigData;
|
||||
|
||||
};
|
||||
|
||||
164
ApplicationCode/ProjectDataModel/RimScriptCollection.cpp
Normal file
164
ApplicationCode/ProjectDataModel/RimScriptCollection.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
|
||||
#include "RimScriptCollection.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafUtils.h"
|
||||
#include "RIMainWindow.h"
|
||||
#include "RimUiTreeModelPdm.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimScriptCollection, "ScriptLocation");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimScriptCollection::RimScriptCollection()
|
||||
{
|
||||
CAF_PDM_InitObject("ScriptLocation", ":/Folder.png", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&directory, "ScriptDirectory", "Dir", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&calcScripts, "CalcScripts", "", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&subDirectories, "SubDirectories", "", "", "", "");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimScriptCollection::~RimScriptCollection()
|
||||
{
|
||||
calcScripts.deleteChildren();
|
||||
subDirectories.deleteChildren();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimScriptCollection::readContentFromDisc()
|
||||
{
|
||||
calcScripts.deleteChildren();
|
||||
|
||||
if (directory().isEmpty())
|
||||
{
|
||||
for (size_t i = 0; i < subDirectories.size(); ++i)
|
||||
{
|
||||
if (subDirectories[i]) subDirectories[i]->readContentFromDisc();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Build a list of all scripts in the specified directory
|
||||
{
|
||||
QString filter = "*.m";
|
||||
QStringList fileList = caf::Utils::getFilesInDirectory(directory, filter, true);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < fileList.size(); i++)
|
||||
{
|
||||
QString fileName = fileList.at(i);
|
||||
|
||||
QFileInfo fi(fileName);
|
||||
if (fi.exists())
|
||||
{
|
||||
RimCalcScript* calcScript = new RimCalcScript;
|
||||
calcScript->absolutePath = fileName;
|
||||
calcScript->setUiName(fi.baseName());
|
||||
calcScript->readContentFromFile();
|
||||
|
||||
calcScripts.push_back(calcScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add subfolders
|
||||
{
|
||||
QDir dir(directory);
|
||||
QFileInfoList fileInfoList = dir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
|
||||
subDirectories.deleteChildren();
|
||||
|
||||
QStringList retFileNames;
|
||||
|
||||
QListIterator<QFileInfo> it(fileInfoList);
|
||||
while (it.hasNext())
|
||||
{
|
||||
QFileInfo fi = it.next();
|
||||
|
||||
RimScriptCollection* scriptLocation = new RimScriptCollection;
|
||||
scriptLocation->directory = fi.absoluteFilePath();
|
||||
scriptLocation->setUiName(fi.baseName());
|
||||
scriptLocation->readContentFromDisc();
|
||||
|
||||
subDirectories.push_back(scriptLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimScriptCollection::pathsAndSubPaths(QStringList& pathList)
|
||||
{
|
||||
if (!this->directory().isEmpty())
|
||||
{
|
||||
pathList.append(this->directory());
|
||||
}
|
||||
|
||||
for (size_t i= 0; i < this->subDirectories.size(); ++i)
|
||||
{
|
||||
if (this->subDirectories[i]) this->subDirectories[i]->pathsAndSubPaths(pathList);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimScriptCollection * RimScriptCollection::findScriptCollection(const QString& path)
|
||||
{
|
||||
if (!this->directory().isEmpty())
|
||||
{
|
||||
QFileInfo otherPath(path);
|
||||
QFileInfo thisPath(directory());
|
||||
if (otherPath == thisPath) return this;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < this->subDirectories.size(); ++i)
|
||||
{
|
||||
RimScriptCollection* foundColl = NULL;
|
||||
if (this->subDirectories[i]) foundColl = this->subDirectories[i]->findScriptCollection(path);
|
||||
if (foundColl) return foundColl;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimScriptCollection::fieldChangedByUi(const caf::PdmFieldHandle *changedField, const QVariant &oldValue, const QVariant &newValue)
|
||||
{
|
||||
if (&directory == changedField)
|
||||
{
|
||||
QFileInfo fi(directory);
|
||||
this->setUiName(fi.baseName());
|
||||
this->readContentFromDisc();
|
||||
RimUiTreeModelPdm* treeModel = RIMainWindow::instance()->uiPdmModel();
|
||||
if (treeModel) treeModel->rebuildUiSubTree(this);
|
||||
}
|
||||
}
|
||||
51
ApplicationCode/ProjectDataModel/RimScriptCollection.h
Normal file
51
ApplicationCode/ProjectDataModel/RimScriptCollection.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "RimCalcScript.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimScriptCollection : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimScriptCollection();
|
||||
virtual ~RimScriptCollection();
|
||||
|
||||
public: // Pdm Fields
|
||||
caf::PdmField<QString> directory;
|
||||
caf::PdmPointersField<RimCalcScript*> calcScripts;
|
||||
|
||||
caf::PdmPointersField<RimScriptCollection*> subDirectories;
|
||||
|
||||
public: // Methods
|
||||
void readContentFromDisc();
|
||||
void pathsAndSubPaths(QStringList& pathList);
|
||||
RimScriptCollection* findScriptCollection(const QString& path);
|
||||
|
||||
// Overrides from PdmObject
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
|
||||
|
||||
};
|
||||
846
ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp
Normal file
846
ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp
Normal file
@@ -0,0 +1,846 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RimUiTreeModelPdm.h"
|
||||
#include "RimCellRangeFilter.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "RimCellPropertyFilter.h"
|
||||
#include "RimCellPropertyFilterCollection.h"
|
||||
|
||||
#include "RimReservoirView.h"
|
||||
#include "RIViewer.h"
|
||||
#include "RimCalcScript.h"
|
||||
#include "RIApplication.h"
|
||||
#include "RIMainWindow.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimUiTreeModelPdm::RimUiTreeModelPdm(QObject* parent)
|
||||
: caf::UiTreeModelPdm(parent)
|
||||
{
|
||||
m_scriptChangeDetector = new QFileSystemWatcher(this);
|
||||
this->updateScriptPaths();
|
||||
connect(m_scriptChangeDetector, SIGNAL(directoryChanged(QString)), this, SLOT(slotRefreshScriptTree(QString)));
|
||||
connect(m_scriptChangeDetector, SIGNAL(fileChanged(QString)), this, SLOT(slotRefreshScriptTree(QString)));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimUiTreeModelPdm::insertRows(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/)
|
||||
{
|
||||
caf::PdmUiTreeItem* parentItem = getTreeItemFromIndex(parent);
|
||||
|
||||
bool canCreateChildren = false;
|
||||
QModelIndex parentIndex = parent;
|
||||
|
||||
if (dynamic_cast<RimCellRangeFilterCollection*>(parentItem->dataObject().p()) ||
|
||||
dynamic_cast<RimCellPropertyFilterCollection*>(parentItem->dataObject().p()))
|
||||
{
|
||||
canCreateChildren = true;
|
||||
}
|
||||
else if (dynamic_cast<RimCellFilter*>(parentItem->dataObject().p()))
|
||||
{
|
||||
parentItem = parentItem->parent();
|
||||
parentIndex = parent.parent();
|
||||
|
||||
canCreateChildren = true;
|
||||
}
|
||||
|
||||
if (canCreateChildren)
|
||||
{
|
||||
beginInsertRows(parent, position, position + rows - 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < rows; i++)
|
||||
{
|
||||
if (dynamic_cast<RimCellRangeFilterCollection*>(parentItem->dataObject().p()))
|
||||
{
|
||||
RimCellRangeFilterCollection* rangeFilterCollection = dynamic_cast<RimCellRangeFilterCollection*>(parentItem->dataObject().p());
|
||||
|
||||
RimCellRangeFilter* rangeFilter = rangeFilterCollection->createAndAppendRangeFilter();
|
||||
|
||||
caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(parentItem, position + i, rangeFilter);
|
||||
}
|
||||
else if (dynamic_cast<RimCellPropertyFilterCollection*>(parentItem->dataObject().p()))
|
||||
{
|
||||
RimCellPropertyFilterCollection* propertyFilterCollection = dynamic_cast<RimCellPropertyFilterCollection*>(parentItem->dataObject().p());
|
||||
|
||||
RimCellPropertyFilter* propertyFilter = propertyFilterCollection->createAndAppendPropertyFilter();
|
||||
|
||||
caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(parentItem, position + i, propertyFilter);
|
||||
}
|
||||
|
||||
}
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
return canCreateChildren;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimUiTreeModelPdm::removePropertyFilter(const QModelIndex& itemIndex)
|
||||
{
|
||||
CVF_ASSERT(itemIndex.isValid());
|
||||
|
||||
caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(itemIndex);
|
||||
CVF_ASSERT(uiItem);
|
||||
|
||||
RimCellPropertyFilter* propertyFilter = dynamic_cast<RimCellPropertyFilter*>(uiItem->dataObject().p());
|
||||
CVF_ASSERT(propertyFilter);
|
||||
|
||||
RimCellPropertyFilterCollection* propertyFilterCollection = propertyFilter->parentContainer();
|
||||
CVF_ASSERT(propertyFilterCollection);
|
||||
|
||||
bool wasFilterActive = propertyFilter->active();
|
||||
bool wasSomeFilterActive = propertyFilterCollection->hasActiveFilters();
|
||||
|
||||
// Remove Ui items pointing at the pdm object to delete
|
||||
removeRow(itemIndex.row(), itemIndex.parent());
|
||||
|
||||
propertyFilterCollection->remove(propertyFilter);
|
||||
delete propertyFilter;
|
||||
|
||||
if (wasFilterActive)
|
||||
{
|
||||
propertyFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::PROPERTY_FILTERED);
|
||||
}
|
||||
|
||||
if (wasSomeFilterActive)
|
||||
{
|
||||
propertyFilterCollection->reservoirView()->createDisplayModelAndRedraw();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimUiTreeModelPdm::removeRangeFilter(const QModelIndex& itemIndex)
|
||||
{
|
||||
CVF_ASSERT(itemIndex.isValid());
|
||||
|
||||
caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(itemIndex);
|
||||
CVF_ASSERT(uiItem);
|
||||
|
||||
RimCellRangeFilter* rangeFilter = dynamic_cast<RimCellRangeFilter*>(uiItem->dataObject().p());
|
||||
CVF_ASSERT(rangeFilter);
|
||||
|
||||
RimCellRangeFilterCollection* rangeFilterCollection = rangeFilter->parentContainer();
|
||||
CVF_ASSERT(rangeFilterCollection);
|
||||
|
||||
bool wasFilterActive = rangeFilter->active();
|
||||
bool wasSomeFilterActive = rangeFilterCollection->hasActiveFilters();
|
||||
|
||||
// Remove Ui items pointing at the pdm object to delete
|
||||
removeRow(itemIndex.row(), itemIndex.parent());
|
||||
|
||||
rangeFilterCollection->remove(rangeFilter);
|
||||
delete rangeFilter;
|
||||
|
||||
if (wasFilterActive)
|
||||
{
|
||||
rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::PROPERTY_FILTERED);
|
||||
}
|
||||
|
||||
if (wasSomeFilterActive)
|
||||
{
|
||||
rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimUiTreeModelPdm::removeReservoirView(const QModelIndex& itemIndex)
|
||||
{
|
||||
CVF_ASSERT(itemIndex.isValid());
|
||||
|
||||
caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(itemIndex);
|
||||
CVF_ASSERT(uiItem);
|
||||
|
||||
RimReservoirView* reservoirView = dynamic_cast<RimReservoirView*>(uiItem->dataObject().p());
|
||||
CVF_ASSERT(reservoirView);
|
||||
|
||||
// Remove Ui items pointing at the pdm object to delete
|
||||
removeRow(itemIndex.row(), itemIndex.parent());
|
||||
|
||||
reservoirView->eclipseCase()->removeReservoirView(reservoirView);
|
||||
delete reservoirView;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellPropertyFilter* RimUiTreeModelPdm::addPropertyFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex)
|
||||
{
|
||||
caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex);
|
||||
|
||||
QModelIndex collectionIndex;
|
||||
RimCellPropertyFilterCollection* propertyFilterCollection = NULL;
|
||||
caf::PdmUiTreeItem* propertyFilterCollectionItem = NULL;
|
||||
int position = 0;
|
||||
|
||||
if (dynamic_cast<RimCellPropertyFilter*>(currentItem->dataObject().p()))
|
||||
{
|
||||
RimCellPropertyFilter* propertyFilter = dynamic_cast<RimCellPropertyFilter*>(currentItem->dataObject().p());
|
||||
propertyFilterCollection = propertyFilter->parentContainer();
|
||||
propertyFilterCollectionItem = currentItem->parent();
|
||||
position = itemIndex.row();
|
||||
collectionIndex = itemIndex.parent();
|
||||
}
|
||||
else if (dynamic_cast<RimCellPropertyFilterCollection*>(currentItem->dataObject().p()))
|
||||
{
|
||||
propertyFilterCollection = dynamic_cast<RimCellPropertyFilterCollection*>(currentItem->dataObject().p());
|
||||
propertyFilterCollectionItem = currentItem;
|
||||
position = propertyFilterCollectionItem->childCount();
|
||||
collectionIndex = itemIndex;
|
||||
}
|
||||
|
||||
beginInsertRows(collectionIndex, position, position);
|
||||
|
||||
RimCellPropertyFilter* propertyFilter = propertyFilterCollection->createAndAppendPropertyFilter();
|
||||
caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(propertyFilterCollectionItem, position, propertyFilter);
|
||||
|
||||
endInsertRows();
|
||||
|
||||
insertedModelIndex = index(position, 0, collectionIndex);
|
||||
|
||||
if (propertyFilterCollection)
|
||||
{
|
||||
propertyFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::PROPERTY_FILTERED);
|
||||
}
|
||||
|
||||
return propertyFilter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCellRangeFilter* RimUiTreeModelPdm::addRangeFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex)
|
||||
{
|
||||
caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex);
|
||||
|
||||
QModelIndex collectionIndex;
|
||||
RimCellRangeFilterCollection* rangeFilterCollection = NULL;
|
||||
caf::PdmUiTreeItem* rangeFilterCollectionItem = NULL;
|
||||
int position = 0;
|
||||
|
||||
if (dynamic_cast<RimCellRangeFilter*>(currentItem->dataObject().p()))
|
||||
{
|
||||
RimCellRangeFilter* rangeFilter = dynamic_cast<RimCellRangeFilter*>(currentItem->dataObject().p());
|
||||
rangeFilterCollection = rangeFilter->parentContainer();
|
||||
rangeFilterCollectionItem = currentItem->parent();
|
||||
position = itemIndex.row();
|
||||
collectionIndex = itemIndex.parent();
|
||||
}
|
||||
else if (dynamic_cast<RimCellRangeFilterCollection*>(currentItem->dataObject().p()))
|
||||
{
|
||||
rangeFilterCollection = dynamic_cast<RimCellRangeFilterCollection*>(currentItem->dataObject().p());
|
||||
rangeFilterCollectionItem = currentItem;
|
||||
position = rangeFilterCollectionItem->childCount();
|
||||
collectionIndex = itemIndex;
|
||||
}
|
||||
|
||||
beginInsertRows(collectionIndex, position, position);
|
||||
|
||||
RimCellRangeFilter* rangeFilter = rangeFilterCollection->createAndAppendRangeFilter();
|
||||
caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(rangeFilterCollectionItem, position, rangeFilter);
|
||||
|
||||
endInsertRows();
|
||||
|
||||
insertedModelIndex = index(position, 0, collectionIndex);
|
||||
if (rangeFilterCollection)
|
||||
{
|
||||
rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED);
|
||||
rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED_INACTIVE);
|
||||
|
||||
}
|
||||
return rangeFilter;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimReservoirView* RimUiTreeModelPdm::addReservoirView(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex)
|
||||
{
|
||||
caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex);
|
||||
if (!currentItem) return NULL;
|
||||
|
||||
RimReservoirView* reservoirView = dynamic_cast<RimReservoirView*>(currentItem->dataObject().p());
|
||||
if (!reservoirView) return NULL;
|
||||
|
||||
RimReservoirView* insertedView = reservoirView->eclipseCase()->createAndAddReservoirView();
|
||||
caf::PdmUiTreeItem* collectionItem = currentItem->parent();
|
||||
|
||||
size_t viewCount = rowCount(itemIndex.parent());
|
||||
beginInsertRows(itemIndex.parent(), viewCount, viewCount);
|
||||
|
||||
caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(collectionItem, viewCount, insertedView);
|
||||
|
||||
endInsertRows();
|
||||
|
||||
insertedView->loadDataAndUpdate();
|
||||
|
||||
rebuildUiSubTree(insertedView);
|
||||
|
||||
return insertedView;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimUiTreeModelPdm::updateScriptPaths()
|
||||
{
|
||||
RimProject* proj = RIApplication::instance()->project();
|
||||
|
||||
if (!proj || !proj->scriptCollection()) return;
|
||||
|
||||
QStringList paths;
|
||||
|
||||
proj->scriptCollection()->pathsAndSubPaths(paths);
|
||||
|
||||
if (m_scriptChangeDetector->directories().size()) m_scriptChangeDetector->removePaths( m_scriptChangeDetector->directories());
|
||||
if (m_scriptChangeDetector->files().size()) m_scriptChangeDetector->removePaths( m_scriptChangeDetector->files());
|
||||
|
||||
if (paths.size()) m_scriptChangeDetector->addPaths(paths);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimUiTreeModelPdm::slotRefreshScriptTree(QString path)
|
||||
{
|
||||
RimProject* proj = RIApplication::instance()->project();
|
||||
|
||||
if (!proj || !proj->scriptCollection()) return;
|
||||
|
||||
RimScriptCollection* changedSColl = proj->scriptCollection()->findScriptCollection(path);
|
||||
if (changedSColl)
|
||||
{
|
||||
changedSColl->readContentFromDisc();
|
||||
this->rebuildUiSubTree(changedSColl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimTreeView::RimTreeView(QWidget *parent /*= 0*/)
|
||||
: QTreeView(parent)
|
||||
{
|
||||
setHeaderHidden(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex());
|
||||
if (uiItem && uiItem->dataObject())
|
||||
{
|
||||
// Range filters
|
||||
if (dynamic_cast<RimReservoirView*>(uiItem->dataObject().p()))
|
||||
{
|
||||
QMenu menu;
|
||||
menu.addAction(QString("Show 3D Window"), this, SLOT(slotShowWindow()));
|
||||
menu.addAction(QString("New View"), this, SLOT(slotAddView()));
|
||||
menu.addAction(QString("Delete"), this, SLOT(slotDeleteView()));
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
else if (dynamic_cast<RimCellRangeFilterCollection*>(uiItem->dataObject().p()))
|
||||
{
|
||||
QMenu menu;
|
||||
menu.addAction(QString("New Range Filter"), this, SLOT(slotAddRangeFilter()));
|
||||
menu.addAction(QString("Slice I Filter"), this, SLOT(slotAddSliceFilterI()));
|
||||
menu.addAction(QString("Slice J Filter"), this, SLOT(slotAddSliceFilterJ()));
|
||||
menu.addAction(QString("Slice K Filter"), this, SLOT(slotAddSliceFilterK()));
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
else if (dynamic_cast<RimCellRangeFilter*>(uiItem->dataObject().p()))
|
||||
{
|
||||
QMenu menu;
|
||||
menu.addAction(QString("Insert Range Filter"), this, SLOT(slotAddRangeFilter()));
|
||||
menu.addAction(QString("Slice I Filter"), this, SLOT(slotAddSliceFilterI()));
|
||||
menu.addAction(QString("Slice J Filter"), this, SLOT(slotAddSliceFilterJ()));
|
||||
menu.addAction(QString("Slice K Filter"), this, SLOT(slotAddSliceFilterK()));
|
||||
menu.addSeparator();
|
||||
menu.addAction(QString("Delete"), this, SLOT(slotDeleteRangeFilter()));
|
||||
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
else if (dynamic_cast<RimCellPropertyFilterCollection*>(uiItem->dataObject().p()))
|
||||
{
|
||||
|
||||
QMenu menu;
|
||||
menu.addAction(QString("New Property Filter"), this, SLOT(slotAddPropertyFilter()));
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
else if (dynamic_cast<RimCellPropertyFilter*>(uiItem->dataObject().p()))
|
||||
{
|
||||
|
||||
QMenu menu;
|
||||
menu.addAction(QString("Insert Property Filter"), this, SLOT(slotAddPropertyFilter()));
|
||||
menu.addSeparator();
|
||||
menu.addAction(QString("Delete"), this, SLOT(slotDeletePropertyFilter()));
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
else if (dynamic_cast<RimCalcScript*>(uiItem->dataObject().p()))
|
||||
{
|
||||
RIApplication* app = RIApplication::instance();
|
||||
|
||||
QMenu menu;
|
||||
{
|
||||
QAction* action = menu.addAction(QString("Edit"), this, SLOT(slotEditScript()));
|
||||
if (app->scriptEditorPath().isEmpty())
|
||||
{
|
||||
action->setEnabled(false);
|
||||
}
|
||||
}
|
||||
menu.addAction(QString("New"), this, SLOT(slotNewScript()));
|
||||
//menu.addAction(QString("ReadFromFile"), this, SLOT(slotReadScriptContentFromFile()));
|
||||
menu.addSeparator();
|
||||
|
||||
{
|
||||
QAction* action = menu.addAction(QString("Execute"), this, SLOT(slotExecuteScript()));
|
||||
if (app->octavePath().isEmpty())
|
||||
{
|
||||
action->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotAddChildItem()
|
||||
{
|
||||
|
||||
QModelIndex index = currentIndex();
|
||||
QAbstractItemModel* myModel = model();
|
||||
|
||||
// Insert a single row at the end of the collection of items
|
||||
int itemCount = myModel->rowCount(index);
|
||||
if (!myModel->insertRow(itemCount, index))
|
||||
return;
|
||||
|
||||
selectionModel()->setCurrentIndex(myModel->index(0, 0, index), QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotDeleteItem()
|
||||
{
|
||||
QModelIndex index = currentIndex();
|
||||
QAbstractItemModel* myModel = model();
|
||||
|
||||
if (!myModel->removeRow(index.row(), index.parent()))
|
||||
return;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotShowWindow()
|
||||
{
|
||||
QModelIndex index = currentIndex();
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex());
|
||||
RimReservoirView * riv = NULL;
|
||||
if (riv = dynamic_cast<RimReservoirView*>(uiItem->dataObject().p()))
|
||||
{
|
||||
riv->showWindow = true;
|
||||
bool generateDisplayModel = (riv->viewer() == NULL);
|
||||
riv->updateViewerWidget();
|
||||
if (generateDisplayModel)
|
||||
{
|
||||
riv->createDisplayModelAndRedraw();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotDeletePropertyFilter()
|
||||
{
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
myModel->removePropertyFilter(currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotDeleteRangeFilter()
|
||||
{
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
myModel->removeRangeFilter(currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotAddPropertyFilter()
|
||||
{
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
QModelIndex insertedIndex;
|
||||
RimCellPropertyFilter* propFilter = myModel->addPropertyFilter(currentIndex(), insertedIndex);
|
||||
setCurrentIndex(insertedIndex);
|
||||
if (propFilter)
|
||||
{
|
||||
propFilter->parentContainer()->reservoirView()->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotAddRangeFilter()
|
||||
{
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
QModelIndex insertedIndex;
|
||||
RimCellRangeFilter* newFilter = myModel->addRangeFilter(currentIndex(), insertedIndex);
|
||||
setCurrentIndex(insertedIndex);
|
||||
|
||||
if (newFilter && newFilter->parentContainer())
|
||||
{
|
||||
newFilter->parentContainer()->reservoirView()->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotAddSliceFilterI()
|
||||
{
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
QModelIndex insertedIndex;
|
||||
RimCellRangeFilter* rangeFilter = myModel->addRangeFilter(currentIndex(), insertedIndex);
|
||||
|
||||
RimCellRangeFilterCollection* rangeFilterCollection = rangeFilter->parentContainer();
|
||||
rangeFilter->name = QString("Slice I (%1)").arg(rangeFilterCollection->rangeFilters().size());
|
||||
rangeFilter->cellCountI = 1;
|
||||
|
||||
rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED);
|
||||
rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED_INACTIVE);
|
||||
|
||||
rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw();
|
||||
|
||||
setCurrentIndex(insertedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotAddSliceFilterJ()
|
||||
{
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
QModelIndex insertedIndex;
|
||||
RimCellRangeFilter* rangeFilter = myModel->addRangeFilter(currentIndex(), insertedIndex);
|
||||
|
||||
RimCellRangeFilterCollection* rangeFilterCollection = rangeFilter->parentContainer();
|
||||
rangeFilter->name = QString("Slice J (%1)").arg(rangeFilterCollection->rangeFilters().size());
|
||||
rangeFilter->cellCountJ = 1;
|
||||
|
||||
rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED);
|
||||
rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED_INACTIVE);
|
||||
|
||||
rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw();
|
||||
|
||||
setCurrentIndex(insertedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotAddSliceFilterK()
|
||||
{
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
QModelIndex insertedIndex;
|
||||
RimCellRangeFilter* rangeFilter = myModel->addRangeFilter(currentIndex(), insertedIndex);
|
||||
|
||||
RimCellRangeFilterCollection* rangeFilterCollection = rangeFilter->parentContainer();
|
||||
rangeFilter->name = QString("Slice K (%1)").arg(rangeFilterCollection->rangeFilters().size());
|
||||
rangeFilter->cellCountK = 1;
|
||||
|
||||
rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED);
|
||||
rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED_INACTIVE);
|
||||
|
||||
rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw();
|
||||
|
||||
setCurrentIndex(insertedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotReadScriptContentFromFile()
|
||||
{
|
||||
QModelIndex index = currentIndex();
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex());
|
||||
if (uiItem)
|
||||
{
|
||||
RimCalcScript* calcScript = dynamic_cast<RimCalcScript*>(uiItem->dataObject().p());
|
||||
if (calcScript)
|
||||
{
|
||||
calcScript->readContentFromFile();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotEditScript()
|
||||
{
|
||||
QModelIndex index = currentIndex();
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex());
|
||||
if (uiItem)
|
||||
{
|
||||
RimCalcScript* calcScript = dynamic_cast<RimCalcScript*>(uiItem->dataObject().p());
|
||||
|
||||
RIApplication* app = RIApplication::instance();
|
||||
QString scriptEditor = app->scriptEditorPath();
|
||||
if (!scriptEditor.isEmpty())
|
||||
{
|
||||
QStringList arguments;
|
||||
arguments << calcScript->absolutePath;
|
||||
|
||||
QProcess* myProcess = new QProcess(this);
|
||||
myProcess->start(scriptEditor, arguments);
|
||||
|
||||
if (!myProcess->waitForStarted(1000))
|
||||
{
|
||||
QMessageBox::warning(RIMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotNewScript()
|
||||
{
|
||||
QModelIndex index = currentIndex();
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex());
|
||||
RimCalcScript* calcScript = NULL;
|
||||
RimScriptCollection * scriptColl = NULL;
|
||||
|
||||
calcScript = dynamic_cast<RimCalcScript*>(uiItem->dataObject().p());
|
||||
scriptColl = dynamic_cast<RimScriptCollection*>(uiItem->dataObject().p());
|
||||
QString fullPathNewScript;
|
||||
|
||||
if (calcScript )
|
||||
{
|
||||
QFileInfo existingScriptFileInfo(calcScript->absolutePath());
|
||||
fullPathNewScript = existingScriptFileInfo.absolutePath();
|
||||
}
|
||||
else if (scriptColl)
|
||||
{
|
||||
fullPathNewScript = scriptColl->directory();
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QString fullPathFilenameNewScript;
|
||||
|
||||
fullPathFilenameNewScript = fullPathNewScript + "/untitled.m";
|
||||
int num= 1;
|
||||
while (QFileInfo(fullPathFilenameNewScript).exists())
|
||||
{
|
||||
fullPathFilenameNewScript = fullPathNewScript + "/untitled" + QString::number(num) + ".m";
|
||||
num++;
|
||||
}
|
||||
|
||||
RIApplication* app = RIApplication::instance();
|
||||
QString scriptEditor = app->scriptEditorPath();
|
||||
if (!scriptEditor.isEmpty())
|
||||
{
|
||||
QStringList arguments;
|
||||
arguments << fullPathFilenameNewScript;
|
||||
|
||||
QProcess* myProcess = new QProcess(this);
|
||||
myProcess->start(scriptEditor, arguments);
|
||||
|
||||
if (!myProcess->waitForStarted(1000))
|
||||
{
|
||||
QMessageBox::warning(RIMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotExecuteScript()
|
||||
{
|
||||
QModelIndex index = currentIndex();
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex());
|
||||
if (uiItem)
|
||||
{
|
||||
RimCalcScript* calcScript = dynamic_cast<RimCalcScript*>(uiItem->dataObject().p());
|
||||
|
||||
RIApplication* app = RIApplication::instance();
|
||||
QString octavePath = app->octavePath();
|
||||
if (!octavePath.isEmpty())
|
||||
{
|
||||
QStringList arguments;
|
||||
|
||||
arguments << calcScript->absolutePath();
|
||||
|
||||
if (!RIApplication::instance()->launchProcess(octavePath, arguments))
|
||||
{
|
||||
QMessageBox::warning(RIMainWindow::instance(), "Script execution", "Failed to start script executable located at\n" + octavePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotAddView()
|
||||
{
|
||||
QModelIndex index = currentIndex();
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex());
|
||||
|
||||
RimReservoirView* rimView = dynamic_cast<RimReservoirView*>(uiItem->dataObject().p());
|
||||
if (rimView)
|
||||
{
|
||||
QModelIndex insertedIndex;
|
||||
myModel->addReservoirView(index, insertedIndex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTreeView::slotDeleteView()
|
||||
{
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
myModel->removeReservoirView(currentIndex());
|
||||
|
||||
RIApplication* app = RIApplication::instance();
|
||||
app->setActiveReservoirView(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimUiPropertyCreatorPdm::RimUiPropertyCreatorPdm(QObject* parent)
|
||||
: caf::UiPropertyCreatorPdm(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimUiPropertyCreatorPdm::uiFields(const caf::PdmObject* object, std::vector<caf::PdmFieldHandle*>& fields) const
|
||||
{
|
||||
const RimCellPropertyFilter* propertyFilter = dynamic_cast<const RimCellPropertyFilter*>(object);
|
||||
if (propertyFilter)
|
||||
{
|
||||
caf::UiPropertyCreatorPdm::uiFields(object, fields);
|
||||
|
||||
CVF_ASSERT(propertyFilter->resultDefinition);
|
||||
|
||||
// Append fields from result definition object
|
||||
std::vector<caf::PdmFieldHandle*> childFields;
|
||||
propertyFilter->resultDefinition->fields(childFields);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < childFields.size(); i++)
|
||||
{
|
||||
fields.push_back(childFields[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
caf::UiPropertyCreatorPdm::uiFields(object, fields);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
113
ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h
Normal file
113
ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include "cafUiTreeModelPdm.h"
|
||||
#include "RimCellRangeFilter.h"
|
||||
|
||||
#include <QTreeView>
|
||||
#include "cafUiPropertyCreatorPdm.h"
|
||||
|
||||
class QFileSystemWatcher;
|
||||
|
||||
class RimCellPropertyFilter;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimUiTreeModelPdm : public caf::UiTreeModelPdm
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
RimUiTreeModelPdm(QObject* parent);
|
||||
|
||||
// Overrides
|
||||
virtual bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex());
|
||||
|
||||
// Special edit methods
|
||||
bool removeRangeFilter(const QModelIndex& itemIndex);
|
||||
bool removePropertyFilter(const QModelIndex& itemIndex);
|
||||
bool removeReservoirView(const QModelIndex& itemIndex);
|
||||
|
||||
RimCellPropertyFilter* addPropertyFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex);
|
||||
RimCellRangeFilter* addRangeFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex);
|
||||
RimReservoirView* addReservoirView(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex);
|
||||
|
||||
void updateScriptPaths();
|
||||
|
||||
private slots:
|
||||
void slotRefreshScriptTree(QString path);
|
||||
|
||||
private:
|
||||
QFileSystemWatcher* m_scriptChangeDetector;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimTreeView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RimTreeView(QWidget *parent = 0);
|
||||
|
||||
protected:
|
||||
void contextMenuEvent(QContextMenuEvent* event);
|
||||
|
||||
private slots:
|
||||
void slotAddChildItem();
|
||||
void slotDeleteItem();
|
||||
void slotShowWindow();
|
||||
|
||||
void slotAddRangeFilter();
|
||||
void slotAddSliceFilterI();
|
||||
void slotAddSliceFilterJ();
|
||||
void slotAddSliceFilterK();
|
||||
|
||||
void slotAddPropertyFilter();
|
||||
|
||||
void slotDeletePropertyFilter();
|
||||
void slotDeleteRangeFilter();
|
||||
|
||||
void slotReadScriptContentFromFile();
|
||||
void slotEditScript();
|
||||
void slotNewScript();
|
||||
void slotExecuteScript();
|
||||
|
||||
void slotAddView();
|
||||
void slotDeleteView();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class RimUiPropertyCreatorPdm : public caf::UiPropertyCreatorPdm
|
||||
{
|
||||
public:
|
||||
RimUiPropertyCreatorPdm(QObject* parent);
|
||||
|
||||
virtual void uiFields(const caf::PdmObject* object, std::vector<caf::PdmFieldHandle*>& fields) const;
|
||||
};
|
||||
123
ApplicationCode/ProjectDataModel/RimWell.cpp
Normal file
123
ApplicationCode/ProjectDataModel/RimWell.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "RimWell.h"
|
||||
#include "RivReservoirViewPartMgr.h"
|
||||
#include "RimReservoirView.h"
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimWell, "Well");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWell::RimWell()
|
||||
{
|
||||
CAF_PDM_InitObject("Well", ":/Well.png", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&name, "WellName", "Name", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&showWellLabel, "ShowWellLabel", true, "Show well label", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&showWellPipes, "ShowWellPipe", true, "Show well pipe", "", "", "");
|
||||
CAF_PDM_InitField(&pipeRadiusScaleFactor, "WellPipeRadiusScale",1.0, " Pipe radius scale", "", "", "");
|
||||
CAF_PDM_InitField(&wellPipeColor, "WellPipeColor", cvf::Color3f(0.588f, 0.588f, 0.804f), " Well pipe color", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&showWellCells, "ShowWellCells", true, "Add cells to range filter", "", "", "");
|
||||
CAF_PDM_InitField(&showWellCellFence, "ShowWellCellFence", false, " Use well fence", "", "", "");
|
||||
//CAF_PDM_InitField(&wellCellColor, "WellCellColor", cvf::Color3f(cvf::Color3f::BROWN), "Well cell color", "", "", "");
|
||||
|
||||
|
||||
|
||||
name.setHidden(true);
|
||||
|
||||
m_reservoirView = NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWell::~RimWell()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimWell::userDescriptionField()
|
||||
{
|
||||
return &name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWell::setReservoirView(RimReservoirView* ownerReservoirView)
|
||||
{
|
||||
m_reservoirView = ownerReservoirView;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWell::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (&showWellLabel == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
else if (&showWellCells == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->scheduleGeometryRegen(RivReservoirViewPartMgr::VISIBLE_WELL_CELLS);
|
||||
m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
|
||||
}
|
||||
else if (&showWellCellFence == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->scheduleGeometryRegen(RivReservoirViewPartMgr::VISIBLE_WELL_CELLS);
|
||||
m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
|
||||
}
|
||||
else if (&showWellPipes == changedField)
|
||||
{
|
||||
if (m_reservoirView) m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
else if (&wellPipeColor == changedField)
|
||||
{
|
||||
if (m_reservoirView) m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
else if (&pipeRadiusScaleFactor == changedField)
|
||||
{
|
||||
if (m_reservoirView) m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
67
ApplicationCode/ProjectDataModel/RimWell.h
Normal file
67
ApplicationCode/ProjectDataModel/RimWell.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmFieldCvfColor.h"
|
||||
|
||||
#include "RigWellResults.h"
|
||||
|
||||
class RimReservoirView;
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimWell : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
|
||||
RimWell();
|
||||
virtual ~RimWell();
|
||||
|
||||
void setReservoirView(RimReservoirView* ownerReservoirView);
|
||||
|
||||
void setWellResults(RigWellResults* wellResults) { m_wellResults = wellResults;}
|
||||
RigWellResults* wellResults() { return m_wellResults.p();}
|
||||
|
||||
virtual caf::PdmFieldHandle* userDescriptionField();
|
||||
|
||||
virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue );
|
||||
|
||||
|
||||
caf::PdmField<QString> name;
|
||||
caf::PdmField<bool> showWellLabel;
|
||||
|
||||
caf::PdmField<bool> showWellCells;
|
||||
caf::PdmField<bool> showWellCellFence;
|
||||
//caf::PdmField<cvf::Color3f> wellCellColor;
|
||||
|
||||
caf::PdmField<bool> showWellPipes;
|
||||
caf::PdmField<cvf::Color3f> wellPipeColor;
|
||||
caf::PdmField<double> pipeRadiusScaleFactor;
|
||||
|
||||
private:
|
||||
cvf::ref<RigWellResults> m_wellResults;
|
||||
|
||||
RimReservoirView* m_reservoirView;
|
||||
};
|
||||
218
ApplicationCode/ProjectDataModel/RimWellCollection.cpp
Normal file
218
ApplicationCode/ProjectDataModel/RimWellCollection.cpp
Normal file
@@ -0,0 +1,218 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmFieldCvfColor.h"
|
||||
|
||||
#include "RigWellResults.h"
|
||||
#include "RimWellCollection.h"
|
||||
#include "RimWell.h"
|
||||
#include "RimReservoirView.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void RimWellCollection::WellVisibilityEnum::setUp()
|
||||
{
|
||||
addItem(RimWellCollection::FORCE_ALL_OFF, "FORCE_ALL_OFF", "Off");
|
||||
addItem(RimWellCollection::ALL_ON, "ALL_ON", "Individual");
|
||||
//addItem(RimWellCollection::RANGE_INTERSECTING, "RANGE_INTERSECTING", "Intersecting range filter only");
|
||||
addItem(RimWellCollection::FORCE_ALL_ON, "FORCE_ALL_ON", "On");
|
||||
}
|
||||
}
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void RimWellCollection::WellFenceEnum::setUp()
|
||||
{
|
||||
addItem(RimWellCollection::K_DIRECTION, "K_DIRECTION", "K - Direction");
|
||||
addItem(RimWellCollection::J_DIRECTION, "J_DIRECTION", "J - Direction");
|
||||
addItem(RimWellCollection::I_DIRECTION, "I_DIRECTION", "I - Direction");
|
||||
setDefault(RimWellCollection::K_DIRECTION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimWellCollection, "Wells");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellCollection::RimWellCollection()
|
||||
{
|
||||
CAF_PDM_InitObject("Wells", ":/WellCollection.png", "", "");
|
||||
|
||||
CAF_PDM_InitField(&showWellHead, "ShowWellHead", true, "Show well heads", "", "", "");
|
||||
CAF_PDM_InitField(&showWellLabel, "ShowWellLabel", true, " Show well labels", "", "", "");
|
||||
CAF_PDM_InitField(&wellHeadScaleFactor, "WellHeadScale", 1.0, " Well head scale", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&wellPipeVisibility, "GlobalWellPipeVisibility", WellVisibilityEnum(ALL_ON), "Global well pipe visibility", "", "", "");
|
||||
CAF_PDM_InitField(&pipeRadiusScaleFactor, "WellPipeRadiusScale", 0.1, " Pipe radius scale", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&wellCellVisibility, "GlobalWellCellVisibility", WellVisibilityEnum(FORCE_ALL_OFF), "Add cells to range filter", "", "", "");
|
||||
CAF_PDM_InitField(&showWellCellFences, "ShowWellFences", false, " Use well fence", "", "", "");
|
||||
CAF_PDM_InitField(&wellCellFenceType, "DefaultWellFenceDirection", WellFenceEnum(K_DIRECTION), " Well Fence direction", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&wellCellTransparencyLevel, "WellCellTransparency", 0.5, "Well cell transparency", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&wells, "Wells", "Wells", "", "", "");
|
||||
|
||||
m_reservoirView = NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellCollection::~RimWellCollection()
|
||||
{
|
||||
wells.deleteChildren();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWell* RimWellCollection::findWell(QString name)
|
||||
{
|
||||
for (size_t i = 0; i < this->wells().size(); ++i)
|
||||
{
|
||||
if (this->wells()[i]->name() == name)
|
||||
{
|
||||
return this->wells()[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimWellCollection::hasVisibleWellCells()
|
||||
{
|
||||
if (this->wellCellVisibility() == FORCE_ALL_OFF) return false;
|
||||
if (this->wells().size() == 0 ) return false;
|
||||
|
||||
bool hasCells = false;
|
||||
for (size_t i = 0 ; !hasCells && i < this->wells().size(); ++i)
|
||||
{
|
||||
RimWell* well = this->wells()[i];
|
||||
if ( well && well->wellResults() && (well->showWellCells() || this->wellCellVisibility() == FORCE_ALL_ON) )
|
||||
{
|
||||
for (size_t tIdx = 0; !hasCells && tIdx < well->wellResults()->m_wellCellsTimeSteps.size(); ++tIdx )
|
||||
{
|
||||
const RigWellResultFrame& wellResultFrame = well->wellResults()->m_wellCellsTimeSteps[tIdx];
|
||||
for (size_t wsIdx = 0; !hasCells && wsIdx < wellResultFrame.m_wellResultBranches.size(); ++wsIdx)
|
||||
{
|
||||
if (wellResultFrame.m_wellResultBranches[wsIdx].m_wellCells.size() > 0 ) hasCells = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasCells) return false;
|
||||
|
||||
if (this->wellCellVisibility() == ALL_ON || this->wellCellVisibility() == FORCE_ALL_ON) return true;
|
||||
|
||||
// Todo: Handle range filter intersection
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Used to know if we need animation of timesteps due to the wells
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimWellCollection::hasVisibleWellPipes()
|
||||
{
|
||||
if (this->wellPipeVisibility() == FORCE_ALL_OFF) return false;
|
||||
if (this->wells().size() == 0 ) return false;
|
||||
if (this->wellPipeVisibility() == FORCE_ALL_ON) return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (&showWellLabel == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
if (&wellCellVisibility == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->scheduleGeometryRegen(RivReservoirViewPartMgr::VISIBLE_WELL_CELLS);
|
||||
m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
else if (&showWellCellFences == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->scheduleGeometryRegen(RivReservoirViewPartMgr::VISIBLE_WELL_CELLS);
|
||||
m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
else if (&wellCellTransparencyLevel == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
else if (&wellCellFenceType == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->scheduleGeometryRegen(RivReservoirViewPartMgr::VISIBLE_WELL_CELLS);
|
||||
m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
else if (&wellPipeVisibility == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
else if (&pipeRadiusScaleFactor == changedField || &wellHeadScaleFactor == changedField || &showWellHead == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->schedulePipeGeometryRegen();
|
||||
m_reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellCollection::setReservoirView(RimReservoirView* ownerReservoirView)
|
||||
{
|
||||
m_reservoirView = ownerReservoirView;
|
||||
}
|
||||
84
ApplicationCode/ProjectDataModel/RimWellCollection.h
Normal file
84
ApplicationCode/ProjectDataModel/RimWellCollection.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include <QString>
|
||||
|
||||
#include "RimWell.h"
|
||||
|
||||
class RimReservoirView;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimWellCollection : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
|
||||
RimWellCollection();
|
||||
virtual ~RimWellCollection();
|
||||
|
||||
void setReservoirView(RimReservoirView* ownerReservoirView);
|
||||
|
||||
enum WellVisibilityType
|
||||
{
|
||||
FORCE_ALL_OFF,
|
||||
ALL_ON,
|
||||
RANGE_INTERSECTING,
|
||||
FORCE_ALL_ON
|
||||
};
|
||||
typedef caf::AppEnum<RimWellCollection::WellVisibilityType> WellVisibilityEnum;
|
||||
|
||||
enum WellFenceType
|
||||
{
|
||||
K_DIRECTION,
|
||||
J_DIRECTION,
|
||||
I_DIRECTION
|
||||
};
|
||||
typedef caf::AppEnum<RimWellCollection::WellFenceType> WellFenceEnum;
|
||||
|
||||
caf::PdmField<bool> showWellLabel;
|
||||
|
||||
caf::PdmField<WellVisibilityEnum> wellCellVisibility;
|
||||
caf::PdmField<bool> showWellCellFences;
|
||||
caf::PdmField<WellFenceEnum> wellCellFenceType;
|
||||
caf::PdmField<double> wellCellTransparencyLevel;
|
||||
|
||||
caf::PdmField<WellVisibilityEnum> wellPipeVisibility;
|
||||
caf::PdmField<double> pipeRadiusScaleFactor;
|
||||
caf::PdmField<double> wellHeadScaleFactor;
|
||||
caf::PdmField<bool> showWellHead;
|
||||
|
||||
caf::PdmPointersField<RimWell*> wells;
|
||||
|
||||
RimWell* findWell(QString name);
|
||||
bool hasVisibleWellCells();
|
||||
bool hasVisibleWellPipes();
|
||||
|
||||
virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue );
|
||||
|
||||
private:
|
||||
RimReservoirView* m_reservoirView;
|
||||
};
|
||||
43
ApplicationCode/RIMain.cpp
Normal file
43
ApplicationCode/RIMain.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
#include "RIApplication.h"
|
||||
#include "RIMainWindow.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
RIApplication app(argc, argv);
|
||||
|
||||
QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates));
|
||||
|
||||
RIMainWindow window;
|
||||
QString platform = cvf::System::is64Bit() ? "(64bit)" : "(32bit)";
|
||||
window.setWindowTitle("ResInsight " + platform);
|
||||
window.resize(1000, 800);
|
||||
window.show();
|
||||
|
||||
if (app.parseArguments())
|
||||
{
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
20
ApplicationCode/RIStdInclude.cpp
Normal file
20
ApplicationCode/RIStdInclude.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
37
ApplicationCode/RIStdInclude.h
Normal file
37
ApplicationCode/RIStdInclude.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
// Compiler warnings in Qt 4.7.0
|
||||
#pragma warning (disable : 4311)
|
||||
#pragma warning (disable : 4312)
|
||||
|
||||
#define USE_PRECOMPILED_HEADERS
|
||||
#ifdef USE_PRECOMPILED_HEADERS
|
||||
|
||||
#include "cvfLibCore.h"
|
||||
#include "cvfLibViewing.h"
|
||||
#include "cvfLibRender.h"
|
||||
#include "cvfLibGeometry.h"
|
||||
|
||||
#include <QtCore/QtCore>
|
||||
#include <QtGui/QtGui>
|
||||
#include <QtOpenGL/QtOpenGL>
|
||||
|
||||
#endif // USE_PRECOMPILED_HEADERS
|
||||
@@ -0,0 +1,88 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
SET (ProjectName RigReservoirDataModel_UnitTests)
|
||||
project ( ${ProjectName} )
|
||||
|
||||
# Qt
|
||||
find_package (Qt4 COMPONENTS QtCore QtGui QtMain QtOpenGl REQUIRED)
|
||||
include (${QT_USE_FILE})
|
||||
|
||||
include_directories(
|
||||
${LibCore_SOURCE_DIR}
|
||||
${LibGeometry_SOURCE_DIR}
|
||||
${LibRender_SOURCE_DIR}
|
||||
${LibViewing_SOURCE_DIR}
|
||||
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/FileInterface
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ProjectDataModel
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty
|
||||
|
||||
${ResInsight_SOURCE_DIR}/cafProjectDataModel
|
||||
|
||||
${ResInsight_SOURCE_DIR}/CommonCode
|
||||
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty/Ert/ecl/include
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty/Ert/util/include
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty/Ert/well/include
|
||||
|
||||
)
|
||||
|
||||
file( GLOB CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../*.cpp )
|
||||
file( GLOB UNIT_TEST_CPP_SOURCES *.cpp )
|
||||
|
||||
|
||||
set( LINK_LIBRARIES
|
||||
CommonCode
|
||||
|
||||
LibViewing
|
||||
LibRender
|
||||
LibGeometry
|
||||
LibCore
|
||||
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
|
||||
add_executable( ${ProjectName}
|
||||
${CPP_SOURCES}
|
||||
${UNIT_TEST_CPP_SOURCES}
|
||||
|
||||
${ResInsight_SOURCE_DIR}/ThirdParty/gtest/gtest-all.cc
|
||||
)
|
||||
|
||||
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set ( LINUX_LINK_LIBRARIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../ThirdParty/Ert/ecl/lib/libecl.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../ThirdParty/Ert/util/lib/libutil.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../ThirdParty/Ert/well/lib/libwell.a
|
||||
lapack
|
||||
)
|
||||
|
||||
# Linux specific code
|
||||
set(CMAKE_CXX_FLAGS "-DCVF_LINUX -DUSE_ECL_LIB -pipe -Wextra -Woverloaded-virtual -Wformat")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG -D_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNO_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ")
|
||||
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
|
||||
target_link_libraries( ${ProjectName} ${LINK_LIBRARIES} ${LINUX_LINK_LIBRARIES})
|
||||
|
||||
|
||||
# Copy Qt Dlls
|
||||
if (MSVC)
|
||||
set (QTLIBLIST QtCore QtGui QtOpenGl)
|
||||
foreach (qtlib ${QTLIBLIST})
|
||||
|
||||
# Debug
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}d4.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug/${qtlib}d4.dll)
|
||||
|
||||
# Release
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/${qtlib}4.dll)
|
||||
endforeach( qtlib )
|
||||
endif(MSVC)
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "RigReservoir.h"
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(RigReservoirTest, BasicTest)
|
||||
{
|
||||
cvf::ref<RigWellResults> wellCellTimeHistory = new RigWellResults;
|
||||
|
||||
QDateTime wellStartTime = QDateTime::currentDateTime();
|
||||
|
||||
size_t wellTimeStepCount = 5;
|
||||
wellCellTimeHistory->m_wellCellsTimeSteps.resize(wellTimeStepCount);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < wellTimeStepCount; i++)
|
||||
{
|
||||
wellCellTimeHistory->m_wellCellsTimeSteps[i].m_timestamp = QDateTime(wellStartTime).addYears(i);
|
||||
}
|
||||
|
||||
size_t resultTimeStepCount = 2 * wellTimeStepCount;
|
||||
QList<QDateTime> resultTimes;
|
||||
for (i = 0; i < resultTimeStepCount; i++)
|
||||
{
|
||||
resultTimes.push_back(QDateTime(wellStartTime).addMonths(i * 6));
|
||||
}
|
||||
|
||||
wellCellTimeHistory->computeMappingFromResultTimeIndicesToWellTimeIndices(resultTimes);
|
||||
|
||||
for (i = 0; i < resultTimeStepCount; i++)
|
||||
{
|
||||
qDebug() << "Index" << i << "is " << wellCellTimeHistory->m_resultTimeStepIndexToWellTimeStepIndex[i];
|
||||
|
||||
const RigWellResultFrame& wellCells = wellCellTimeHistory->wellResultFrame(wellCellTimeHistory->m_resultTimeStepIndexToWellTimeStepIndex[i]);
|
||||
qDebug() << wellCells.m_timestamp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cvfTrace.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
//printf("Running main() from LibCore_UnitTests.cpp\n");
|
||||
//printf("LibCore version: %s.%s-%s (%s) \n\n", CVF_MAJOR_VERSION, CVF_MINOR_VERSION, CVF_BUILD_NUMBER, CVF_SPECIAL_BUILD);
|
||||
|
||||
cvf::Assert::setReportMode(cvf::Assert::CONSOLE);
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
std::cout << "Please press <Enter> to close the window.";
|
||||
std::cin.get();
|
||||
|
||||
return result;
|
||||
}
|
||||
154
ApplicationCode/ReservoirDataModel/RigCell.cpp
Normal file
154
ApplicationCode/ReservoirDataModel/RigCell.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RigCell.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "cvfPlane.h"
|
||||
|
||||
static size_t undefinedCornersArray[8] = {cvf::UNDEFINED_SIZE_T,
|
||||
cvf::UNDEFINED_SIZE_T,
|
||||
cvf::UNDEFINED_SIZE_T,
|
||||
cvf::UNDEFINED_SIZE_T,
|
||||
cvf::UNDEFINED_SIZE_T,
|
||||
cvf::UNDEFINED_SIZE_T,
|
||||
cvf::UNDEFINED_SIZE_T,
|
||||
cvf::UNDEFINED_SIZE_T };
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigCell::RigCell() :
|
||||
m_parentCellIndex(cvf::UNDEFINED_SIZE_T),
|
||||
m_mainGridCellIndex(cvf::UNDEFINED_SIZE_T),
|
||||
m_subGrid(NULL),
|
||||
m_hostGrid(NULL),
|
||||
m_isActive(true),
|
||||
m_isInvalid(false),
|
||||
m_isWellCell(false),
|
||||
m_globalActiveIndex(cvf::UNDEFINED_SIZE_T),
|
||||
m_cellIndex(cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
memcpy(m_cornerIndices.m_array, undefinedCornersArray, 8*sizeof(size_t));
|
||||
|
||||
m_cellFaceFaults[0] = false;
|
||||
m_cellFaceFaults[1] = false;
|
||||
m_cellFaceFaults[2] = false;
|
||||
m_cellFaceFaults[3] = false;
|
||||
m_cellFaceFaults[4] = false;
|
||||
m_cellFaceFaults[5] = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigCell::~RigCell()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RigCell::center() const
|
||||
{
|
||||
cvf::Vec3d avg(cvf::Vec3d::ZERO);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
avg += m_hostGrid->mainGrid()->nodes()[m_cornerIndices[i]];
|
||||
}
|
||||
|
||||
avg /= 8.0;
|
||||
|
||||
return avg;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RigCell::faceCenter(cvf::StructGridInterface::FaceType face) const
|
||||
{
|
||||
cvf::Vec3d avg(cvf::Vec3d::ZERO);
|
||||
|
||||
cvf::ubyte faceVertexIndices[4];
|
||||
cvf::StructGridInterface::cellFaceVertexIndices(face, faceVertexIndices);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
avg += m_hostGrid->mainGrid()->nodes()[m_cornerIndices[faceVertexIndices[i]]];
|
||||
}
|
||||
|
||||
avg /= 4.0;
|
||||
|
||||
return avg;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find the intersection between the cell and the ray. The point closest to the ray origin is returned
|
||||
/// if no intersection is found, the intersection point is untouched.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigCell::firstIntersectionPoint(const cvf::Ray& ray, cvf::Vec3d* intersectionPoint) const
|
||||
{
|
||||
CVF_ASSERT(intersectionPoint != NULL);
|
||||
|
||||
cvf::ubyte faceVertexIndices[4];
|
||||
int face;
|
||||
const std::vector<cvf::Vec3d>& nodes = m_hostGrid->mainGrid()->nodes();
|
||||
|
||||
cvf::Vec3d firstIntersection(cvf::Vec3d::ZERO);
|
||||
double minLsq = HUGE_VAL;
|
||||
|
||||
for (face = 0; face < 6 ; ++face)
|
||||
{
|
||||
cvf::StructGridInterface::cellFaceVertexIndices(static_cast<cvf::StructGridInterface::FaceType>(face), faceVertexIndices);
|
||||
cvf::Vec3d intersection;
|
||||
cvf::Vec3d faceCenter = this->faceCenter(static_cast<cvf::StructGridInterface::FaceType>(face));
|
||||
|
||||
ray.triangleIntersect(nodes[m_cornerIndices[faceVertexIndices[0]]],
|
||||
nodes[m_cornerIndices[faceVertexIndices[1]]], faceCenter, &intersection);
|
||||
|
||||
for (size_t i = 0; i < 4; ++i)
|
||||
{
|
||||
size_t next = i < 3 ? i+1 : 0;
|
||||
if ( ray.triangleIntersect( nodes[m_cornerIndices[faceVertexIndices[i]]],
|
||||
nodes[m_cornerIndices[faceVertexIndices[next]]],
|
||||
faceCenter,
|
||||
&intersection))
|
||||
{
|
||||
double lsq = (intersection - ray.origin() ).lengthSquared();
|
||||
if (lsq < minLsq)
|
||||
{
|
||||
firstIntersection = intersection;
|
||||
minLsq = lsq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minLsq != HUGE_VAL)
|
||||
{
|
||||
*intersectionPoint = firstIntersection;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
90
ApplicationCode/ReservoirDataModel/RigCell.h
Normal file
90
ApplicationCode/ReservoirDataModel/RigCell.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include "RigLocalGrid.h"
|
||||
#include "cvfStructGrid.h"
|
||||
#include "cafFixedArray.h"
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class Ray;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class RigCell
|
||||
{
|
||||
public:
|
||||
RigCell();
|
||||
~RigCell(); // Not virtual, to save space. Do not inherit from this class
|
||||
|
||||
caf::SizeTArray8& cornerIndices() { return m_cornerIndices;}
|
||||
const caf::SizeTArray8& cornerIndices() const { return m_cornerIndices;}
|
||||
|
||||
bool active() const { return m_isActive; }
|
||||
void setActive(bool val) { m_isActive = val; }
|
||||
|
||||
bool isInvalid() const { return m_isInvalid; }
|
||||
void setInvalid( bool val ) { m_isInvalid = val; }
|
||||
|
||||
bool isWellCell() const { return m_isWellCell; }
|
||||
void setAsWellCell(bool isWellCell) { m_isWellCell = isWellCell; }
|
||||
|
||||
size_t cellIndex() const { return m_cellIndex; }
|
||||
void setCellIndex(size_t val) { m_cellIndex = val; }
|
||||
|
||||
size_t globalActiveIndex() const { return m_globalActiveIndex; }
|
||||
void setGlobalActiveIndex(size_t val) { m_globalActiveIndex = val; }
|
||||
|
||||
RigLocalGrid* subGrid() const { return m_subGrid; }
|
||||
void setSubGrid(RigLocalGrid* subGrid) { m_subGrid = subGrid; }
|
||||
|
||||
RigGridBase* hostGrid() const { return m_hostGrid; }
|
||||
void setHostGrid(RigGridBase* hostGrid) { m_hostGrid = hostGrid; }
|
||||
|
||||
size_t parentCellIndex() const { return m_parentCellIndex; }
|
||||
void setParentCellIndex(size_t parentCellIndex) { m_parentCellIndex = parentCellIndex; }
|
||||
size_t mainGridCellIndex() const { return m_mainGridCellIndex; }
|
||||
void setMainGridCellIndex(size_t mainGridCellContainingThisCell) { m_mainGridCellIndex = mainGridCellContainingThisCell; }
|
||||
|
||||
void setCellFaceFault(cvf::StructGridInterface::FaceType face) { m_cellFaceFaults[face] = true; }
|
||||
bool isCellFaceFault(cvf::StructGridInterface::FaceType face) const { return m_cellFaceFaults[face]; }
|
||||
|
||||
cvf::Vec3d center() const;
|
||||
cvf::Vec3d faceCenter(cvf::StructGridInterface::FaceType face) const;
|
||||
bool firstIntersectionPoint(const cvf::Ray& ray, cvf::Vec3d* intersectionPoint) const;
|
||||
|
||||
private:
|
||||
caf::SizeTArray8 m_cornerIndices;
|
||||
|
||||
bool m_isActive;
|
||||
bool m_isInvalid;
|
||||
bool m_isWellCell;
|
||||
|
||||
RigLocalGrid* m_subGrid;
|
||||
|
||||
bool m_cellFaceFaults[6];
|
||||
|
||||
RigGridBase* m_hostGrid;
|
||||
size_t m_parentCellIndex; ///< Grid cell index of the cell in the parent grid containing this cell
|
||||
size_t m_mainGridCellIndex;
|
||||
|
||||
size_t m_globalActiveIndex; ///< This cell's running index of all the active calls in the reservoir. Used for result mapping
|
||||
size_t m_cellIndex; ///< This cells index in the grid it belongs to.
|
||||
};
|
||||
568
ApplicationCode/ReservoirDataModel/RigGridBase.cpp
Normal file
568
ApplicationCode/ReservoirDataModel/RigGridBase.cpp
Normal file
@@ -0,0 +1,568 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
#include "RigGridBase.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigCell.h"
|
||||
#include "RigReservoirCellResults.h"
|
||||
|
||||
#include "cvfAssert.h"
|
||||
|
||||
|
||||
RigGridBase::RigGridBase(RigMainGrid* mainGrid):
|
||||
m_gridPointDimensions(0,0,0),
|
||||
m_mainGrid(mainGrid),
|
||||
m_indexToStartOfCells(0)
|
||||
{
|
||||
if (mainGrid == NULL)
|
||||
{
|
||||
m_gridIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gridIndex = cvf::UNDEFINED_SIZE_T;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RigGridBase::~RigGridBase(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGridBase::setGridName(const std::string& gridName)
|
||||
{
|
||||
m_gridName = gridName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::string RigGridBase::gridName() const
|
||||
{
|
||||
return m_gridName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Do we need this ?
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigCell& RigGridBase::cell(size_t gridCellIndex)
|
||||
{
|
||||
CVF_ASSERT(m_mainGrid);
|
||||
|
||||
CVF_ASSERT(m_indexToStartOfCells + gridCellIndex < m_mainGrid->cells().size());
|
||||
|
||||
return m_mainGrid->cells()[m_indexToStartOfCells + gridCellIndex];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RigCell& RigGridBase::cell(size_t gridCellIndex) const
|
||||
{
|
||||
CVF_ASSERT(m_mainGrid);
|
||||
|
||||
return m_mainGrid->cells()[m_indexToStartOfCells + gridCellIndex];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGridBase::initSubGridParentPointer()
|
||||
{
|
||||
RigGridBase* grid = this;
|
||||
|
||||
size_t cellIdx;
|
||||
for (cellIdx = 0; cellIdx < grid->cellCount(); ++cellIdx)
|
||||
{
|
||||
RigCell& cell = grid->cell(cellIdx);
|
||||
if (cell.subGrid())
|
||||
{
|
||||
cell.subGrid()->setParentGrid(grid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find the cell index to the maingrid cell containing this cell, and store it as
|
||||
/// m_mainGridCellIndex in each cell.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGridBase::initSubCellsMainGridCellIndex()
|
||||
{
|
||||
RigGridBase* grid = this;
|
||||
if (grid->isMainGrid())
|
||||
{
|
||||
size_t cellIdx;
|
||||
for (cellIdx = 0; cellIdx < grid->cellCount(); ++cellIdx)
|
||||
{
|
||||
RigCell& cell = grid->cell(cellIdx);
|
||||
cell.setMainGridCellIndex(cellIdx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t cellIdx;
|
||||
for (cellIdx = 0; cellIdx < grid->cellCount(); ++cellIdx)
|
||||
{
|
||||
RigLocalGrid* localGrid = NULL;
|
||||
RigGridBase* parentGrid = NULL;
|
||||
|
||||
localGrid = static_cast<RigLocalGrid*>(grid);
|
||||
parentGrid = localGrid->parentGrid();
|
||||
|
||||
RigCell& cell = localGrid->cell(cellIdx);
|
||||
size_t parentCellIndex = cell.parentCellIndex();
|
||||
|
||||
while (!parentGrid->isMainGrid())
|
||||
{
|
||||
const RigCell& parentCell = parentGrid->cell(parentCellIndex);
|
||||
parentCellIndex = parentCell.parentCellIndex();
|
||||
|
||||
localGrid = static_cast<RigLocalGrid*>(parentGrid);
|
||||
parentGrid = localGrid->parentGrid();
|
||||
}
|
||||
|
||||
cell.setMainGridCellIndex(parentCellIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigGridBase::scalarSetCount() const
|
||||
{
|
||||
return m_mainGrid->results()->resultCount();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGridBase::cellCornerVertices(size_t cellIndex, cvf::Vec3d vertices[8]) const
|
||||
{
|
||||
const caf::SizeTArray8& indices = cell(cellIndex).cornerIndices();
|
||||
|
||||
vertices[0].set(m_mainGrid->nodes()[indices[0]]);
|
||||
vertices[1].set(m_mainGrid->nodes()[indices[1]]);
|
||||
vertices[2].set(m_mainGrid->nodes()[indices[2]]);
|
||||
vertices[3].set(m_mainGrid->nodes()[indices[3]]);
|
||||
vertices[4].set(m_mainGrid->nodes()[indices[4]]);
|
||||
vertices[5].set(m_mainGrid->nodes()[indices[5]]);
|
||||
vertices[6].set(m_mainGrid->nodes()[indices[6]]);
|
||||
vertices[7].set(m_mainGrid->nodes()[indices[7]]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigGridBase::cellIndexFromIJK(size_t i, size_t j, size_t k) const
|
||||
{
|
||||
size_t ci = i + j*(m_gridPointDimensions.x() - 1) + k*((m_gridPointDimensions.x() - 1)*(m_gridPointDimensions.y() - 1));
|
||||
return ci;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGridBase::cellMinMaxCordinates(size_t cellIndex, cvf::Vec3d* minCoordinate, cvf::Vec3d* maxCoordinate) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigGridBase::ijkFromCellIndex(size_t cellIndex, size_t* i, size_t* j, size_t* k) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(cellIndex < cellCount());
|
||||
|
||||
size_t index = cellIndex;
|
||||
|
||||
if (cellCountI() <= 0 || cellCountJ() <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*k = index/(cellCountI()*cellCountJ());
|
||||
index -= (*k)*(cellCountI()*cellCountJ());
|
||||
*j = index/cellCountI();
|
||||
index -= (*j)*cellCountI();
|
||||
*i = index;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigGridBase::gridPointIndexFromIJK(size_t i, size_t j, size_t k) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGridBase::cellCornerScalars(size_t timeStepIndex, size_t scalarSetIndex, size_t i, size_t j, size_t k, double scalars[8]) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigGridBase::vectorSetCount() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigGridBase::cellScalar(size_t timeStepIndex, size_t scalarSetIndex, size_t i, size_t j, size_t k) const
|
||||
{
|
||||
size_t cellIndex = cellIndexFromIJK(i, j, k);
|
||||
|
||||
return cellScalar(timeStepIndex, scalarSetIndex, cellIndex);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigGridBase::cellScalar(size_t timeStepIndex, size_t scalarSetIndex, size_t cellIndex) const
|
||||
{
|
||||
size_t resultIndex = cell(cellIndex).globalActiveIndex(); // !! Assumes results are given for active cells only !!
|
||||
if (resultIndex == cvf::UNDEFINED_SIZE_T) return HUGE_VAL;
|
||||
const std::vector< std::vector<double> >& scalarResult = m_mainGrid->results()->cellScalarResults(scalarSetIndex);
|
||||
|
||||
if (!(timeStepIndex < scalarResult.size() && resultIndex < scalarResult[timeStepIndex].size())) return HUGE_VAL;
|
||||
|
||||
return scalarResult[timeStepIndex][resultIndex];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigGridBase::cellIJKFromCoordinate(const cvf::Vec3d& coord, size_t* i, size_t* j, size_t* k) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RigGridBase::gridPointCoordinate(size_t i, size_t j, size_t k) const
|
||||
{
|
||||
cvf::Vec3d pos;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RigGridBase::minCoordinate() const
|
||||
{
|
||||
cvf::Vec3d v;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigGridBase::gridPointCountI() const
|
||||
{
|
||||
return m_gridPointDimensions.x();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigGridBase::gridPointCountJ() const
|
||||
{
|
||||
return m_gridPointDimensions.y();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigGridBase::gridPointCountK() const
|
||||
{
|
||||
return m_gridPointDimensions.z();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RigGridBase::cellCentroid(size_t cellIndex) const
|
||||
{
|
||||
cvf::Vec3d v;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RigGridBase::maxCoordinate() const
|
||||
{
|
||||
cvf::Vec3d v;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigGridBase::isCellValid(size_t i, size_t j, size_t k) const
|
||||
{
|
||||
if (i >= cellCountI() || j >= cellCountJ() || k >= cellCountK())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t idx = cellIndexFromIJK(i, j, k);
|
||||
const RigCell& c = cell(idx);
|
||||
return !c.isInvalid();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigGridBase::isCellActive(size_t i, size_t j, size_t k) const
|
||||
{
|
||||
size_t idx = cellIndexFromIJK(i, j, k);
|
||||
const RigCell& c = cell(idx);
|
||||
if (!c.active() || c.isInvalid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// TODO: Use structgrid::neighborIJKAtCellFace
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigGridBase::cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex) const
|
||||
{
|
||||
size_t ni, nj, nk;
|
||||
neighborIJKAtCellFace(i, j, k, face, &ni, &nj, &nk);
|
||||
|
||||
if (!isCellValid(ni, nj, nk))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (neighborCellIndex)
|
||||
{
|
||||
*neighborCellIndex = cellIndexFromIJK(ni, nj, nk);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const cvf::Vec3d* RigGridBase::cellVector(size_t vectorSetIndex, size_t i, size_t j, size_t k) const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGridBase::computeFaults()
|
||||
{
|
||||
//size_t k;
|
||||
#pragma omp parallel for
|
||||
for (int k = 0; k < static_cast<int>(cellCountK()); k++)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < cellCountJ(); j++)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < cellCountI(); i++)
|
||||
{
|
||||
size_t idx = cellIndexFromIJK(i, j, k);
|
||||
|
||||
RigCell& currentCell = cell(idx);
|
||||
|
||||
if (currentCell.isInvalid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t faceIdx;
|
||||
for (faceIdx = 0; faceIdx < 6; faceIdx++)
|
||||
{
|
||||
cvf::StructGridInterface::FaceType face = static_cast<cvf::StructGridInterface::FaceType>(faceIdx);
|
||||
|
||||
size_t cellNeighbourIdx = 0;
|
||||
if (!cellIJKNeighbor(i, j, k, face, &cellNeighbourIdx))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const RigCell& neighbourCell = cell(cellNeighbourIdx);
|
||||
if (neighbourCell.isInvalid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cvf::Vec3d currentCellFaceVertices[4];
|
||||
{
|
||||
cvf::ubyte faceVertexIndices[4];
|
||||
cellFaceVertexIndices(face, faceVertexIndices);
|
||||
const caf::SizeTArray8& cornerIndices = currentCell.cornerIndices();
|
||||
|
||||
currentCellFaceVertices[0].set(m_mainGrid->nodes()[cornerIndices[faceVertexIndices[0]]]);
|
||||
currentCellFaceVertices[1].set(m_mainGrid->nodes()[cornerIndices[faceVertexIndices[1]]]);
|
||||
currentCellFaceVertices[2].set(m_mainGrid->nodes()[cornerIndices[faceVertexIndices[2]]]);
|
||||
currentCellFaceVertices[3].set(m_mainGrid->nodes()[cornerIndices[faceVertexIndices[3]]]);
|
||||
}
|
||||
|
||||
cvf::Vec3d neighbourCellFaceVertices[4];
|
||||
{
|
||||
cvf::ubyte faceVertexIndices[4];
|
||||
StructGridInterface::FaceType opposite = StructGridInterface::oppositeFace(face);
|
||||
cellFaceVertexIndices(opposite, faceVertexIndices);
|
||||
const caf::SizeTArray8& cornerIndices = neighbourCell.cornerIndices();
|
||||
|
||||
neighbourCellFaceVertices[0].set(m_mainGrid->nodes()[cornerIndices[faceVertexIndices[0]]]);
|
||||
neighbourCellFaceVertices[1].set(m_mainGrid->nodes()[cornerIndices[faceVertexIndices[3]]]);
|
||||
neighbourCellFaceVertices[2].set(m_mainGrid->nodes()[cornerIndices[faceVertexIndices[2]]]);
|
||||
neighbourCellFaceVertices[3].set(m_mainGrid->nodes()[cornerIndices[faceVertexIndices[1]]]);
|
||||
}
|
||||
|
||||
bool sharedFaceVertices = true;
|
||||
|
||||
// Check if vertices are matching
|
||||
double tolerance = 1e-6;
|
||||
size_t i;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (currentCellFaceVertices[i].pointDistance(neighbourCellFaceVertices[i]) > tolerance )
|
||||
{
|
||||
sharedFaceVertices = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sharedFaceVertices)
|
||||
{
|
||||
currentCell.setCellFaceFault(face);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigGridBase::isMainGrid() const
|
||||
{
|
||||
return this == m_mainGrid;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Models with large absolute values for coordinate scalars will often end up with z-fighting due
|
||||
/// to numerical limits in float used by OpenGL to represent a position. displayModelOffset() is intended
|
||||
// to be subtracted from domain model coordinate when building geometry for visualization
|
||||
//
|
||||
// Vec3d domainModelCoord
|
||||
// Vec3d coordForVisualization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RigGridBase::displayModelOffset() const
|
||||
{
|
||||
return m_mainGrid->displayModelOffset();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the max size of the charactristic cell sizes
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigGridBase::characteristicCellSize()
|
||||
{
|
||||
double characteristicCellSize = 0;
|
||||
|
||||
double cellSizeI, cellSizeJ, cellSizeK;
|
||||
this->characteristicCellSizes(&cellSizeI, &cellSizeJ, &cellSizeK);
|
||||
|
||||
if (cellSizeI > characteristicCellSize) characteristicCellSize = cellSizeI;
|
||||
if (cellSizeJ > characteristicCellSize) characteristicCellSize = cellSizeJ;
|
||||
if (cellSizeK > characteristicCellSize) characteristicCellSize = cellSizeK;
|
||||
|
||||
return characteristicCellSize;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigGridCellFaceVisibilityFilter::isFaceVisible(size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(m_grid);
|
||||
|
||||
if (m_showFaultFaces)
|
||||
{
|
||||
size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k);
|
||||
if (m_grid->cell(cellIndex).isCellFaceFault(face))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_showExternalFaces)
|
||||
{
|
||||
size_t ni, nj, nk;
|
||||
cvf::StructGridInterface::neighborIJKAtCellFace(i, j, k, face, &ni, &nj, &nk);
|
||||
|
||||
if (ni >= m_grid->cellCountI() || nj >= m_grid->cellCountJ() || nk >= m_grid->cellCountK())
|
||||
{
|
||||
// Detected cell on edge of grid
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t neighborCellIndex = m_grid->cellIndexFromIJK(ni, nj, nk);
|
||||
const RigCell& neighborCell = m_grid->cell(neighborCellIndex);
|
||||
if (neighborCell.subGrid())
|
||||
{
|
||||
// Do not show face with a LGR neighbor. The subgrid will be responsible for displaying the face from the opposite side
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((cellVisibility != NULL) && !(*cellVisibility)[neighborCellIndex])
|
||||
{
|
||||
// Neighbor cell is not part of visible cells
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
127
ApplicationCode/ReservoirDataModel/RigGridBase.h
Normal file
127
ApplicationCode/ReservoirDataModel/RigGridBase.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include "cvfStructGrid.h"
|
||||
#include "cvfStructGridGeometryGenerator.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
class RigMainGrid;
|
||||
class RigCell;
|
||||
|
||||
class RigGridBase : public cvf::StructGridInterface
|
||||
{
|
||||
public:
|
||||
RigGridBase(RigMainGrid* mainGrid);
|
||||
virtual ~RigGridBase(void);
|
||||
|
||||
void setGridPointDimensions(const cvf::Vec3st& gridDimensions) { m_gridPointDimensions = gridDimensions;}
|
||||
cvf::Vec3st gridPointDimensions() { return m_gridPointDimensions; }
|
||||
|
||||
size_t cellCount() const { return cellCountI() * cellCountJ() * cellCountK(); }
|
||||
RigCell& cell(size_t gridCellIndex);
|
||||
const RigCell& cell(size_t gridCellIndex) const;
|
||||
|
||||
void setIndexToStartOfCells(size_t indexToStartOfCells) { m_indexToStartOfCells = indexToStartOfCells; }
|
||||
void setGridIndex(size_t index) { m_gridIndex = index; }
|
||||
size_t gridIndex() { return m_gridIndex; }
|
||||
|
||||
double characteristicCellSize();
|
||||
|
||||
std::string gridName() const;
|
||||
void setGridName(const std::string& gridName);
|
||||
|
||||
void computeFaults();
|
||||
bool isMainGrid() const;
|
||||
RigMainGrid* mainGrid() const { return m_mainGrid; }
|
||||
|
||||
protected:
|
||||
friend class RigMainGrid;//::initAllSubGridsParentGridPointer();
|
||||
void initSubGridParentPointer();
|
||||
void initSubCellsMainGridCellIndex();
|
||||
|
||||
// Interface implementation
|
||||
public:
|
||||
virtual size_t gridPointCountI() const;
|
||||
virtual size_t gridPointCountJ() const;
|
||||
virtual size_t gridPointCountK() const;
|
||||
|
||||
virtual cvf::Vec3d minCoordinate() const;
|
||||
virtual cvf::Vec3d maxCoordinate() const;
|
||||
virtual cvf::Vec3d displayModelOffset() const;
|
||||
|
||||
virtual size_t cellIndexFromIJK( size_t i, size_t j, size_t k ) const;
|
||||
virtual bool ijkFromCellIndex( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const;
|
||||
|
||||
virtual bool cellIJKFromCoordinate( const cvf::Vec3d& coord, size_t* i, size_t* j, size_t* k ) const;
|
||||
virtual void cellCornerVertices( size_t cellIndex, cvf::Vec3d vertices[8] ) const;
|
||||
virtual cvf::Vec3d cellCentroid( size_t cellIndex ) const;
|
||||
|
||||
virtual void cellMinMaxCordinates( size_t cellIndex, cvf::Vec3d* minCoordinate, cvf::Vec3d* maxCoordinate ) const;
|
||||
|
||||
virtual size_t gridPointIndexFromIJK( size_t i, size_t j, size_t k ) const;
|
||||
virtual cvf::Vec3d gridPointCoordinate( size_t i, size_t j, size_t k ) const;
|
||||
|
||||
virtual size_t scalarSetCount() const;
|
||||
virtual double cellScalar(size_t timeStepIndex, size_t scalarSetIndex, size_t i, size_t j, size_t k ) const;
|
||||
virtual double cellScalar(size_t timeStepIndex, size_t scalarSetIndex, size_t cellIndex ) const;
|
||||
|
||||
virtual void cellCornerScalars(size_t timeStepIndex, size_t scalarSetIndex, size_t i, size_t j, size_t k, double scalars[8]) const;
|
||||
|
||||
virtual size_t vectorSetCount() const;
|
||||
virtual const cvf::Vec3d* cellVector( size_t vectorSetIndex, size_t i, size_t j, size_t k ) const;
|
||||
|
||||
virtual bool isCellActive( size_t i, size_t j, size_t k ) const;
|
||||
virtual bool isCellValid( size_t i, size_t j, size_t k ) const;
|
||||
virtual bool cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex ) const;
|
||||
private:
|
||||
std::string m_gridName;
|
||||
cvf::Vec3st m_gridPointDimensions;
|
||||
size_t m_indexToStartOfCells; ///< Index into the global cell array stored in main-grid where this grids cells starts.
|
||||
size_t m_gridIndex; ///< The LGR index of this grid. Starts with 1. Main grid has index 0.
|
||||
RigMainGrid* m_mainGrid;
|
||||
};
|
||||
|
||||
|
||||
class RigGridCellFaceVisibilityFilter : public cvf::CellFaceVisibilityFilter
|
||||
{
|
||||
public:
|
||||
RigGridCellFaceVisibilityFilter(const RigGridBase* grid)
|
||||
: m_grid(grid),
|
||||
m_showFaultFaces(true),
|
||||
m_showExternalFaces(true)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool isFaceVisible( size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility ) const;
|
||||
|
||||
public:
|
||||
bool m_showFaultFaces;
|
||||
bool m_showExternalFaces;
|
||||
|
||||
private:
|
||||
const RigGridBase* m_grid;
|
||||
};
|
||||
35
ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp
Normal file
35
ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
#include "RigLocalGrid.h"
|
||||
|
||||
|
||||
|
||||
RigLocalGrid::RigLocalGrid(RigMainGrid* mainGrid):
|
||||
RigGridBase(mainGrid),
|
||||
m_parentGrid(NULL),
|
||||
m_positionInParentGrid(cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
RigLocalGrid::~RigLocalGrid()
|
||||
{
|
||||
}
|
||||
39
ApplicationCode/ReservoirDataModel/RigLocalGrid.h
Normal file
39
ApplicationCode/ReservoirDataModel/RigLocalGrid.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include "RigGridBase.h"
|
||||
|
||||
class RigLocalGrid : public RigGridBase
|
||||
{
|
||||
public:
|
||||
RigLocalGrid(RigMainGrid* mainGrid);
|
||||
virtual ~RigLocalGrid();
|
||||
|
||||
RigGridBase * parentGrid() const { return m_parentGrid; }
|
||||
void setParentGrid(RigGridBase * parentGrid) { m_parentGrid = parentGrid; }
|
||||
|
||||
size_t positionInParentGrid() const { return m_positionInParentGrid; }
|
||||
void setPositionInParentGrid(size_t positionInParentGrid) { m_positionInParentGrid = positionInParentGrid; }
|
||||
|
||||
private:
|
||||
RigGridBase * m_parentGrid;
|
||||
size_t m_positionInParentGrid;
|
||||
|
||||
};
|
||||
|
||||
346
ApplicationCode/ReservoirDataModel/RigMainGrid.cpp
Normal file
346
ApplicationCode/ReservoirDataModel/RigMainGrid.cpp
Normal file
@@ -0,0 +1,346 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigReservoirCellResults.h"
|
||||
|
||||
#include "cvfAssert.h"
|
||||
|
||||
RigMainGrid::RigMainGrid(void)
|
||||
: RigGridBase(this),
|
||||
m_activeCellPositionMin(cvf::Vec3st::UNDEFINED),
|
||||
m_activeCellPositionMax(cvf::Vec3st::UNDEFINED),
|
||||
m_validCellPositionMin(cvf::Vec3st::UNDEFINED),
|
||||
m_validCellPositionMax(cvf::Vec3st::UNDEFINED),
|
||||
m_activeCellCount(cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
m_results = new RigReservoirCellResults;
|
||||
|
||||
m_activeCellsBoundingBox.add(cvf::Vec3d::ZERO);
|
||||
m_gridIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
RigMainGrid::~RigMainGrid(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMainGrid::addLocalGrid(RigLocalGrid* localGrid)
|
||||
{
|
||||
m_localGrids.push_back(localGrid);
|
||||
localGrid->setGridIndex(m_localGrids.size()); // Maingrid itself has grid index 0
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMainGrid::initAllSubGridsParentGridPointer()
|
||||
{
|
||||
initSubGridParentPointer();
|
||||
size_t i;
|
||||
for (i = 0; i < m_localGrids.size(); ++i)
|
||||
{
|
||||
m_localGrids[i]->initSubGridParentPointer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMainGrid::initAllSubCellsMainGridCellIndex()
|
||||
{
|
||||
initSubCellsMainGridCellIndex();
|
||||
size_t i;
|
||||
for (i = 0; i < m_localGrids.size(); ++i)
|
||||
{
|
||||
m_localGrids[i]->initSubCellsMainGridCellIndex();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Calculates the number of active cells in the complete reservoir.
|
||||
/// Caches the result, so subsequent calls are fast
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigMainGrid::numActiveCells()
|
||||
{
|
||||
if (m_activeCellCount != cvf::UNDEFINED_SIZE_T) return m_activeCellCount;
|
||||
|
||||
if (m_cells.size() == 0) return 0;
|
||||
|
||||
size_t numActiveCells = 0;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < m_cells.size(); i++)
|
||||
{
|
||||
if (m_cells[i].active()) numActiveCells++;
|
||||
}
|
||||
|
||||
m_activeCellCount = numActiveCells;
|
||||
return m_activeCellCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMainGrid::activeCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const
|
||||
{
|
||||
min = m_activeCellPositionMin;
|
||||
max = m_activeCellPositionMax;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::BoundingBox RigMainGrid::activeCellsBoundingBox() const
|
||||
{
|
||||
return m_activeCellsBoundingBox;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMainGrid::validCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const
|
||||
{
|
||||
min = m_validCellPositionMin;
|
||||
max = m_validCellPositionMax;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Helper class used to find min/max range for valid and active cells
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class CellRangeBB
|
||||
{
|
||||
public:
|
||||
CellRangeBB()
|
||||
: m_min(cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T),
|
||||
m_max(cvf::Vec3st::ZERO)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void add(size_t i, size_t j, size_t k)
|
||||
{
|
||||
if (i < m_min.x()) m_min.x() = i;
|
||||
if (j < m_min.y()) m_min.y() = j;
|
||||
if (k < m_min.z()) m_min.z() = k;
|
||||
|
||||
if (i > m_max.x()) m_max.x() = i;
|
||||
if (j > m_max.y()) m_max.y() = j;
|
||||
if (k > m_max.z()) m_max.z() = k;
|
||||
}
|
||||
|
||||
public:
|
||||
cvf::Vec3st m_min;
|
||||
cvf::Vec3st m_max;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMainGrid::computeActiveAndValidCellRanges()
|
||||
{
|
||||
CellRangeBB validBB;
|
||||
CellRangeBB activeBB;
|
||||
|
||||
size_t idx;
|
||||
for (idx = 0; idx < cellCount(); idx++)
|
||||
{
|
||||
const RigCell& c = cell(idx);
|
||||
|
||||
size_t i, j, k;
|
||||
ijkFromCellIndex(idx, &i, &j, &k);
|
||||
|
||||
if (!c.isInvalid())
|
||||
{
|
||||
validBB.add(i, j, k);
|
||||
}
|
||||
|
||||
if (c.active())
|
||||
{
|
||||
activeBB.add(i, j, k);
|
||||
}
|
||||
}
|
||||
|
||||
m_validCellPositionMin = validBB.m_min;
|
||||
m_validCellPositionMax = validBB.m_max;
|
||||
|
||||
m_activeCellPositionMin = activeBB.m_min;
|
||||
m_activeCellPositionMax = activeBB.m_max;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RigMainGrid::displayModelOffset() const
|
||||
{
|
||||
return m_activeCellsBoundingBox.min();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMainGrid::computeBoundingBox()
|
||||
{
|
||||
m_activeCellsBoundingBox.reset();
|
||||
|
||||
if (m_nodes.size() == 0)
|
||||
{
|
||||
m_activeCellsBoundingBox.add(cvf::Vec3d::ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < cellCount(); i++)
|
||||
{
|
||||
const RigCell& c = cell(i);
|
||||
if (c.active())
|
||||
{
|
||||
const caf::SizeTArray8& indices = c.cornerIndices();
|
||||
|
||||
size_t idx;
|
||||
for (idx = 0; idx < 8; idx++)
|
||||
{
|
||||
m_activeCellsBoundingBox.add(m_nodes[indices[idx]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Initialize pointers from grid to parent grid
|
||||
/// Compute cell ranges for active and valid cells
|
||||
/// Compute bounding box in world coordinates based on node coordinates
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMainGrid::computeCachedData()
|
||||
{
|
||||
initAllSubGridsParentGridPointer();
|
||||
initAllSubCellsMainGridCellIndex();
|
||||
computeActiveAndValidCellRanges();
|
||||
computeBoundingBox();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMainGrid::calculateActiveCellInfo(std::vector<qint32> &gridNumber,
|
||||
std::vector<qint32> &cellI,
|
||||
std::vector<qint32> &cellJ,
|
||||
std::vector<qint32> &cellK,
|
||||
std::vector<qint32> &parentGridNumber,
|
||||
std::vector<qint32> &hostCellI,
|
||||
std::vector<qint32> &hostCellJ,
|
||||
std::vector<qint32> &hostCellK)
|
||||
{
|
||||
size_t numActiveCells = this->numActiveCells();
|
||||
|
||||
gridNumber.clear();
|
||||
cellI.clear();
|
||||
cellJ.clear();
|
||||
cellK.clear();
|
||||
parentGridNumber.clear();
|
||||
hostCellI.clear();
|
||||
hostCellJ.clear();
|
||||
hostCellK.clear();
|
||||
|
||||
gridNumber.reserve(numActiveCells);
|
||||
cellI.reserve(numActiveCells);
|
||||
cellJ.reserve(numActiveCells);
|
||||
cellK.reserve(numActiveCells);
|
||||
parentGridNumber.reserve(numActiveCells);
|
||||
hostCellI.reserve(numActiveCells);
|
||||
hostCellJ.reserve(numActiveCells);
|
||||
hostCellK.reserve(numActiveCells);
|
||||
|
||||
for (size_t cIdx = 0; cIdx < m_cells.size(); ++cIdx)
|
||||
{
|
||||
if (m_cells[cIdx].active())
|
||||
{
|
||||
RigGridBase* grid = m_cells[cIdx].hostGrid();
|
||||
CVF_ASSERT(grid != NULL);
|
||||
size_t cellIndex = m_cells[cIdx].cellIndex();
|
||||
|
||||
size_t i, j, k;
|
||||
grid->ijkFromCellIndex(cellIndex, &i, &j, &k);
|
||||
|
||||
size_t pi, pj, pk;
|
||||
RigGridBase* parentGrid = NULL;
|
||||
|
||||
if (grid->isMainGrid())
|
||||
{
|
||||
pi = i;
|
||||
pj = j;
|
||||
pk = k;
|
||||
parentGrid = grid;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t parentCellIdx = m_cells[cIdx].parentCellIndex();
|
||||
parentGrid = (static_cast<RigLocalGrid*>(grid))->parentGrid();
|
||||
CVF_ASSERT(parentGrid != NULL);
|
||||
parentGrid->ijkFromCellIndex(parentCellIdx, &pi, &pj, &pk);
|
||||
}
|
||||
|
||||
gridNumber.push_back(grid->gridIndex());
|
||||
cellI.push_back(i);
|
||||
cellJ.push_back(j);
|
||||
cellK.push_back(k);
|
||||
parentGridNumber.push_back(parentGrid->gridIndex());
|
||||
hostCellI.push_back(pi);
|
||||
hostCellJ.push_back(pj);
|
||||
hostCellK.push_back(pk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the grid with index \a localGridIndex. Main Grid itself has index 0. First LGR starts on 1
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigGridBase* RigMainGrid::gridByIndex(size_t localGridIndex)
|
||||
{
|
||||
if (localGridIndex == 0) return this;
|
||||
CVF_ASSERT(localGridIndex - 1 < m_localGrids.size()) ;
|
||||
return m_localGrids[localGridIndex-1].p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the grid with index \a localGridIndex. Main Grid itself has index 0. First LGR starts on 1
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RigGridBase* RigMainGrid::gridByIndex(size_t localGridIndex) const
|
||||
{
|
||||
if (localGridIndex == 0) return this;
|
||||
CVF_ASSERT(localGridIndex - 1 < m_localGrids.size()) ;
|
||||
return m_localGrids[localGridIndex-1].p();
|
||||
}
|
||||
89
ApplicationCode/ReservoirDataModel/RigMainGrid.h
Normal file
89
ApplicationCode/ReservoirDataModel/RigMainGrid.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include "RigGridBase.h"
|
||||
#include <vector>
|
||||
#include "RigCell.h"
|
||||
#include "RigLocalGrid.h"
|
||||
#include "cvfCollection.h"
|
||||
#include "cvfBoundingBox.h"
|
||||
#include <QtGlobal>
|
||||
|
||||
class RigReservoirCellResults;
|
||||
|
||||
class RigMainGrid : public RigGridBase
|
||||
{
|
||||
public:
|
||||
RigMainGrid();
|
||||
virtual ~RigMainGrid();
|
||||
|
||||
public:
|
||||
std::vector<cvf::Vec3d>& nodes() {return m_nodes;}
|
||||
const std::vector<cvf::Vec3d>& nodes() const {return m_nodes;}
|
||||
|
||||
std::vector<RigCell>& cells() {return m_cells;}
|
||||
const std::vector<RigCell>& cells() const {return m_cells;}
|
||||
|
||||
RigReservoirCellResults* results() {return m_results.p();}
|
||||
const RigReservoirCellResults* results() const {return m_results.p();}
|
||||
|
||||
size_t numActiveCells();
|
||||
void activeCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const;
|
||||
void validCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const;
|
||||
|
||||
void addLocalGrid(RigLocalGrid* localGrid);
|
||||
size_t gridCount() const { return m_localGrids.size() + 1; }
|
||||
RigGridBase* gridByIndex(size_t localGridIndex);
|
||||
const RigGridBase* gridByIndex(size_t localGridIndex) const;
|
||||
|
||||
void calculateActiveCellInfo(std::vector<qint32>& gridNumber,
|
||||
std::vector<qint32>& i,
|
||||
std::vector<qint32>& j,
|
||||
std::vector<qint32>& k,
|
||||
std::vector<qint32>& parentGridNumber,
|
||||
std::vector<qint32>& hostCellI,
|
||||
std::vector<qint32>& hostCellJ,
|
||||
std::vector<qint32>& hostCellK);
|
||||
void computeCachedData();
|
||||
|
||||
cvf::BoundingBox activeCellsBoundingBox() const;
|
||||
|
||||
// Overrides
|
||||
virtual cvf::Vec3d displayModelOffset() const;
|
||||
|
||||
private:
|
||||
void initAllSubGridsParentGridPointer();
|
||||
void initAllSubCellsMainGridCellIndex();
|
||||
void computeActiveAndValidCellRanges();
|
||||
void computeBoundingBox();
|
||||
private:
|
||||
std::vector<cvf::Vec3d> m_nodes; ///< Global vertex table
|
||||
std::vector<RigCell> m_cells; ///< Global array of all cells in the reservoir (including the ones in LGR's)
|
||||
cvf::Collection<RigLocalGrid> m_localGrids; ///< List of all the LGR's in this reservoir
|
||||
cvf::ref<RigReservoirCellResults> m_results;
|
||||
size_t m_activeCellCount;
|
||||
|
||||
cvf::Vec3st m_activeCellPositionMin;
|
||||
cvf::Vec3st m_activeCellPositionMax;
|
||||
cvf::Vec3st m_validCellPositionMin;
|
||||
cvf::Vec3st m_validCellPositionMax;
|
||||
|
||||
cvf::BoundingBox m_activeCellsBoundingBox;
|
||||
};
|
||||
|
||||
224
ApplicationCode/ReservoirDataModel/RigReservoir.cpp
Normal file
224
ApplicationCode/ReservoirDataModel/RigReservoir.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RIStdInclude.h"
|
||||
#include "RigReservoir.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigReservoir::RigReservoir()
|
||||
{
|
||||
m_mainGrid = new RigMainGrid();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigReservoir::~RigReservoir()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigReservoir::computeFaults()
|
||||
{
|
||||
std::vector<RigGridBase*> grids;
|
||||
allGrids(&grids);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < grids.size(); i++)
|
||||
{
|
||||
grids[i]->computeFaults();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigReservoir::allGrids(std::vector<RigGridBase*>* grids)
|
||||
{
|
||||
CVF_ASSERT(grids);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < m_mainGrid->gridCount(); i++)
|
||||
{
|
||||
grids->push_back(m_mainGrid->gridByIndex(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigReservoir::allGrids(std::vector<const RigGridBase*>* grids) const
|
||||
{
|
||||
CVF_ASSERT(grids);
|
||||
size_t i;
|
||||
for (i = 0; i < m_mainGrid->gridCount(); i++)
|
||||
{
|
||||
grids->push_back(m_mainGrid->gridByIndex(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get grid by index. The main grid has index 0, so the first lgr has index 1
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RigGridBase* RigReservoir::grid(size_t index) const
|
||||
{
|
||||
return m_mainGrid->gridByIndex(index);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigReservoir::computeWellCellsPrGrid()
|
||||
{
|
||||
// If we have computed this already, return
|
||||
if (m_wellCellsInGrid.size()) return;
|
||||
|
||||
std::vector<RigGridBase*> grids;
|
||||
this->allGrids(&grids);
|
||||
size_t gIdx;
|
||||
|
||||
// Allocate and initialize the arrays
|
||||
|
||||
m_wellCellsInGrid.resize(grids.size());
|
||||
|
||||
for (gIdx = 0; gIdx < grids.size(); ++gIdx)
|
||||
{
|
||||
if (m_wellCellsInGrid[gIdx].isNull() || m_wellCellsInGrid[gIdx]->size() != grids[gIdx]->cellCount())
|
||||
{
|
||||
m_wellCellsInGrid[gIdx] = new cvf::UByteArray;
|
||||
m_wellCellsInGrid[gIdx]->resize(grids[gIdx]->cellCount());
|
||||
|
||||
}
|
||||
m_wellCellsInGrid[gIdx]->setAll(false);
|
||||
}
|
||||
|
||||
// Fill arrays with data
|
||||
size_t wIdx;
|
||||
for (wIdx = 0; wIdx < m_wellResults.size(); ++wIdx)
|
||||
{
|
||||
size_t tIdx;
|
||||
for (tIdx = 0; tIdx < m_wellResults[wIdx]->m_wellCellsTimeSteps.size(); ++tIdx)
|
||||
{
|
||||
RigWellResultFrame& wellCells = m_wellResults[wIdx]->m_wellCellsTimeSteps[tIdx];
|
||||
|
||||
size_t gridIndex = wellCells.m_wellHead.m_gridIndex;
|
||||
size_t gridCellIndex = wellCells.m_wellHead.m_gridCellIndex;
|
||||
|
||||
CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size());
|
||||
grids[gridIndex]->cell(gridCellIndex).setAsWellCell(true);
|
||||
m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true);
|
||||
|
||||
size_t sIdx;
|
||||
for (sIdx = 0; sIdx < wellCells.m_wellResultBranches.size(); ++sIdx)
|
||||
{
|
||||
RigWellResultBranch& wellSegment = wellCells.m_wellResultBranches[sIdx];
|
||||
size_t cdIdx;
|
||||
for (cdIdx = 0; cdIdx < wellSegment.m_wellCells.size(); ++cdIdx)
|
||||
{
|
||||
gridIndex = wellSegment.m_wellCells[cdIdx].m_gridIndex;
|
||||
gridCellIndex = wellSegment.m_wellCells[cdIdx].m_gridCellIndex;
|
||||
|
||||
CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size());
|
||||
|
||||
grids[gridIndex]->cell(gridCellIndex).setAsWellCell(true);
|
||||
m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigReservoir::setWellResults(const cvf::Collection<RigWellResults>& data)
|
||||
{
|
||||
m_wellResults = data;
|
||||
m_wellCellsInGrid.clear();
|
||||
computeWellCellsPrGrid();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::UByteArray* RigReservoir::wellCellsInGrid(size_t gridIndex)
|
||||
{
|
||||
computeWellCellsPrGrid();
|
||||
CVF_ASSERT(gridIndex < m_wellCellsInGrid.size());
|
||||
|
||||
return m_wellCellsInGrid[gridIndex].p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigCell& RigReservoir::cellFromWellResultCell(const RigWellResultCell& wellResultCell)
|
||||
{
|
||||
size_t gridIndex = wellResultCell.m_gridIndex;
|
||||
size_t gridCellIndex = wellResultCell.m_gridCellIndex;
|
||||
|
||||
std::vector<RigGridBase*> grids;
|
||||
allGrids(&grids);
|
||||
|
||||
return grids[gridIndex]->cell(gridCellIndex);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigReservoir::findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace,const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const
|
||||
{
|
||||
size_t gridIndex = sourceWellCellResult.m_gridIndex;
|
||||
size_t gridCellIndex = sourceWellCellResult.m_gridCellIndex;
|
||||
|
||||
size_t otherGridIndex = otherWellCellResult.m_gridIndex;
|
||||
size_t otherGridCellIndex = otherWellCellResult.m_gridCellIndex;
|
||||
|
||||
if (gridIndex != otherGridIndex) return false;
|
||||
|
||||
std::vector<const RigGridBase*> grids;
|
||||
allGrids(&grids);
|
||||
|
||||
const RigGridBase* grid = grids[gridIndex];
|
||||
size_t i, j, k;
|
||||
grid->ijkFromCellIndex(gridCellIndex, &i, &j, &k);
|
||||
|
||||
size_t faceIdx;
|
||||
for (faceIdx = 0; faceIdx < 6; faceIdx++)
|
||||
{
|
||||
cvf::StructGridInterface::FaceType sourceFace = static_cast<cvf::StructGridInterface::FaceType>(faceIdx);
|
||||
|
||||
size_t ni, nj, nk;
|
||||
grid->neighborIJKAtCellFace(i, j, k, sourceFace, &ni, &nj, &nk);
|
||||
size_t neighborCellIndex = grid->cellIndexFromIJK(ni, nj, nk);
|
||||
|
||||
if (neighborCellIndex == otherGridCellIndex)
|
||||
{
|
||||
sharedSourceFace = sourceFace;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
61
ApplicationCode/ReservoirDataModel/RigReservoir.h
Normal file
61
ApplicationCode/ReservoirDataModel/RigReservoir.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "RigCell.h"
|
||||
#include "cvfVector3.h"
|
||||
#include "cvfAssert.h"
|
||||
#include "cvfObject.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigWellResults.h"
|
||||
|
||||
|
||||
class RigReservoir: public cvf::Object
|
||||
{
|
||||
public:
|
||||
RigReservoir();
|
||||
~RigReservoir();
|
||||
|
||||
RigMainGrid* mainGrid() { return m_mainGrid.p(); }
|
||||
const RigMainGrid* mainGrid() const { return m_mainGrid.p(); }
|
||||
|
||||
void allGrids(std::vector<RigGridBase*>* grids);
|
||||
void allGrids(std::vector<const RigGridBase*>* grids) const;
|
||||
const RigGridBase* grid(size_t index) const;
|
||||
|
||||
void setWellResults(const cvf::Collection<RigWellResults>& data);
|
||||
const cvf::Collection<RigWellResults>& wellResults() { return m_wellResults; }
|
||||
|
||||
|
||||
cvf::UByteArray* wellCellsInGrid(size_t gridIndex);
|
||||
void computeFaults();
|
||||
|
||||
RigCell& cellFromWellResultCell(const RigWellResultCell& wellResultCell);
|
||||
bool findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace, const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const;
|
||||
|
||||
|
||||
private:
|
||||
void computeWellCellsPrGrid();
|
||||
|
||||
cvf::ref<RigMainGrid> m_mainGrid;
|
||||
|
||||
cvf::Collection<RigWellResults> m_wellResults;
|
||||
cvf::Collection<cvf::UByteArray> m_wellCellsInGrid;
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user