From 792129f4beba0b41a54511f0ab0dc7d16a7961cb Mon Sep 17 00:00:00 2001 From: Lars Bilke <lars.bilke@ufz.de> Date: Wed, 25 Apr 2012 10:11:11 +0200 Subject: [PATCH] This is release version 5.3.0. Squashed commit of the following: commit 898329fc2815068adbf5b939d057f9b1fead5854 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Apr 25 09:55:50 2012 +0200 Bumped version number to 5.3.0 commit 7e4617a89adc8d3b450c1f1e3bfd6357e82a1108 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Apr 24 12:17:44 2012 +0200 fixed warnings and optimised treemodel for meshes a little bit commit 1495e376738c6ad1d6b9033577370c25921a79e9 Merge: 1377212 f5785ce Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Apr 24 11:22:44 2012 +0200 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit f5785cedc5acce373bfb42157d19178b18279be2 Merge: ebb2de2 983cb25 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Apr 24 12:06:55 2012 +0200 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources Conflicts: Qt/Gui/mainwindow.cpp commit ebb2de2a3dcd35afc40fef25bafe2f9142c4ec52 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Apr 24 11:45:54 2012 +0200 class GMSHAdaptiveMeshDensity: - added method getSteinerPoints() - added method getQuadTreeGeometry() in debug mode - inserts the QuadTree object into the GEOObjects instance class GMSHPolygonTree - added method writeAdditionalPointData() class Polygon: - substituted method getIntersectionPointPolygonLine() by method getNextIntersectionPointPolygonLine() class QuadTree: - removed some commented code (method getQuadTree()) - added method getMaxDepth() - added a getter method for depth of QuadTree node class MeshGrid: - added method createMeshGridGeometry() in debug mode class CFEMesh: - added getter method for attribute _mesh_grid that is an instance of class MeshGrid files MathLib/MathTools.{h.cpp} - inlined the sqrDist() function commit 13772126635febfee03dd19ada3b1b5bd8b0ed40 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Apr 24 11:20:57 2012 +0200 optimised meshsource a bit (meshes load faster now) commit 983cb2595a772e3a455a82d069a23dadd3ca1bfa Merge: 72e2912 451c841 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Apr 23 18:14:05 2012 +0200 Merged Dima's changes. Merge commit 'refs/merge-requests/1' of git://vismac02.intranet.ufz.de/ogs5/sources into merge-requests/1 * git://vismac02.intranet.ufz.de/ogs5/sources: Comment on possible SEGV. Emit warning when creating surface from open polyline. Correct function names in dbg output. Conflicts: FileIO/OGSIOVer4.cpp commit 72e2912d8cea3b72bbd65a5d2e880fe5030f05ac Merge: c1d018d 7f85f7a Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Apr 23 17:47:00 2012 +0200 Merge remote-tracking branch 'upstream/master' * upstream/master: git-svn-id: https://svn.ufz.de/svn/ogs/trunk/sources@10682 3895a583-e809-0410-9bb6-aa9463026377 a few fixes. some number adjustments will follow. retry. switch to direct curve derivative, rather than iterative. small changes. allow dpcdsw=0 for richards. correct ouput schemes for secondary vars with two time slots. git-svn-id: https://svn.ufz.de/svn/ogs/trunk/sources@10664 3895a583-e809-0410-9bb6-aa9463026377 thermal expansion was off! also fix to MFP outputs. Clarity for screen outputs with RSM. fix to PP. Possible fix to PI. fixes pcs without time control Fixes momentum (past error) and mass tran for multiple components. Include the FEMEnums header instead of forward declaring an enum. switched error methods enums to .num. quick bugs. version 5.2.09 Conflicts: FEM/rf_num_new.h FileIO/MeshIO/LegacyVtkInterface.cpp commit 612abcbe9c6452b51dbbda5c41646105c641ebb3 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Apr 23 13:05:00 2012 +0200 moved MshLayerMapper into MSH dir commit c1d018db2d960ee1e590deff7119071892c25a8c Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Apr 23 10:21:51 2012 +0200 added missing files commit 9fa363bb9b66013411b284fa995204429df35ab0 Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Apr 20 16:49:08 2012 +0200 included file converter into OGS-Tools menu commit 94d49c03881503b7722f67ddc8f562826401e1d7 Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Apr 20 12:33:48 2012 +0200 fixed index error in fem condition visualistion commit ed99be8234971d02228b5840c115655c7212a01a Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Apr 19 18:09:44 2012 +0200 fixed call sequence in FEMConditionSetupDialog commit 754bfdc64410b0a56d8ce9dd10b6c616603d6ff4 Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Apr 19 17:37:42 2012 +0200 corrected direction of surface normals for prism elements in msh layer extrusion commit b721c022956ce3a8bb9e7beec8810b09836d1ff8 Merge: efac021 cd79a64 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Apr 18 17:44:07 2012 +0200 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit efac0211fed5c7553df1965d2c9651a1455a520e Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Apr 18 17:43:47 2012 +0200 FEMConditions can now be edited from GUI commit 530fa8d2adccd61aca1f8c38826ff81eddf18f30 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Apr 18 12:48:13 2012 +0200 added functionality and dialog for setting up arbitrary linear conditions commit cd79a64caa904310bf3a0b3cccdfe673e4752b2c Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Apr 17 16:37:52 2012 +0200 another change due to test point in polygon functionality commit f49c4c2f50d3739bd4552066a093e594c9c674cb Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Apr 17 16:26:25 2012 +0200 due to the modification of the test criterion for the point in polygon test it was necessary to modify the TestPointInPolygon program commit 94efdac7ec75e9fe3349b76bf70ecc2bbd778a61 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Apr 17 16:11:46 2012 +0200 removed old code from GMSHInterface commit 8bbbddd98cbf15998e8d2def8786c0105b7d7d96 Merge: 0521b47 f6a1c2e Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Apr 17 15:55:54 2012 +0200 Merge branch 'master' into GMSHInterface Conflicts: FileIO/XmlIO/XmlGmlInterface.cpp UTL/MSHGEOTOOLS/mapGeoToDEM.cpp commit f6a1c2ee85ac25c10189f16a023801c6591c9be0 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Apr 17 15:33:21 2012 +0200 fixed a small compiling bug commit f32766c69ce1d224643bd4f5c1b344a6562fff94 Merge: 9a4e019 d8cf171 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Apr 17 15:15:32 2012 +0200 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 0521b47c00718646b0d387d5e2878829125f6af3 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Apr 17 15:09:10 2012 +0200 - correction of GMSHPolygonTree::insertPolyline - added documentation to class GEOObjects - added documentation to class Polygon - added method getAllIntersectionPointsPolygonLine() to class Polygon - removed some debug output from method Polyline::insertPoint() commit d8cf171633f32114236f3f2cc0a5490bd7cd876b Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Apr 17 11:22:14 2012 +0200 fixed casting error in linux commit 1e4d40681fa4e0f1c00571807cc60c2ba236661e Merge: 4064f83 8572862 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Apr 17 11:12:28 2012 +0200 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 4064f83e1df70b35e001dde8a5dd33aa99e948b5 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Apr 17 11:12:07 2012 +0200 direct conditions are now integrated into file converter commit 857286272fa34274696ab08013f06573c4bd1a9c Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Mar 30 13:41:25 2012 +0200 README code indention. commit f383fda08a9dfa960a0c5ed88d8a3577e76b6fae Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Apr 16 17:59:31 2012 +0200 direct source terms from cnd-files are now pretty seamslessly integrated, direct st's from ascii files still works (lots of changes while reading) but requires a lot of extra code and should be removed asap commit 451c841de0ace2b602c2d650e6588c3df079a64e Author: Dmitri Naumov <dmitri.naumov@ufz.de> Date: Mon Apr 16 11:44:33 2012 +0200 Comment on possible SEGV. Signed-off-by: Dmitri Naumov <dmitri.naumov@ufz.de> commit b15002811fc4768c143dcec12626962b45bf614d Author: Dmitri Naumov <dmitri.naumov@ufz.de> Date: Mon Apr 16 11:43:53 2012 +0200 Emit warning when creating surface from open polyline. Signed-off-by: Dmitri Naumov <dmitri.naumov@ufz.de> commit 22f33cd29b6acbd9670098869825c4b6ad3c2d68 Author: Dmitri Naumov <dmitri.naumov@ufz.de> Date: Mon Apr 16 11:43:32 2012 +0200 Correct function names in dbg output. Signed-off-by: Dmitri Naumov <dmitri.naumov@ufz.de> commit 65eb0e02f739124a15515ec512bb0152d5624d59 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Apr 16 12:31:28 2012 +0200 changed structure of distribution-storage in FEMCondition commit 6fda771d82ef866b1bf6ef0503b52c0a5bbcaedf Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Apr 13 14:59:51 2012 +0200 added cnd2bc conversion to OGSFileConverter commit 3fee6d046ba77391afc3f5702358e24070236f11 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Fri Apr 13 14:52:03 2012 +0200 backup of daily work - still errors within the code commit eb74a5afe4760db54fe0a59617c83c3347cf6a9e Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Apr 13 11:50:54 2012 +0200 fixed error management in XmlGmlInterface - writer commit 9a7f91ccb536dc2546c325eec86f38ac38baf3c2 Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Apr 13 11:35:48 2012 +0200 added ASCII-Conditions to XML-Conditions Conversion to ConversionTool; added/extended error management in GeoIO commit 9b28b754bac7ff68c8f9c1d166d7fefbf89e4f7a Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Wed Apr 11 16:34:57 2012 +0200 backup of work commit c09619c33971b3da6acf4be6d110dcf6eac87d9f Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Apr 4 17:26:35 2012 +0200 started implementation of OGSFileConverter (incl. GUI) for conversion of xml-format to legacy formats and back. geometry conversions are implemented in both directions, condition conversions are still missing. commit 9a4e019856c72cce1d0eab1d857a02bdb1ef614e Merge: a8671b1 b6c984e Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Wed Apr 4 12:30:13 2012 +0200 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources Conflicts: FileIO/MeshIO/OGSMeshIO.cpp commit 1420f6b0f31039502b9a737ea99e85674197f594 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Wed Apr 4 12:26:00 2012 +0200 rewrote GMSHInterface - still not complete (inserting stations is missing) - backup commit b6c984e24976c7ad4e6b30469ffd05d25a39c9a7 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Apr 3 12:59:37 2012 +0200 re-implemented generation of mapped multi-layer meshes and removed old method; implemented method to get surface-mesh from a multi-layer-mesh; changed input and output of distribution information in XmlCndInterface (part of ongoing changes for universal handling of fem-conditions) commit 3c1170979e360820cf0a85955a4e5cd3ebe8c028 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Mar 28 16:53:45 2012 +0200 removed changes specific to the rappbode-demo commit b2671cdd375dc16df8b3dea5ab620c1bce454042 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Mar 28 11:28:10 2012 +0200 more adaptions for rappbode-simulation-demo commit fea8c8904d33364f63abe484010faa7710deca24 Merge: 31fb422 4a96f39 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Mar 28 08:31:53 2012 +0200 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 31fb4227a47f7f1f241a50fe25172f4fdadc9a3b Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Mar 28 08:31:38 2012 +0200 fixed some performance issues (pvs-studio), special visualisation changes for bode-boatpath commit 4a96f39d7589cf396b0485110d3b207d4b862f57 Merge: 444f604 2624e59 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Mar 26 11:33:34 2012 +0200 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources * 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources: removed last remnants of old mapping code, fixed initialisation issue in FEM-Cond-Setup commit 444f604aea5ad92467beca8dc077478d5e290ab3 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Mar 26 11:33:21 2012 +0200 Fixed building of utils on Linux. commit 2624e59cd05f3b3efb5d189eb63ed2f0d69dca27 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Mar 26 10:27:37 2012 +0200 removed last remnants of old mapping code, fixed initialisation issue in FEM-Cond-Setup commit eb6e3dccc0744a08131a000edcd9a36c0777fd25 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Mar 21 09:26:56 2012 +0100 integrated new interpolation scheme into MshLayerMapper commit efd9aa53dba0c6a66a6cf3a941083a2dd8216cff Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Mar 20 14:00:35 2012 +0100 GL_COMBINE is not available on Windows, GL_MODULATE gives the same results. commit 3715583bcefd3bc462f9b9376062a118b0a2ec53 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Mar 20 12:26:13 2012 +0100 One more missing include. commit 9aee41d450810bde2fed9bc64b4d1c90a59ff490 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Mar 20 12:07:14 2012 +0100 Added missing include. commit 760340711a8ec416577d7ee0cce361ba575283ff Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Mar 20 11:20:02 2012 +0100 OpenSG-exported textured objects are now correctly lit. Set EnvMode to GL_COMBINE in vtkOsgConverter's texture chunk. commit 1089d95ca25c41e9e65bb1ea66d0c1a318a78f92 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Mar 19 11:11:39 2012 +0100 Added a comment how to apply default colored lut to a grayscale texture. commit cff2ff75b91f5bef7bcc209717751a619fe317aa Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Mar 14 15:16:03 2012 +0100 Cloning the lut is not needed in the ParaView OpenSG Exporter. commit 0b3e51128518ea69a8cd3fd5e073cc2681bd0cba Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Mar 16 11:41:24 2012 +0100 fixed an issue with TIFF palette selection; added method for assigning borehole profiles to station objects commit 5e2be90424a7ee2a98153cdce6251b685839784f Merge: 1169ad1 4b1207b Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Mar 14 10:35:20 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 1169ad1d5dd6b6c8ecbd36a99ea2e49867434e5e Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Mar 14 10:35:04 2012 +0100 updated mapGeoToDEM-Tool to also map station data commit 4b1207b43392e63c6e7ea69008c63e331fb00497 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Mar 13 12:09:57 2012 +0100 Fixed overriding of compiler flags on not debug builds. commit c3c9b57e28bec625e5da33a2c2278d2e11055c68 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Mar 12 16:54:17 2012 +0100 Add lut now remembers its directory. commit 26ba0869bd9f537e91b52ff1d81cc771c73ffd3f Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Mar 12 16:46:29 2012 +0100 Fixed lut bug in OpenSG converter. commit 5042591c6a581a8c18b8841aa98e86c242ede51e Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Fri Mar 9 12:43:27 2012 +0100 save work - version of GMSHInterface does not work! commit 3cff111140a618c832a0daa16ce94c5d2dff4680 Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Mar 8 18:13:22 2012 +0100 fixed issue with precision in mesh-output; added GridAdapter Copy-Constructor; added extendable removeMeshNodes tool to remove nodes and adjacent elements according to given keywords commit d456c0f844d057a78fe77a373935a1de330cf2d6 Merge: 83c8eb2 a8671b1 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Mar 8 12:30:51 2012 +0100 Merge branch 'master' into GMSHInterface commit a8671b18ca1dea76c0d0ce92e87b4c7f76dc9f3a Merge: 038b128 54ec3a4 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Mar 8 12:30:26 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 038b128fc47af610d3c92715be97f68d43345025 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Mar 8 12:29:02 2012 +0100 changed the output precision for writing mesh node coordinates inserted some debug code in equation_class.cpp commit 54ec3a4746621468714b71d25a27e70461754a26 Merge: f67be01 dd0f8f9 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Mar 6 18:20:11 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit f67be017cb5dfb12f17b22b16272801407cef0db Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Mar 6 18:19:08 2012 +0100 fixed array initialisation error for mesh-construction from double array (i.e. netcdf) commit 09cdd146156fa8614da399dc2dbca90852dcaa3a Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Mar 6 15:20:57 2012 +0100 fixed index error in coordinate-output for mesh elements commit 20124e4d67818f828329476d4900a3e476cc4db5 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Mar 6 15:11:41 2012 +0100 fixed index error for strat-index in borehole-source-object commit 83c8eb211c5ac1e60d139907da14ab50aa7a5604 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Mon Mar 5 16:07:52 2012 +0100 some improvements in GMSHInterface - not yet finished - under very heavy construction! commit dd0f8f9223c6932d3d820438f4de5e99f77e28e3 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Mar 5 12:09:03 2012 +0100 Added a directory for every file type which is loaded to QSettings. commit 9042ca6f2e2a7cf167b4eba0fe39eae39a7f7cb8 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Mar 5 11:57:25 2012 +0100 Refactord pipeline item remove code. VtkAlgorithmProperties has a new member _removable which should be set to false in a derived class which should be not removable from the pipeline view. commit 4053333b095205d17cde76e902b51b869ab0b748 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Mar 5 11:28:48 2012 +0100 OpenSG Export works so far. Cell data is converted to point data. To correctly export meshes comment out line 104-115 in vtkOsgConverter. commit 634300e426439ea1b2fba76810d43b0c10a6688b Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Mar 2 17:14:25 2012 +0100 WIP: getting OpenSG export to work properly. commit c744aec853bdc14b63d1550b905e4bf9287c0489 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Mar 2 17:13:45 2012 +0100 Moved VtkAlgorithmProperties to base class VtkVisPipelineItem. Fixed getting the right VtkAlgorithmProperties in VisPipelineView::contextMenuEvent(). commit 3f2fc6ecb9780282107825fdd74adf5b1a010c56 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Mar 1 16:09:25 2012 +0100 Fixed a bug where entering zero into the z-scale field hides the data permanently. commit b1de459fd44988c2ebb7192037e5eece5911ecf3 Merge: 31238be 85cbb30 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Mar 1 14:04:14 2012 +0100 Merge remote-tracking branch 'upstream/master' * upstream/master: updated version to 5.2.08 merged OGS-GEM-MT changes into trunk Recovery GetElementFaceTri..Quad bug fix for benchmark H2/LabGasInjec Conflicts: FileIO/MeshIO/LegacyVtkInterface.cpp commit 22d2f7ef9af77d5cdd9cde8dac9f49e97ffff729 Merge: 2c455fa 31238be Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Mar 1 12:49:09 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 2c455fabac630b0359a613f076983798bc85b416 Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Mar 1 12:48:45 2012 +0100 fixed issue with layer mapping due to to transition to VtkRaster commit 31238be45cd410ad16bfcc34d45741f8bbe0e4d0 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Mar 1 12:39:48 2012 +0100 Added warning when lut can not be applied. commit cb897f5e872f585d893eee6c7b77b905d23975c6 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Mar 1 12:33:57 2012 +0100 Fixed setting lut on tubes. commit 09fe6aa96ed78eea71922ec7877b7f10741b68d6 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Mar 1 12:10:38 2012 +0100 Revert images should not be interpolated. commit eb5079092069c935e55e672117d47f2598cc2b64 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Mar 1 11:38:41 2012 +0100 Removed OGSRaster. Refactored VtkBGImageSource which is used for exporting raster data to OpenSG to be used similar to VtkTextureOnSurfaceFilter. commit c9db2e3e289476472ebbc8c756362a999ce5cc1b Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Mar 1 10:20:26 2012 +0100 - fixed a compile error within UTL programms - fixed some warnings commit 7eafc3b3b2722409d9a22efb83d7bc2d574542a3 Merge: 56a2948 c9372d4 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Mar 1 09:52:29 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 56a29485b5ab55730fed9be5faf9b2d327ae9cf9 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Mar 1 09:51:04 2012 +0100 commented some debug messages in class OctTree added MeshGrid algorithm to the testMeshSearchAlgorithms program commit c9372d47a444c741bb552997eba6c0238d04cfcf Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 29 16:16:42 2012 +0100 Finished Surfer-Import, removed old OGSRaster-class everywhere except in OpenSG-Raster Export and replaced with VtkRaster commit 00114568b69db6744e4000d0471e554d3ab79fc5 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 29 15:37:01 2012 +0100 added import for Surfer-ASCII raster files commit a564cb0b0dbad136202ea30d0ef52d1dff23cde5 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 29 12:57:15 2012 +0100 added optional station_value attribute to station objects commit 7d26180b78bafae0cbba9d3c662507c3a4e0ca79 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 29 11:38:18 2012 +0100 removed color-attribute from stations (not needed) commit e20ac6a636d8a56a8817a81cb9fa41361f3e57e1 Merge: 353b36e dcf274e Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 29 11:29:20 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 353b36e90b73d0c783ac75ca4330ae2f17d19e09 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 29 11:05:14 2012 +0100 more work on creating, saving and loading of DIRECT terms commit abefb68b8666104f11ffd64a95a408c69edc50ee Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Feb 28 15:16:18 2012 +0100 changed output precision for gml files in rotateMesh programm some changes in class CNode in order to make it possible to use it with class template OctTree changes in the testMeshSearchAlgorithm programm commit 8654b1b9737db7d535b38e3a3550a2655ae3e386 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Feb 28 13:12:32 2012 +0100 - added test programm for mesh search algorithms - changes due to changes in the interface of the XML classes commit dcf274ee6e018f0b889b291cc1aff451f950c25a Merge: 50f3233 e6ea6a3 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Feb 28 12:17:33 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources Conflicts: UTL/FileConverter/generateMatPropsFromMatID.cpp commit 50f3233ed1080a1672ac9edd46b5885159a1300e Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Feb 28 12:12:25 2012 +0100 - implemented class OctTree for faster search - will be tested soon - added access operators to CNode (access to coordinates) - modifications in utility programms GMSH2OGS.cpp, generateMatPropsFromMatID.cpp, mainModifyMeshProperties.cpp and rotateMesh.cpp due to changes in class FileIO::OGSMeshIO commit e6ea6a3041e595e4172969c83dcde643a78a04d5 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 27 16:41:02 2012 +0100 Fix for subverison cmake script. commit bf0bd61ca5cb31542b4c78f6414b90230f4fc9aa Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 27 14:51:50 2012 +0100 Fixed FindMsysGit^. commit dfaa87841493a96a42a152c45d95229da8b44678 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 27 12:43:54 2012 +0100 Some CMake improvements: msysgit unix tools will be used on Windows. commit 9cbfe842f71d1d35b3b973c6f81d499259a58caf Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 27 09:51:41 2012 +0100 Fixed CMake include order. commit 5ccee0ec9720a236715fefced48e6fe821344127 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 27 12:10:40 2012 +0100 finished conversion of xml-classes into new hierarchy, adapted tests + tools commit 8f0577eeedb9781dc552483fc361cc2e6b904323 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 27 11:23:06 2012 +0100 derived all xml-classes from Writer-class commit 563a4212b6cac1c460ebf93d56fc250a9c00ffb5 Merge: e961cab 4728f1b Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 27 09:17:25 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit e961cab2f3946ed62e94859a2b78cbcd2cade1f5 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 27 09:17:18 2012 +0100 integration of direct st generator into gui (not yet finished) commit 4728f1bd3b7a3700f66882861592f03d8ce1b11c Merge: d1813d5 ac93e47 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 27 09:15:01 2012 +0100 Merge branch 'fileio_baseclass' * fileio_baseclass: Moved write method to protected. WIP: Reader. Refactored OGSMeshIO to use the new Writer base class. Added output parameter to QtTestrunner. Removed wrong method. Added Writer base class. commit ac93e47021e8a5ad0976818c45bb2c34b878c475 Merge: 62d0313 d1813d5 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 27 09:13:56 2012 +0100 Merge branch 'master' into fileio_baseclass * master: (48 commits) Threshold filter gets the right range. Added missing include. Mapper automatically uses the range from its associated lookup table. Fixed threshold filter color lookup. Fixed threshold filter lookup table coloring. Added -o switch for additional CMake options. fixed a bug in rotateMesh program (deleted an object twice) fixed a normalisation thingy changed distance computation in quadtree fixed a compile error in OGSError - Changed reading gli files, the function returns now a std::vector<std::string>. In this vector of strings possible error messages are catched and can be desplayed later on. - Changed test if point is already in quadtree. just some cosmetic changes... Reovery MarkInterface_mHM_Hydro_3D() for marking nodes on the top surface Fixed empty VtkAlgorithmProperties in point set item. added an "epsilon" to the search of mesh nodes within surfaces Correct the getElementFaces... some fixes for surface integration via GUI added an optional parameter to rotateMesh program Fixed css link on doxygen. Removed debug output. modified rotation programm ... commit 62d0313968f97f72e2228778d03628cc5576304e Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 27 09:13:30 2012 +0100 Moved write method to protected. commit d1813d5a56af4e2fccd8a95dd3040735d10bfae4 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Feb 24 11:44:14 2012 +0100 Threshold filter gets the right range. commit 96116a1c753412f82241088ed7311a5b3a26b886 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Feb 24 09:00:17 2012 +0100 Added missing include. commit 3b6c606acc322821349d7285c9511f15529ca161 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 23 17:59:34 2012 +0100 Mapper automatically uses the range from its associated lookup table. Simplification of lookup table code. Fixed VtkCompositeImageToCylindersFilter table range property. commit 01a5b01759568f1d69fd4f1966da8736f1fbb021 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 23 16:50:11 2012 +0100 Fixed threshold filter color lookup. TODO: Get contour filter to work with color lookup. commit 46ba4f9beb8d28074c00f88f449c773b7270ffe5 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 22 14:38:09 2012 +0100 Fixed threshold filter lookup table coloring. Fixed order of initialization steps in VtkVisPointSetItem. Extracted method getScalarArrayNames() from VtkVisTabWidget to VtkVisPipelineItem. commit 6fdf6e2f57ceb230418f51cb5299fff18056d338 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 22 14:36:22 2012 +0100 Added -o switch for additional CMake options. commit 8ee83bc47538d9e4af58fdbd060a19eb12b21094 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Wed Feb 22 15:24:47 2012 +0100 fixed a bug in rotateMesh program (deleted an object twice) commit 2821effa909e75be126de2fe47e54fcc14fd682e Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 22 09:42:38 2012 +0100 fixed a normalisation thingy commit 12b72da924db3f785fdf9900c3faa4b321a44261 Merge: e9c22d5 ddd8d3e Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Feb 21 14:12:01 2012 +0100 resolved conflict commit ddd8d3e74380b6dcb747f182f1c936171d30e9c6 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Feb 21 13:57:00 2012 +0100 changed distance computation in quadtree fixed a compile error in OGSError commit d3a98155b49c86c6b293c0f9d02ccc4b1a726772 Merge: 490999f b1ae64c Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Feb 21 13:20:46 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 490999f4558f19accc59b76b00eaab1a468c6350 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Feb 21 13:18:03 2012 +0100 - Changed reading gli files, the function returns now a std::vector<std::string>. In this vector of strings possible error messages are catched and can be desplayed later on. - Changed test if point is already in quadtree. commit e9c22d54900b8f7cb473f46e0b47235383b91627 Merge: 52493ed b55ee92 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Feb 21 12:14:12 2012 +0100 Merge remote branch 'svn/master' commit 52493edf0750d520190677f13fab83590e732253 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Feb 21 12:13:07 2012 +0100 just some cosmetic changes... commit b1ae64cb83fa95f2482852835378d64a8103490e Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 20 12:38:07 2012 +0100 Fixed empty VtkAlgorithmProperties in point set item. Signed-off-by: Lars Bilke <lars.bilke@ufz.de> commit e27eb60168b84f59cedb9b6df3c4288348368f63 Merge: a63e01f c0c4b77 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 20 12:20:33 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit a63e01f0a51a4cce364440d8903655dea3e39bb0 Merge: 3f5e071 5b7edb6 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 20 12:16:49 2012 +0100 merged commit c0c4b7775bf9b6a1a4e084fc29ff79419ee8e473 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Mon Feb 20 11:58:09 2012 +0100 added an "epsilon" to the search of mesh nodes within surfaces commit 3f5e071a698aec09da73506447fa4c956e4e5875 Merge: bceced0 20bb3e1 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 20 10:09:26 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit bceced04225588064698167f71bd06c0f69470c2 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 20 10:09:05 2012 +0100 some fixes for surface integration via GUI commit 20bb3e1f8411cb9067b5575571685d9ead7dcac0 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Mon Feb 20 09:08:41 2012 +0100 added an optional parameter to rotateMesh program commit 589087cd343d38234a67c5905f13b138d178fa7f Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Feb 17 11:48:06 2012 +0100 Fixed css link on doxygen. commit b7eceeaad9b1b39f5eee3742b829cc259fabe751 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Feb 17 10:23:01 2012 +0100 Removed debug output. commit 0940bdf4ed24015be3779c4e75c4b3d4518c1365 Merge: 6613ccd f7103f1 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Fri Feb 17 13:37:27 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources Conflicts: UTL/MSHGEOTOOLS/CMakeLists.txt commit 6613ccd022b7a31059251a457c91398da7ee2173 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Fri Feb 17 13:18:41 2012 +0100 modified rotation programm commit f7103f1ed56e2728b99ced82b353fd36703cdcd3 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Feb 17 09:55:10 2012 +0100 Refactored geotiff library inclusion. commit c38f395249a17c1f6eb0df0d6c4f4753c42dc1ef Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Fri Feb 17 08:39:52 2012 +0100 fixed compilation error and removed some warnings commit bf687438c60074bccc68ae4cc200c4cbabb8d106 Merge: a75f51f 64e0f8b Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Feb 16 18:09:24 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit a75f51f710f24ce4488fdee9d74dad63767eff6d Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Feb 16 18:09:07 2012 +0100 fixed yet another colour-lookup-table bug; implemented first attempt for surface integration of direct source terms (based on WW code, not tested yet) commit 64e0f8b2f252bbcdb5209e848b0eb43436d4fa63 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 16 16:31:37 2012 +0100 Fixed crashes which occurred when wildly clicking in a tree view happened. commit c9f56a5f15001e681947178bab4addcc59cdc9e1 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 16 14:52:35 2012 +0100 Fixed ConvertGliToVtk compile error on older boost version. commit 58d5e805bcc7059d011a236e598fbc7fb79b889e Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 16 14:24:30 2012 +0100 Remember directory for lookup table. commit 286a6a229dbb90ae1ff839e92c68499a83d8d920 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Feb 16 15:48:20 2012 +0100 removed some warnings commit 5eb90f77724a8c498f00d557d17b0c2c690bd616 Merge: 40ec71e 354a0d6 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Feb 16 15:27:30 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 40ec71ec99eba7c5baad3bf5c5f5c6225ff6eae7 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Feb 16 15:26:33 2012 +0100 improved search mesh nodes in (geometric) surfaces commit 354a0d6a4693c7747fa77b04bf3b2e03e070732f Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 16 10:28:07 2012 +0100 Fixed coloring of assigned textures in VtkTextureOnSurfaceFilter. .# Please enter the commit message for your changes. Lines starting commit 1fcc6bf496930d56cddc7794b50f112d3db8354f Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 16 10:27:29 2012 +0100 One more fix for correctly creating lookup tables in VtkVisPointSetItem. commit db2eb96ff72d2e12303e80c7f5b5f0ef62148f25 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 15 16:37:19 2012 +0100 Fixed a bug in FindMKL.cmake on *nix 32-bit. commit 8af412911be9338561d39b0b25500c3c74964bcc Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 15 17:37:05 2012 +0100 fixed an issue where colourlookuptables wouldn't work correctly if the offset was far from 0 commit 9d6acd2cbd0471ad0a918e26f42d40dff408f2b4 Merge: 8310dda 62da5e0 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 15 12:21:01 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 8310dda681322979b296588651497b03e65df5cc Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 15 12:20:43 2012 +0100 adjusted colour table scaling commit 62da5e0810b84210aad4c92e284024d47e39b32c Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 15 11:09:11 2012 +0100 Fixed UTL build on Mac. commit f39f15a96f19a22d2fd7a524e48dab114efdaea2 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 15 11:09:00 2012 +0100 Missing file. commit 1aca305cb6e62c62cc3bf329893ccd3dc12b29b9 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 15 09:51:45 2012 +0100 Split VtkAlgorithmProperties into header and source file. commit a30fe0cd68c150f0fe96c5ae33d1972241696fb5 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Feb 14 17:26:05 2012 +0100 Removed _activeAttribute from VtkVisPointSetItem. The active attribute is stored in VtkVisPointSetItem::_vtkProps. commit 18a36f0187d8fecc8ffbd1f58254f6c5534a4c1a Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Feb 14 17:13:00 2012 +0100 Fixed color lookup table functionality. commit a52ae05242c40e7d24583d44aa33f3fb07be1545 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 15 11:42:57 2012 +0100 Fixed building of UTL. commit bae9625408a6a311f54a3a667520ef32800e1f86 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 13 17:48:44 2012 +0100 fixed another small thing concerning borehole depth initialisation commit 75f8b113ddd90d44cbe5ece1a2b1fe2ade1e67fa Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 13 17:22:54 2012 +0100 WIP: Reader. commit ecb255fd2c1073219d3ccf17370ba7e9169e4e70 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 13 16:34:21 2012 +0100 Refactored OGSMeshIO to use the new Writer base class. commit 8c51dce8868b030be2ed3fe774e653655f43f856 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 13 16:33:00 2012 +0100 Added output parameter to QtTestrunner. When this parameter is given the output of a failed test is written to tests/results/. commit 079d4c4dfaaba79d4cafe8bf8f4248cb902c6dcd Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 13 16:25:14 2012 +0100 Removed wrong method. commit a9323b6ec1ebf20ceda611909a6418f586268598 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Feb 13 16:23:55 2012 +0100 Added Writer base class. commit 503f5230093701a7b6911fbc20e78f02f838b011 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 13 12:49:11 2012 +0100 fixed bug were vtk visualisation (lines to tubes) would produce false results if borehole had soil layers with thickness 0 commit 1fbe37e72758d77f1891ef558d37a8a6d723f3ee Merge: 4612a75 cf48800 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 13 10:40:41 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit cf48800a11f3583030a0dac777e0272d323fd8c4 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Feb 10 15:40:55 2012 +0100 Fixed some small bug in vtk output. commit e58e14908d9aac29f3bce7236de4c531bfc2bff9 Merge: 9939d3b 2829668 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Feb 10 09:48:19 2012 +0100 Merge branch 'vtk_tensors_output' * vtk_tensors_output: Some formatting. Fixed non VTK build. Added Option OGS_DONT_USE_VTK. Implemented eigenvector vtk output of tensors with vtkMath class. Removed Eigenvectors functions. Added Eigenvector calculation from vtk. Bumped minimum cmake version to 2.8.3. commit 28296684675f6275d2c720a7da263e2174bb2c83 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Feb 10 09:46:41 2012 +0100 Some formatting. commit 49b080140f73a1bfe9265625bb9ffb89343a4516 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 9 18:10:44 2012 +0100 Fixed non VTK build. commit 2f8fdaf66725260a425d9694f00d0faf31e8a90a Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 9 18:05:51 2012 +0100 Added Option OGS_DONT_USE_VTK. commit 82c3241ea73a9dcf807544036f427053d5c95f13 Merge: 94f865d 9939d3b Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 9 17:16:00 2012 +0100 Merge branch 'master' into vtk_tensors_output * master: Reversed order in EQ_ASSERTS. commit 9939d3b7ecdef4885341f7c1f617be0330ce6fd6 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 9 17:10:39 2012 +0100 Reversed order in EQ_ASSERTS. commit 94f865d16d147df4be1d78736df67940a5008f18 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 9 17:07:28 2012 +0100 Implemented eigenvector vtk output of tensors with vtkMath class. The eigenvectors are normalized and then multiplied by their eigenvalues. In *.out file the output array names must be in that order: *_XX *_XY *_YY *_ZZ *_XZ *_YZ commit 4f37bb1426099b6ea4f627015ec32321c3760652 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 9 17:06:09 2012 +0100 Removed Eigenvectors functions. commit 4612a75af5666acad9e646adc69cebdfccdf63b1 Merge: 44f7008 852573b Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 8 18:05:24 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 44f7008794ed5e60df142d66d4ad2ed545a812a4 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Feb 8 14:34:59 2012 +0100 added tool to map elevation of points in gml-files according to DEM commit f904321eecd01f63a8be0d60d55ef4d27cca591a Merge: 32e8975 852573b Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Wed Feb 8 13:45:31 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 32e897574dab665da37ec540f76cd18b83f4600b Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Wed Feb 8 13:43:48 2012 +0100 - rotateMesh - added functionality - first try to improve geometry-mesh-search commit b74bdd71724b717c42598e51cea43de9e6286670 Merge: 4317f8d 852573b Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 8 12:06:08 2012 +0100 Merge branch 'master' into vtk_tensors_output * master: (119 commits) QtDataView must be built before VtkVis. Reintroduced getter methods on VtkGeoImageSource. Fixed two warnings. resolved various issues with netCDF import; NetCDF data can be imported as raster (and texture) now; ImageAlgorithms can be created from data arrays now; textures now use VTKRaster class; textures are currently using a default colour table - this should be prevented Fixed image to lines filter. Added backface culling option under Visualization Settings. - introduced a new nodes search algorithm (class MeshGrid) - TetGen export does not work as desired :-( fixed image translation by half a pixel image origin and spacing are now managed via image import; raster to mesh is working again; applying color table to images is working again; bar-chart filter ist still NOT working correctly; issue with floating value to material id conversion in raster-to-mesh-conversion images are now read directly via vtk, automatically scaled and noData values are transparent (for asc, tif, png, bmp and jpg); image-based filters do not yet work again Georeferenced image positioning fixed. Fixed path. removed QImage and tried to replace functionality entirely by VTK ... not working atm Fixed some doxygen warnings. Fixed typo. Added benchmark coverage script. Added benchmark_coverage target. Added parameter passing to testrunner. Refactored CMake include directories to use absolute paths. Exclude tests directory on coverage. ... commit 852573b95e60a2d52eaf34a61c285f8fa70a546d Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 8 11:53:34 2012 +0100 QtDataView must be built before VtkVis. This fixes a compile error on *nix. commit 79c2f6b5dd58f2261ec6772df3746dd37a1fab74 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 8 11:10:26 2012 +0100 Reintroduced getter methods on VtkGeoImageSource. commit ffeb4276ebf350da09ea2cff831d06f053369edc Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 8 11:10:09 2012 +0100 Fixed two warnings. commit fe52e67350fde31c4d4e5b8ce4a1bd1d6b9be0c0 Merge: 5241fbb 7c893e7 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Feb 7 17:55:51 2012 +0100 resolved merge conflict commit 5241fbb3374b8aab7cd1f2a468193e9b257c99c9 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Feb 7 17:51:47 2012 +0100 resolved various issues with netCDF import; NetCDF data can be imported as raster (and texture) now; ImageAlgorithms can be created from data arrays now; textures now use VTKRaster class; textures are currently using a default colour table - this should be prevented commit 7c893e7e6c28759974aad57a88cf03a3e58fcb3a Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Feb 7 17:30:45 2012 +0100 Fixed image to lines filter. TODO: Image to bar chart filter (colors missing). commit 36a92129abf81a47e1b6e9fc6f024dbbf8247f39 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Feb 7 16:08:57 2012 +0100 Added backface culling option under Visualization Settings. commit e53b5e5287ec1bb067547c2b10b68679457e3ffb Merge: eea0bcb bdc5ba4 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Feb 7 12:25:28 2012 +0100 Merge branch 'master' into TetGenOutput Conflicts: CMakeLists.txt commit bdc5ba43c8700893efc0436e9eb2c4db3459e52b Merge: 7a07d21 7525ef0 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Feb 7 12:19:35 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 7a07d212d51c492b5b954d34b055c9b96d2aa4e8 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Feb 7 12:17:37 2012 +0100 - introduced a new nodes search algorithm (class MeshGrid) - TetGen export does not work as desired :-( commit 7525ef0c52ee769f92a23c61e08a13f8f10dceb6 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Feb 7 09:50:26 2012 +0100 fixed image translation by half a pixel commit 68e2f8c2ab0cf181f14d31b980afba2c2d20166f Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 6 17:25:38 2012 +0100 image origin and spacing are now managed via image import; raster to mesh is working again; applying color table to images is working again; bar-chart filter ist still NOT working correctly; issue with floating value to material id conversion in raster-to-mesh-conversion commit 66c62b381cafe7dc5d7fc8dfc54596278757f420 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Feb 6 14:36:16 2012 +0100 images are now read directly via vtk, automatically scaled and noData values are transparent (for asc, tif, png, bmp and jpg); image-based filters do not yet work again commit dee84eb876cece67b67283869f70c8254c0b47fb Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Feb 3 14:21:57 2012 +0100 Georeferenced image positioning fixed. commit 6ee0693e37f8f6e217f86c225d8f1fb7ec45e2c6 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Feb 3 10:16:46 2012 +0100 Fixed path. commit ed3103b64c193123e10c94eda6d4eae97744adea Merge: 0fc50ab b20210d Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Feb 2 17:52:00 2012 +0100 Merge branch 'master' of vismac02.intranet.ufz.de:+ff-devs/ogs5/ff-sources commit 0fc50abbf2a8b2220d06191efb81366a209634e3 Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Feb 2 17:51:43 2012 +0100 removed QImage and tried to replace functionality entirely by VTK ... not working atm commit b20210d2b8a0e640f2e5dfc2e5b0f87b743e925c Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 2 17:37:05 2012 +0100 Fixed some doxygen warnings. commit 8aea6867f4928bfac0dfb749ebc019548ab844ab Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 2 16:22:55 2012 +0100 Fixed typo. commit 18815a618fd3814850bdedefa82bbde8ce4fe881 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 2 14:03:55 2012 +0100 Added benchmark coverage script. commit 8217b59b9554dc3deefa01090c974a6c4e487105 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 2 13:55:19 2012 +0100 Added benchmark_coverage target. commit 6b18a1d6ad5d880e850ed76e629ee9adb93dc498 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Feb 2 13:53:37 2012 +0100 Added parameter passing to testrunner. commit 928fb7c12e02e83a70b5ae7b7e8445d4699f2282 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 1 17:02:46 2012 +0100 Refactored CMake include directories to use absolute paths. On one hand this makes the CMake files better readable and on the hand this will fix the presentation of code coverage reports on Jenkins. commit ba6f049521598da9154e11a61a7962b27512b418 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 1 16:01:09 2012 +0100 Exclude tests directory on coverage. commit e16d6f39ff20ad8938962d37ece805b8449bb74e Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 1 15:49:13 2012 +0100 One more fix. commit 14c4c86b3b7375e3f4b348a6ada6f4374b9340ac Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 1 15:40:51 2012 +0100 Fixed Jenkins build. commit 4ac18ea6bacae1053beb9c917633f7757b51a1f9 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 1 12:34:18 2012 +0100 Added coverage build script. commit 036d257ca8d9e008cf1c56405460883a238c5d07 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 1 12:33:26 2012 +0100 White space fixes. commit 918b016a22ce47f265a8f787d3c3f7ac3205120a Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 1 12:31:14 2012 +0100 Code coverage on Jenkins. commit f9e91a6f38138af760548a111f12dcf3981ded4c Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 1 12:30:57 2012 +0100 SOme small fixes. commit a4fa6aedb49f995208710122c95f71d6578a2fd4 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 1 12:29:36 2012 +0100 VRPN extension is only build when option is set. commit b3d57f0186ce059cddbd7cd63aeea3c5ea5e08c7 Merge: fdb2140 e2c1ce2 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Feb 1 10:49:09 2012 +0100 Merge remote-tracking branch 'upstream/master' * upstream/master: HS Fix PTC update Fix bugs in van Genuchten permeability model for two-phase flow. From now on, index 43 stands for wetting phase and 44 for gas phase Squashed commit. PTC_FLOW, updated commit fdb214047a3c5eda5545d594b2d565014865f0c4 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 17:29:33 2012 +0100 Cobertura code coverage report generation with gcovr added. commit b7a372789917c58426c9c2e769c82187c71cef64 Merge: 3330389 96a51e3 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 16:08:57 2012 +0100 Merge commit '96a51e34b5ebe66ab23778541a69fd56eeaada06' * commit '96a51e34b5ebe66ab23778541a69fd56eeaada06': Squashed 'cmake/' changes from 85fb0c6..b27f806 commit 96a51e34b5ebe66ab23778541a69fd56eeaada06 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 16:08:57 2012 +0100 Squashed 'cmake/' changes from 85fb0c6..b27f806 b27f806 Fixed typo. git-subtree-dir: cmake git-subtree-split: b27f8064a6348de3be4c397fedbfddcce321fced commit 333038961f2f287b03c5d6d05301e12567e4da97 Merge: 59146e0 48b2c75 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 12:28:40 2012 +0100 Merge commit '48b2c75b69a4bce3c991a2adf861eb865712033d' * commit '48b2c75b69a4bce3c991a2adf861eb865712033d': Squashed 'cmake/' changes from d77e35c..85fb0c6 commit 48b2c75b69a4bce3c991a2adf861eb865712033d Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 12:28:40 2012 +0100 Squashed 'cmake/' changes from d77e35c..85fb0c6 85fb0c6 Some renaming. git-subtree-dir: cmake git-subtree-split: 85fb0c61ad9afbeea96315257f4388a05bda223d commit 59146e00508b405513433f67b366af0740b03db3 Merge: 8d8eef6 f51df6c Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 12:19:37 2012 +0100 Merge commit 'f51df6c8368c3d8032e9592c720e38337c44b0cc' * commit 'f51df6c8368c3d8032e9592c720e38337c44b0cc': Squashed 'cmake/' changes from 2c1a353..d77e35c Conflicts: cmake/CodeCoverage.cmake commit f51df6c8368c3d8032e9592c720e38337c44b0cc Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 12:19:12 2012 +0100 Squashed 'cmake/' changes from 2c1a353..d77e35c d77e35c Merge commit 'ace8b6e945c61df3f11dadcc3665dfa5a928db47' ace8b6e Code coverage with lcov module. f068b6d This is version 5.2.07 by LB / TF / KR. 6507fac Squashed commit of the following: git-subtree-dir: cmake git-subtree-split: d77e35cf601f065b838de0bedd1e66d0280f05f9 commit 8d8eef679283c9596aa158e54cbd26cd7f61f565 Merge: f34517e 088aa7f Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 12:03:22 2012 +0100 Merge commit '088aa7f4b2e891b41f3e6aefc6fe496417a21fc7' * commit '088aa7f4b2e891b41f3e6aefc6fe496417a21fc7': Squashed 'cmake/' changes from 6773a13..2c1a353 Conflicts: cmake/FindMSVCRedist.cmake commit 088aa7f4b2e891b41f3e6aefc6fe496417a21fc7 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 12:01:29 2012 +0100 Squashed 'cmake/' changes from 6773a13..2c1a353 2c1a353 Moved some CMake modules to cmake/. e63887f Moved some CMake modules to cmake/. 6c55978 Updated README for pushing. 903e318 Added missing cmake module. git-subtree-dir: cmake git-subtree-split: 2c1a3532c55313f1a220609e168dc64300ddd290 commit f34517e1157a8b3bde47bd2c4466c9ec19ae1946 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 12:00:22 2012 +0100 Some renaming. commit 468a316efbb4ab04d0cb12a65c78795b5463eb69 Merge: 0b96faf fc9d5ab Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 11:56:13 2012 +0100 Merge branch 'gcov' * gcov: Code coverage with lcov working. Code coverage with lcov module. commit fc9d5ab6b51bdce71338b5875adbddb5a23ed4b0 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 11:54:01 2012 +0100 Code coverage with lcov working. Enable it with OGS_COVERAGE=ON and then make the gtests target. commit 87caa3677157d57c4856f3c1578bcfee620e8d48 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 31 11:53:48 2012 +0100 Code coverage with lcov module. commit 2d628996057a92b7df42f00e5d6935daca0becbf Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 30 18:46:51 2012 +0100 added missing file commit 0bd22a28dd9589882bf0d0a3e359234cc7a7e8e7 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 30 18:46:14 2012 +0100 ogs now uses xml-color-lookup-tables (same as paraview), colour tables can now be applied to images commit eea0bcb47f9e2818d405e7074f20128b2173b0bc Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Mon Jan 30 15:18:22 2012 +0100 added a programm that rotates 2D meshes into the x-z-plane commit 0b96faffadc59eebe485e03a408e50b22c634c00 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Jan 27 11:35:24 2012 +0100 Fixed include (including cpp's is not allowed). commit 092295b83cf240a23d5e9325323566974f5d76d2 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Jan 27 11:34:12 2012 +0100 Marked CTAGS and BBEdit CMake vars as advanced, commit 5ad7ba014f8386a9492fc43bb9a35e5f31e35899 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Mon Jan 30 08:45:05 2012 +0100 added test dir in CMakeLists.txt commit 9911f4b5c1294c2e855c0a39d681e9904557190b Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 23 17:59:16 2012 +0100 Jenkins commit url test. commit ebfc6dae3393b5e1f3de0aa83ee3d4d7cd32b5eb Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 23 17:38:22 2012 +0100 CMake dependency not needed here. commit 5490e352d3a5c7c0ddbbd99237fb6089c55e157d Merge: 8c1c0b9 4c167b7 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 23 17:07:19 2012 +0100 Merge branch 'ff' * ff: (95 commits) Forgot file. Forgot that gdiff depends on Qt Refactored GEO tests. Moved gdiff to tests/. Refactored QtTestrunner to use googletest instead of QTest. Fixed creating first reference file. Added some QCOMPARE example usages. Added Qt definitions as stated in http://developer.qt.nokia.com/quarterly/view/using_cmake_to_build_qt_projects added testGMSHFromGeo Fixed false interpretation of test diffs and added possibility to update reference files. Added code completion file generation with ctags. fixed index error in FEMConditionSetupDialog removed test funcionality fixed an index error in meshfromraster fixed a bug in mesh writing fixed error in TestRasterFromMesh Fixed one folder mistake and simplified test make targets. Fixed gdiff building on Windows. All test targets are now organized in a Testing folder in Visual Studio. made interface of OGSMeshIO::write() more general ... commit 4c167b7511f3afcdd41f346a566de4d55a2beb6b Merge: 2f6e020 8c1c0b9 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 23 17:03:35 2012 +0100 Merge branch 'master' into ff * master: Fixed Windows packaging on Visual Studio 2010 Win XP x32. back git-svn-id: https://svn.ufz.de/svn/ogs/trunk/sources@10001 3895a583-e809-0410-9bb6-aa9463026377 PTC has updated w.r.t. EOS Squashed commit. Squashed commit. commit 2f6e0207a7e16c0db5cb7f28dd8e9fada9b7a439 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 23 13:45:28 2012 +0100 Forgot file. commit ed00775a2bf5d9c584a7a8331075f3af5299c080 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 23 12:42:52 2012 +0100 Forgot that gdiff depends on Qt commit 97b9ca7b5e1139590da28c15890069fb242a3036 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 23 12:38:21 2012 +0100 Refactored GEO tests. Moved input file to testdata repository. Made TestPointInTriangle googletest although it needs some test assertions. commit f2ca760a39118dcae882522b22e6052c332cf980 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 23 11:55:56 2012 +0100 Moved gdiff to tests/. commit 484140750dff86c62fb2d22152b0775b11f923d5 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Jan 20 17:44:17 2012 +0100 Refactored QtTestrunner to use googletest instead of QTest. This is because when using QTest ther must be one executable per test to function properly. This would make it more complex to write tests. commit 984c77a7e0b96cb68ec2efa98035d7df037793b6 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Jan 20 14:49:48 2012 +0100 Fixed creating first reference file. commit f25cff6538fe4bed976607b64a399879c3eda8fa Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Jan 20 14:26:10 2012 +0100 Added some QCOMPARE example usages. commit 67d202c646637de0f6558ffc6c0618f1df081c58 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Jan 20 14:24:38 2012 +0100 Added Qt definitions as stated in http://developer.qt.nokia.com/quarterly/view/using_cmake_to_build_qt_projects commit b9e731246447af1eb99be283fe5ac36170b2ca2e Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Jan 20 14:18:20 2012 +0100 added testGMSHFromGeo commit 95f5a95584dcaa94563a5b2e969c3b5283ec1c1f Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Jan 19 15:07:03 2012 +0100 Fixed false interpretation of test diffs and added possibility to update reference files. To update a reference file run QtTestrunner with a test function name, e.g. bin/QtTestrunner testMeshFromRaster commit bc0c6274367e7f7248318c188c3e05f667c919ed Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Jan 19 12:24:10 2012 +0100 Added code completion file generation with ctags. See http://ctags.sourceforge.net/ctags.html or http://www.cellcortex.com/2011/02/vim-ctags-for-qt-development-on-osx.html for details. commit e731caea5cf676ebbc3f34aa5ef20c22abf638e5 Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Jan 19 12:33:53 2012 +0100 fixed index error in FEMConditionSetupDialog commit f9a5f7f47f4cb06dc7f7fae76c10a283896f3fc1 Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Jan 19 11:55:30 2012 +0100 removed test funcionality commit ce89b6605752476de0a4a3b13549f672398824ea Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Jan 19 11:54:28 2012 +0100 fixed an index error in meshfromraster commit ed4e7ad6d81f6059ef710434dbf059431686ada8 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Jan 19 11:55:55 2012 +0100 fixed a bug in mesh writing commit 81b5adc0e9e0dd60e78c6713b4a5de4f5e55e1c6 Merge: b424d17 dd65b87 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Jan 19 11:46:30 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit dd65b87edd705248835877ec424be879cf75f445 Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Jan 19 10:16:56 2012 +0100 fixed error in TestRasterFromMesh commit b424d17f5b22f399e5d61179191ad5959abd8701 Merge: 4e388ac 9b51868 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Jan 19 08:29:09 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 9b51868b9ab4bac97d8c9acec5256f4e64dc3b9c Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 17:41:26 2012 +0100 Fixed one folder mistake and simplified test make targets. commit 9767d945583921880d7bb4f19b7e18ffcad80c48 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 17:24:19 2012 +0100 Fixed gdiff building on Windows. commit e907c68cdad7ff97343a624785e35d7bc4b84fcf Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 17:18:50 2012 +0100 All test targets are now organized in a Testing folder in Visual Studio. commit 4e388ac2f5833f4c7d8da728f66b72888b0d2e0e Merge: 163db50 7cfbe6f Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Wed Jan 18 16:30:29 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 163db503cb0f75aceaf0c5cee31c5ba4889df17d Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Wed Jan 18 16:29:51 2012 +0100 made interface of OGSMeshIO::write() more general commit b972e4dedba107f6d1a24e614a019a4148cd3bfd Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 16:27:04 2012 +0100 Introduced new make targets gtest and qtest and renamed CTests for them. commit e54b96b4257bfba3c3f931de286467a31a992ccb Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 16:26:45 2012 +0100 Added correct return code. commit 7cfbe6fd0fa5039065ae1d41dde593954e386a21 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 15:28:15 2012 +0100 Nun aber! commit 6ab90350a84a982f4357e1e62d8f64f407ca92ae Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Jan 18 15:28:18 2012 +0100 fixed a few warnings commit 24bcf66d4f7ea57a69d9b8366dd76072de216cae Merge: ea7ca6c f4b52e1 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Jan 18 15:05:58 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit ea7ca6cb8b67ff5178e5425568cd89cd65b84bb6 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Jan 18 15:05:21 2012 +0100 FEM Conditions can now be set on all points of a given polyline or surface commit f4b52e13eea9a8327b9f0c6fdba0c259648261c7 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 15:03:41 2012 +0100 Benchmark script considers new Qt tests. commit e199a73395860ec805750d08aebcd2bb5a00863d Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 15:03:24 2012 +0100 Fixed CMake variable. commit 006425970ff5f3c2ccf6e2e05869ada9f6ae46f0 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 14:48:30 2012 +0100 Fixed diff output url path. commit be169ca368715dd6d13e2002a80679917efc27db Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 14:34:20 2012 +0100 Added link to the diff output on failed tests. commit e12b875b600c2976e10de5bb37d1cedcd3fa1636 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 12:19:18 2012 +0100 WIP: Just testing a link in the test output. commit 2bc88687ae80db1c53473034a2da98e77c112b60 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 11:54:52 2012 +0100 Changed QtTestrunner to a non-gui app because of Jenkins testing. A Jenkins Linux slave does not have a X server running. commit 1e7aa4402f404cd09c2eea9c21444c7bc278adb4 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 11:36:10 2012 +0100 Fixes a linker error on dev2. commit 1aa7a6db960673d8a98ace09b58966791f53bbe8 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 10:57:16 2012 +0100 Enabled testing in build script. commit 893ecba9287fa1789049e63313da6ced7b0658fe Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 18 10:28:35 2012 +0100 QtTestrunner is now also a ctest with QtTests. If run through ctest it outputs to build/testsQtTestrunner.xml. commit 83ba5e9772e4c3cda85e648966ac5f1fa218bee7 Merge: 17f8a97 3c2d3c5 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 17 15:16:10 2012 +0100 Merge commit 'e8de161' into ff * commit 'e8de161': Finished first working version of Qt / Vtk testing. Moved test data to its own repository testdata. Forgot this. First implementation of the QTest based Qt/Vtk testing. Added a mesh write method which works with stringstreams. Removed time from build time stamp because this enforces a rebuilt. Fixed CMake build path. Renamed TestMeshFromRaster. * commit '3c2d3c5e6c3bf37b44c2168e784413e9d2c9e562': Finished first working version of Qt / Vtk testing. Moved test data to its own repository testdata. Forgot this. First implementation of the QTest based Qt/Vtk testing. Added a mesh write method which works with stringstreams. Removed time from build time stamp because this enforces a rebuilt. Fixed CMake build path. Renamed TestMeshFromRaster. commit 3c2d3c5e6c3bf37b44c2168e784413e9d2c9e562 Merge: 883c1df 17f8a97 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 17 15:06:06 2012 +0100 Merge branch 'ff' into HEAD * ff: Removed old and unused LIB_DIR CMake variable. Removed unnecessary OGS_USE_NETCDF CMake variable. fixed a few inlude-issues Bumping required VTK version to 5.8 Added ncvalues.h from vtknetcdf source to DataView to fix compilation on *nix. renamed local variables for NetCDFDialog, included initialisation list and removed warnings fixed path-error under linux fixed bug concerning colour-table assignment; fixed bug concerning source term conversion NetCDFDialog: enter name of nc-object NetCDF Import Interface * commit '17f8a977ad03b11a19da7bd2593dab1df0828086': Removed old and unused LIB_DIR CMake variable. Removed unnecessary OGS_USE_NETCDF CMake variable. fixed a few inlude-issues fixed a bug creating Steiner points in GMSHInterface Bumping required VTK version to 5.8 Added ncvalues.h from vtknetcdf source to DataView to fix compilation on *nix. renamed local variables for NetCDFDialog, included initialisation list and removed warnings fixed path-error under linux fixed bug concerning colour-table assignment; fixed bug concerning source term conversion NetCDFDialog: enter name of nc-object NetCDF Import Interface commit 883c1dfe6b2267c9c385784c9a57bb1a43557ae8 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 17 15:01:51 2012 +0100 Finished first working version of Qt / Vtk testing. These tests depend on the existence of the new testdata repository. See tests/Qt/Vtk/TestMeshFromRaster.h for an example test. commit 1a9f55cf534a72b04a0cc003047eaf4fa403b04b Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 17 14:10:07 2012 +0100 Moved test data to its own repository testdata. Url: http://vismac02.intranet.ufz.de:8080/ogs5/testdata commit 17f8a977ad03b11a19da7bd2593dab1df0828086 Merge: 5df482c d00085f Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Jan 17 11:07:23 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit d00085f151d8f622666c667c3d7cd8711745b416 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 17 09:54:32 2012 +0100 Removed old and unused LIB_DIR CMake variable. commit 9bfd3a8bea6c24eb1906a7c58e96178166b7e03e Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 17 09:53:43 2012 +0100 Removed unnecessary OGS_USE_NETCDF CMake variable. commit e1d006c7706b6f5c9f9cad421755afbaa64ee6fe Merge: 983342e 24ce539 Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Jan 17 09:29:19 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 983342e170be75d5fca6571af216b4d743ba233c Author: Karsten Rink <karsten.rink@ufz.de> Date: Tue Jan 17 09:29:00 2012 +0100 fixed a few inlude-issues commit 5df482c00ce4c345fe12381c6ad1a05cb4c1387f Merge: 9f62d33 24ce539 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Jan 17 09:11:25 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 9f62d33f05ddcca6ea215bd99fa36c71a8834dbf Merge: 5fc38bd d98c980 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Jan 17 08:06:28 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 5fc38bd240e8dc98a3e99b3f3e4d1182ef1553bc Merge: ba59846 810e680 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Jan 17 07:58:41 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit ba59846d2ef460d7c2a238e6a225383f04e437cb Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue Jan 17 07:57:59 2012 +0100 fixed a bug creating Steiner points in GMSHInterface commit 24ce539346a5ada6352d2ed9e8bf8b712c6bce2b Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 17 07:37:16 2012 +0100 Bumping required VTK version to 5.8 commit d98c980b8d65442353c24c9ed80d1c184d50e68d Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 17 07:00:59 2012 +0100 Added ncvalues.h from vtknetcdf source to DataView to fix compilation on *nix. This is a temporary bugfix for a VTK bug. The header is not installed by VTK but is needed from the vtknetcdf_cxx library. On Windows this is not the case because VTK is not installed but only built. See http://www.vtk.org/pipermail/vtkusers/2012-January/120994.html for more details. commit 937f6a43cb8125db801662fe2ee7f4b306dedfb0 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 16 17:26:06 2012 +0100 Forgot this. commit 7a1573990d1f217d837f87815d5d252e2ea8f3b4 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 16 17:24:34 2012 +0100 First implementation of the QTest based Qt/Vtk testing. commit 17a580277948166ffc8cfd0b3cd8a6fa3f87cabb Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 16 17:23:23 2012 +0100 Added a mesh write method which works with stringstreams. commit c4af45d10dcb9d509ad2da00ee0c0295638ca217 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 16 17:22:27 2012 +0100 Removed time from build time stamp because this enforces a rebuilt. commit 7b1f1dd8d6f329c32e9dde4634c4ead6842d843e Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 16 17:22:05 2012 +0100 Fixed CMake build path. commit 198d475c1b8ff827d534169836e97892c9429757 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 16 17:21:33 2012 +0100 Renamed TestMeshFromRaster. commit 810e680c23c7c812413f1fe4168e131ac12482d3 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 16 16:10:58 2012 +0100 renamed local variables for NetCDFDialog, included initialisation list and removed warnings commit d0312aaea849b7f0e005c0f5a161274c86e7222f Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 16 15:53:26 2012 +0100 fixed path-error under linux commit c4bc8ccecb43de347889de8990586b2ba92184ea Merge: 094a00a 0949419 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 16 15:28:02 2012 +0100 Merge remote branch 'caro/ff' into ff commit 094a00a01562ef2549c05a59829d6f4fe2325809 Merge: 18313ed e034505 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 16 15:25:58 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 18313ed9f4237684650199aa0ae94bf7b54774a7 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 16 15:08:43 2012 +0100 fixed bug concerning colour-table assignment; fixed bug concerning source term conversion commit e03450592ce5e6a65b4629188977eb44445d0128 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 16 11:41:31 2012 +0100 Removed UTL/Vtk from CMake. commit 86c0ba241a09be91bb4ef8bb816f53ed0486d9a8 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 16 11:03:22 2012 +0100 Fixed build script and moved testMeshFromRaster to tests/. commit 3d1914177ab324ab9548a9d98231edb7799517c3 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 16 10:16:57 2012 +0100 fixed cmake issues under MSVS commit 4a517e9c1b2cfdef7135d0ac327d410c33b5bc06 Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 16 10:05:21 2012 +0100 Added Visual Studio folder grouping. Visual C++ Express users must explicitly turn this feauture OFF with CMAKE_USE_FOLDERS=OFF. commit cb6c2767589f5ab59e224a089331c16044d40e3e Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Jan 13 15:28:20 2012 +0100 Added googletest source code and removed external library dependency. commit a1e5864aaaf846a27c0d4936deaa0d11210a94bb Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 11 11:40:06 2012 +0100 Bumped minimum cmake version to 2.8.3. commit 58086349d86add39ab1e1b8f404061bb9efeeb10 Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Jan 13 15:54:51 2012 +0100 added documentation for testMeshFromRaster commit f62a437c33c19b2a60f6e8c6579876b07a2ac5dd Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Jan 13 12:08:59 2012 +0100 fixed cmake file commit 3f453cd67e9e0339247308e99522813a306120fc Merge: 4b7f0bb 128406e Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Jan 13 11:53:38 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 4b7f0bbb576c8aa1c5f9f3c70f097fa126ebd5cc Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Jan 13 11:53:16 2012 +0100 added test for raster-to-mesh conversion; some efficiancy-changes in condition-source commit 128406e1ad82d6d653eb8326d994f2251a181822 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Jan 12 09:52:58 2012 +0100 fixed a small bug, which prevents compilation with linux commit d869386a6b51d287d645f029390f40c7be6d8000 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Jan 11 18:13:23 2012 +0100 added missing dialog files commit 681308ecbd6ccd750910e15fcaa1dff3c29a7828 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Jan 11 18:12:32 2012 +0100 all (simple) femconditions can now be converted to the old fem objects, fem conditions can now be saved to file via a special dialog that allows to select various options commit 4317f8d2e35a6bc6239c92627b0d7e3af3b61d65 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 11 17:45:36 2012 +0100 Added Eigenvector calculation from vtk. commit 09494199598fc56d3e93e20971f4f1e50b79be1f Author: Carolin Helbig <carolin.helbig@ufz.de> Date: Wed Jan 11 17:11:19 2012 +0100 NetCDFDialog: enter name of nc-object commit 70e141e06ceec179772e87003c2f22d76f91ec5e Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 11 11:40:06 2012 +0100 Bumped minimum cmake version to 2.8.3. commit f0ba97174b020eb47757d2cb7b6292a1628d63a0 Author: Carolin Helbig <carolin.helbig@ufz.de> Date: Wed Jan 11 15:31:52 2012 +0100 NetCDF Import Interface commit bf3d26b3670dc02f3ae0bca4aeb490a91b4d13ed Merge: 0cfdd15 683bf2c Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Jan 11 12:41:18 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 0cfdd1526099461c5960da300cfb2ad66fcbb180 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Jan 11 12:41:01 2012 +0100 added CBoundaryCondition(BoundaryCondition*)-Constructor, fixed bug with incorrect names for surfaces from old geometry-files commit 683bf2cbb0d14cf8df8fa31cbb37598e59bd0ea5 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 10 10:14:44 2012 +0100 Fixed Windows packaging on Visual Studio 2010 Win XP x32. commit 83d09e4ea6dffba06b2bd071895db5869f76703e Author: Lars Bilke <lars.bilke@ufz.de> Date: Mon Jan 9 13:02:48 2012 +0100 Typo. commit 3410f4dfe822c9ab56477365a6435b7009d35ff2 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 9 17:31:20 2012 +0100 removed debug-output commit 2de554b6cc645dd211bced36a9a58047a9220f9d Merge: 974dd04 20983a0 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 9 17:26:57 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 974dd0422313ded313c5ee773825c4b7037d1c70 Author: Karsten Rink <karsten.rink@ufz.de> Date: Mon Jan 9 17:26:25 2012 +0100 restructured VtkConditionSource such that only geometry-points that are actually needed are port of the object ... this also resolves the issue with incorrecct visualisation of DIRECT conditions and non-surface points commit 550b471042113ab67deebca0e48b6b827f69cba7 Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Jan 6 14:14:43 2012 +0100 back before trying something new commit 20983a04a117ed5e495078a68bbdb8829b603b02 Author: Lars Bilke <lars.bilke@ufz.de> Date: Fri Jan 6 14:02:22 2012 +0100 Corrected cmake message when profiling. commit d75a441195b8ec8e9f97a378533bb52417664aea Merge: 84b4d74 5e98368 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Fri Jan 6 13:44:43 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 84b4d74ee58350743c101f09f23c3f5ce854373d Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Fri Jan 6 13:44:00 2012 +0100 fixed a serious bug in vtk output commit 838d57d8841d36b8445c1a02af562eaa61bcc5a6 Author: Karsten Rink <karsten.rink@ufz.de> Date: Fri Jan 6 12:29:01 2012 +0100 refined direct-st generation (only surface nodes are used now) commit 5e98368ab52601a9ec1c05654cea43647875c9e3 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Jan 5 11:18:41 2012 +0100 Updated gprof2dot to rev cbf7da383d79. commit 24ed192f6ffc7d02d588f7f497bf16a52b1330f1 Author: Lars Bilke <lars.bilke@ufz.de> Date: Thu Jan 5 10:48:21 2012 +0100 Forgot gprof call when configured with OGS_PROFILE=ON and running CTest. commit b11a8c92a626bb35cd2b391586c0738ee986a34f Merge: 13d4b9c 71e7531 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Fri Jan 6 07:50:46 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 13d4b9cd1d7011b6ebe914f7227c12eb42abbb2a Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Jan 5 16:20:28 2012 +0100 fixed some typos commit 71e753199f07cd52e3f0023ef1420c9ad3bf6632 Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Jan 5 15:34:40 2012 +0100 Fixed a few memory leaks commit f51c852138c824e7f8efd92ed7b79036a88f5918 Merge: 6a909a7 1ea2ff5 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Jan 5 15:16:55 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 6a909a72148d16f05829e9ecc845b1c5fae1e677 Merge: e0dc6e7 f86f8ac Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Jan 5 15:07:17 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit e0dc6e722affb92e6e2be106c9e08ccf4c2a6aa9 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu Jan 5 15:06:04 2012 +0100 some changes to transform an old GeoSys4 Surface type 4 into a surface that can be described by GEOLIB::Surface class commit 1ea2ff5454d41a5f79e23764c44b22cd9d612515 Merge: ef3a63f f86f8ac Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Jan 5 14:13:05 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit ef3a63f484849f7576caab5d9bd69e12fef7b37b Author: Karsten Rink <karsten.rink@ufz.de> Date: Thu Jan 5 14:12:36 2012 +0100 added first test to create direct source terms from raster files commit f86f8ac1027cda53ab76621748c4e9409f8a21bd Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 4 15:05:51 2012 +0100 Once again testing hooks. commit f4d6cad5b59d1f60220d6cdc9e59d431a02e9e9b Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 4 15:00:41 2012 +0100 One more whitespace fix. I am just testing the gitorious post-receive hooks. commit 85dbbbc46444a54bfef39fd21ce7c27e79973c7f Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 4 14:35:32 2012 +0100 More whitespace fixes. commit 410d595cc6fbca8fbff26e768f079d2ec2b47711 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 4 14:21:26 2012 +0100 Some whitespace fixes. commit 82defb95e803f28f31511f7409465e90b9116e52 Merge: 6510d2a 7b9a29d Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Jan 4 10:31:25 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 6510d2afa438ea62c8637b2982a68c9b09f4a8c1 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Jan 4 10:31:14 2012 +0100 some small changes commit 7b9a29df25ea188d5b0a9cfff8611bc2618d3c56 Merge: 303c939 93d5173 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 4 09:58:27 2012 +0100 Merge branch 'remove_wget_deps' into ff * remove_wget_deps: Revert md5. Fixed Typo. Fixed md5 for shapelib makefile. Fixed paths and added output which file is downloaded. Added mkdir bin. Removed wget dependency for setup scripts on Windows. Added bash function to download a file with cmake. commit 93d517323b12606dcdbb2eb385fe8851e2b99fc7 Merge: 32edc97 303c939 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 4 09:57:41 2012 +0100 Merge branch 'ff' into remove_wget_deps * ff: commit 32edc97b97ab1dc5a902b92aba37c6604b21c952 Merge: 7c896b8 0fd3063 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 4 09:56:55 2012 +0100 Merge branch 'master' into remove_wget_deps * master: Removed old SetupLibs.bat script (and also test the subversion sync again). Squashed commit of the following: Squashed commit of the following: commit 7c896b8be1f6a125d549a5080f1eb82166dd0615 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 4 09:27:42 2012 +0100 Revert md5. commit 27b578cf40dd2792d9b9e5a4c35c6116798f9224 Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 4 09:23:48 2012 +0100 Fixed Typo. commit d00d6e695541e9398981a8be8ade7a53add576af Author: Lars Bilke <lars.bilke@ufz.de> Date: Wed Jan 4 09:21:42 2012 +0100 Fixed md5 for shapelib makefile. commit 303c9398234bdb8017b278e9a0aad64f9b460ae7 Merge: 6fc2296 0fd3063 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 3 15:11:58 2012 +0100 Merge branch 'master' into ff * master: Removed old SetupLibs.bat script (and also test the subversion sync again). Squashed commit of the following: Squashed commit of the following: commit d82599b0a0fc1a2e69252da9492b30d7888155e0 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 3 15:10:16 2012 +0100 Fixed paths and added output which file is downloaded. commit 37155c4d4af7fd375ac9b8260b1beeb667d3c79d Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 3 14:44:03 2012 +0100 Added mkdir bin. commit 4581d932f831d99bf844a4c7e4c2820932745624 Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 3 14:36:30 2012 +0100 Removed wget dependency for setup scripts on Windows. commit b000e0ea91949b37ca9e625c23f051321aec3a1b Author: Lars Bilke <lars.bilke@ufz.de> Date: Tue Jan 3 14:15:03 2012 +0100 Added bash function to download a file with cmake. commit 6c3894471012e03079e8ff87fd42179c927db60b Merge: 4c2e288 6fc2296 Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Mon Jan 2 08:21:00 2012 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 4c2e288b5dc380d4720e182557caa3bf0072132c Author: Thomas Fischer <thomas.fischer@ufz.de> Date: Mon Jan 2 08:20:33 2012 +0100 fixed warnings in FEM/vtk.cpp commit 6fc2296e4d9d3ba9c53d975d283fa95a5a4428c2 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Dec 21 15:56:58 2011 +0100 optimized GridAdapter to CFEMesh conversion (and vice versa) a bit commit 18b42f4dfa78421266be239b424e11e592252f76 Merge: 70b218c be08f78 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Dec 21 15:35:20 2011 +0100 Merge branch 'ff' of vismac02.intranet.ufz.de:ogs5/sources into ff commit 70b218cea3192205114bb8031a022289a6985d74 Author: Karsten Rink <karsten.rink@ufz.de> Date: Wed Dec 21 15:34:55 2011 +0100 changed VtkMeshConverter to work with GridAdapter instead of CFEMeshes; changed MshModel to a more GridAdapter-centered approach; fixed bug in MshLayerMapper --- CMakeLists.txt | 11 +- DataView/CMakeLists.txt | 50 +- DataView/CondFromRaster.ui | 241 ++++++ DataView/CondFromRasterDialog.cpp | 111 +++ DataView/CondFromRasterDialog.h | 47 + DataView/CondObjectListItem.h | 7 +- DataView/ConditionWriter.ui | 143 ++++ DataView/ConditionWriterDialog.cpp | 95 +++ DataView/ConditionWriterDialog.h | 40 + DataView/DataView.cpp | 51 +- DataView/DataView.h | 4 + DataView/DatabaseConnection.cpp | 19 +- DataView/DatabaseConnection.h | 3 +- DataView/DiagramView/CMakeLists.txt | 13 +- DataView/DirectConditionGenerator.cpp | 157 ++++ DataView/DirectConditionGenerator.h | 30 + DataView/ElementTreeModel.cpp | 7 +- DataView/FEMConditionSetup.ui | 18 +- DataView/FEMConditionSetupDialog.cpp | 301 +++++-- DataView/FEMConditionSetupDialog.h | 31 +- DataView/GEOModels.cpp | 68 +- DataView/GEOModels.h | 10 +- DataView/GMSHPrefsDialog.h | 2 +- DataView/GeoTreeModel.cpp | 2 +- DataView/GeoTreeView.cpp | 31 +- DataView/GeoTreeView.h | 12 +- DataView/LinearEdit.ui | 90 ++ DataView/LinearEditDialog.cpp | 68 ++ DataView/LinearEditDialog.h | 43 + DataView/MshEditDialog.cpp | 58 +- DataView/MshLayerMapper.cpp | 618 +++++--------- DataView/MshLayerMapper.h | 8 +- DataView/MshModel.cpp | 62 +- DataView/MshModel.h | 6 +- DataView/NetCdfConfigure.ui | 801 ++++++++++++++++++ DataView/NetCdfConfigureDialog.cpp | 448 ++++++++++ DataView/NetCdfConfigureDialog.h | 58 ++ DataView/OGSRaster.cpp | 429 ---------- DataView/OGSRaster.h | 134 --- DataView/ProcessModel.cpp | 105 +-- DataView/ProcessModel.h | 5 +- DataView/ProcessView.cpp | 86 +- DataView/ProcessView.h | 8 + DataView/SHPImportDialog.cpp | 13 +- DataView/SelectMeshDialog.cpp | 61 ++ DataView/SelectMeshDialog.h | 57 ++ DataView/StationTreeView.cpp | 3 + DataView/StratView/CMakeLists.txt | 11 +- DataView/ncvalues.h | 279 ++++++ Gui/CMakeLists.txt | 72 +- Gui/mainwindow.cpp | 407 +++++---- Gui/mainwindow.h | 13 +- Gui/mainwindow.ui | 23 + OpenSG/CMakeLists.txt | 2 +- OpenSG/vtkOsgConverter.cpp | 176 ++-- OpenSG/vtkOsgConverter.h | 1 - Vrpn/CMakeLists.txt | 6 +- VtkAct/CMakeLists.txt | 20 +- VtkVis/CMakeLists.txt | 37 +- VtkVis/VisPrefs.ui | 21 +- VtkVis/VisPrefsDialog.cpp | 10 + VtkVis/VisPrefsDialog.h | 13 +- VtkVis/VisualizationWidget.cpp | 2 + VtkVis/VtkAlgorithmProperties.cpp | 99 +++ VtkVis/VtkAlgorithmProperties.h | 107 +-- VtkVis/VtkApplyColorTableFilter.cpp | 104 --- VtkVis/VtkApplyColorTableFilter.h | 64 -- VtkVis/VtkBGImageSource.cpp | 39 +- VtkVis/VtkBGImageSource.h | 17 +- VtkVis/VtkColorLookupTable.cpp | 97 +-- VtkVis/VtkColorLookupTable.h | 2 +- VtkVis/VtkCompositeColorByHeightFilter.cpp | 8 +- VtkVis/VtkCompositeColormapToImageFilter.cpp | 49 +- VtkVis/VtkCompositeContourFilter.cpp | 13 +- VtkVis/VtkCompositeContourFilter.h | 2 + VtkVis/VtkCompositeFilter.cpp | 2 +- VtkVis/VtkCompositeFilter.h | 2 + VtkVis/VtkCompositeImageToCylindersFilter.cpp | 47 +- VtkVis/VtkCompositeImageToCylindersFilter.h | 2 - VtkVis/VtkCompositeLineToTubeFilter.cpp | 5 +- VtkVis/VtkCompositePointToGlyphFilter.cpp | 2 +- VtkVis/VtkCompositeSelectionFilter.cpp | 1 + VtkVis/VtkCompositeSelectionFilter.h | 4 + VtkVis/VtkCompositeTextureOnSurfaceFilter.cpp | 42 +- VtkVis/VtkCompositeThresholdFilter.cpp | 35 +- VtkVis/VtkCompositeThresholdFilter.h | 2 + VtkVis/VtkConditionSource.cpp | 121 +-- VtkVis/VtkGeoImageSource.cpp | 107 +-- VtkVis/VtkGeoImageSource.h | 26 +- VtkVis/VtkImageDataToLinePolyDataFilter.cpp | 21 +- VtkVis/VtkImageDataToLinePolyDataFilter.h | 5 +- VtkVis/VtkMeshConverter.cpp | 157 ++-- VtkVis/VtkMeshConverter.h | 63 +- VtkVis/VtkMeshSource.cpp | 21 +- VtkVis/VtkPointsSource.cpp | 2 + VtkVis/VtkPolylinesSource.cpp | 2 + VtkVis/VtkRaster.cpp | 516 +++++++++++ VtkVis/VtkRaster.h | 145 ++++ VtkVis/VtkSelectionFilter.h | 3 + VtkVis/VtkStationSource.cpp | 29 +- VtkVis/VtkSurfacesSource.cpp | 2 + VtkVis/VtkTextureOnSurfaceFilter.cpp | 67 +- VtkVis/VtkTextureOnSurfaceFilter.h | 3 +- VtkVis/VtkVisImageItem.cpp | 28 +- VtkVis/VtkVisPipeline.cpp | 21 +- VtkVis/VtkVisPipeline.h | 3 + VtkVis/VtkVisPipelineItem.cpp | 74 +- VtkVis/VtkVisPipelineItem.h | 27 +- VtkVis/VtkVisPipelineView.cpp | 84 +- VtkVis/VtkVisPipelineView.h | 2 +- VtkVis/VtkVisPointSetItem.cpp | 214 +++-- VtkVis/VtkVisPointSetItem.h | 18 +- VtkVis/VtkVisTabWidget.cpp | 23 +- 113 files changed, 5759 insertions(+), 2528 deletions(-) create mode 100644 DataView/CondFromRaster.ui create mode 100644 DataView/CondFromRasterDialog.cpp create mode 100644 DataView/CondFromRasterDialog.h create mode 100644 DataView/ConditionWriter.ui create mode 100644 DataView/ConditionWriterDialog.cpp create mode 100644 DataView/ConditionWriterDialog.h create mode 100644 DataView/DirectConditionGenerator.cpp create mode 100644 DataView/DirectConditionGenerator.h create mode 100644 DataView/LinearEdit.ui create mode 100644 DataView/LinearEditDialog.cpp create mode 100644 DataView/LinearEditDialog.h create mode 100644 DataView/NetCdfConfigure.ui create mode 100644 DataView/NetCdfConfigureDialog.cpp create mode 100644 DataView/NetCdfConfigureDialog.h delete mode 100644 DataView/OGSRaster.cpp delete mode 100644 DataView/OGSRaster.h create mode 100644 DataView/SelectMeshDialog.cpp create mode 100644 DataView/SelectMeshDialog.h create mode 100644 DataView/ncvalues.h create mode 100644 VtkVis/VtkAlgorithmProperties.cpp delete mode 100644 VtkVis/VtkApplyColorTableFilter.cpp delete mode 100644 VtkVis/VtkApplyColorTableFilter.h create mode 100644 VtkVis/VtkRaster.cpp create mode 100644 VtkVis/VtkRaster.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b826640341..88fdb47082f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,15 +3,6 @@ IF (NOT VTK_FOUND) ENDIF (NOT VTK_FOUND) INCLUDE( ${VTK_USE_FILE} ) -# Find libgeotiff -FIND_PACKAGE( LibGeoTiff ) -IF(libgeotiff_FOUND) - ADD_DEFINITIONS(-Dlibgeotiff_FOUND) -ENDIF() # libgeotiff_FOUND -IF(NOT MSVC) - FIND_PACKAGE( LibTiff ) -ENDIF() # NOT MSVC - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /ZI /Od /Ob0") # Add subprojects @@ -24,7 +15,7 @@ ADD_SUBDIRECTORY( VtkAct ) IF (OGS_USE_OPENSG) ADD_SUBDIRECTORY( OpenSG ) ENDIF (OGS_USE_OPENSG) -IF(VRPN_FOUND) +IF(VRPN_FOUND AND OGS_USE_VRPN) ADD_SUBDIRECTORY( Vrpn ) ENDIF() ADD_SUBDIRECTORY( Gui ) diff --git a/DataView/CMakeLists.txt b/DataView/CMakeLists.txt index 4d4bbf31177..edbd1f66344 100644 --- a/DataView/CMakeLists.txt +++ b/DataView/CMakeLists.txt @@ -2,9 +2,12 @@ set( SOURCES ColorTableModel.cpp ColorTableView.cpp + CondFromRasterDialog.cpp + ConditionWriterDialog.cpp DatabaseConnection.cpp DataView.cpp DBConnectionDialog.cpp + DirectConditionGenerator.cpp ElementTreeModel.cpp FEMConditionSetupDialog.cpp GEOModels.cpp @@ -12,6 +15,7 @@ set( SOURCES GeoTreeModel.cpp GeoTreeView.cpp GMSHPrefsDialog.cpp + LinearEditDialog.cpp LineEditDialog.cpp ListPropertiesDialog.cpp ModellingTabWidget.cpp @@ -22,11 +26,12 @@ set( SOURCES MshModel.cpp MshQualitySelectionDialog.cpp MshTabWidget.cpp + NetCdfConfigureDialog.cpp NewProcessDialog.cpp - OGSRaster.cpp ProcessModel.cpp ProcessView.cpp QueryResultsDialog.cpp + SelectMeshDialog.cpp SetNameDialog.cpp StationTabWidget.cpp StationTreeModel.cpp @@ -37,7 +42,8 @@ set( SOURCES set( MOC_HEADERS ColorTableModel.h ColorTableView.h - CondItem.h + CondFromRasterDialog.h + ConditionWriterDialog.h DatabaseConnection.h DataView.h DBConnectionDialog.h @@ -48,6 +54,7 @@ set( MOC_HEADERS GeoTreeModel.h GeoTreeView.h GMSHPrefsDialog.h + LinearEditDialog.h LineEditDialog.h ListPropertiesDialog.h ModellingTabWidget.h @@ -55,10 +62,12 @@ set( MOC_HEADERS MshModel.h MshQualitySelectionDialog.h MshTabWidget.h + NetCdfConfigureDialog.h NewProcessDialog.h ProcessModel.h ProcessView.h QueryResultsDialog.h + SelectMeshDialog.h SetNameDialog.h StationTabWidget.h StationTreeModel.h @@ -68,28 +77,33 @@ set( MOC_HEADERS # Header files set( HEADERS BaseItem.h - ProcessItem.h + CondItem.h + DirectConditionGenerator.h CondObjectListItem.h GeoObjectListItem.h GeoTreeItem.h ModelTreeItem.h MshItem.h MshLayerMapper.h - OGSRaster.h + ProcessItem.h ) # UI files set( UIS + CondFromRaster.ui + ConditionWriter.ui DatabaseResultView.ui DBConnection.ui FEMConditionSetup.ui GeoTabWidgetBase.ui GMSHPrefs.ui + LinearEdit.ui LineEdit.ui ModellingTabWidgetBase.ui MshEdit.ui MshQualitySelection.ui MshTabWidgetBase.ui + NetCdfConfigure.ui NewProcess.ui StationTabWidgetBase.ui ) @@ -116,28 +130,24 @@ qt4_wrap_cpp( MOC_SOURCES ${MOC_HEADERS} ) # Include the headers which are generated by uic and moc # and include additional header include_directories( - . ${CMAKE_BINARY_DIR}/Qt/Base ${CMAKE_BINARY_DIR}/Qt/DataView ${CMAKE_BINARY_DIR}/Qt/DataView/DiagramView ${CMAKE_BINARY_DIR}/Qt/DataView/StratView - ../../Base - ../../MathLib - ../../GEO - ../../MSH - ../../FEM - ../../FileIO - ../Base - ./DiagramView - ./StratView - ../VtkVis - ${CMAKE_SOURCE_DIR} + + ${CMAKE_SOURCE_DIR}/Base + ${CMAKE_SOURCE_DIR}/MathLib + ${CMAKE_SOURCE_DIR}/GEO + ${CMAKE_SOURCE_DIR}/MSH + ${CMAKE_SOURCE_DIR}/FEM + ${CMAKE_SOURCE_DIR}/FileIO + ${CMAKE_SOURCE_DIR}/Qt/Base + ${CMAKE_SOURCE_DIR}/Qt/DataView + ${CMAKE_SOURCE_DIR}/Qt/DataView/DiagramView + ${CMAKE_SOURCE_DIR}/Qt/DataView/StratView + ${CMAKE_SOURCE_DIR}/Qt/VtkVis ) -if (OGS_COMPILE_QVTK) - include_directories(${CMAKE_BINARY_DIR}/Qt/QVTK ../QVTK) -endif (OGS_COMPILE_QVTK) - IF(VRPN_FOUND) INCLUDE_DIRECTORIES( ../Vrpn ${VRPN_INCLUDE_DIRS} ) ENDIF() diff --git a/DataView/CondFromRaster.ui b/DataView/CondFromRaster.ui new file mode 100644 index 00000000000..44be4ff9166 --- /dev/null +++ b/DataView/CondFromRaster.ui @@ -0,0 +1,241 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CondFromRaster</class> + <widget class="QDialog" name="CondFromRaster"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>340</width> + <height>230</height> + </rect> + </property> + <property name="windowTitle"> + <string>Create Boundary Conditions from Raster Files</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="meshLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>50</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Mesh</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="3"> + <widget class="QComboBox" name="meshBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="rasterLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>50</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Raster</string> + </property> + </widget> + </item> + <item row="4" column="1" colspan="2"> + <widget class="QLineEdit" name="rasterEdit"/> + </item> + <item row="4" column="3"> + <widget class="QPushButton" name="selectButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="7" column="2" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="6" column="0" colspan="4"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Calculation method</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0" colspan="3"> + <widget class="QRadioButton" name="directButton"> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Use raster values directly</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="3"> + <widget class="QRadioButton" name="integrateButton"> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Integrate over mesh elements</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="scalingLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>50</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Scaling</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="scalingEdit"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>70</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>70</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>(Note: Normalization is 1 / Scaling)</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>CondFromRaster</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>CondFromRaster</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/DataView/CondFromRasterDialog.cpp b/DataView/CondFromRasterDialog.cpp new file mode 100644 index 00000000000..babf1d87f42 --- /dev/null +++ b/DataView/CondFromRasterDialog.cpp @@ -0,0 +1,111 @@ +/** + * \file CondFromRasterDialog.cpp + * 2012/01/04 KR Initial implementation + */ + +#include "CondFromRasterDialog.h" + +#include <QFileDialog> +#include <QSettings> + +#include "DirectConditionGenerator.h" +#include "OGSError.h" +#include "StrictDoubleValidator.h" + +CondFromRasterDialog::CondFromRasterDialog(const std::map<std::string, MeshLib::CFEMesh*> &msh_map, QDialog* parent) + : QDialog(parent), _msh_map(msh_map) +{ + setupUi(this); + + this->scalingEdit->setEnabled(false); + _scale_validator = new StrictDoubleValidator(-1e+10, 1e+20, 5); + this->scalingEdit->setText("1.0"); + this->scalingEdit->setValidator (_scale_validator); + + for (std::map<std::string, MeshLib::CFEMesh*>::const_iterator it = _msh_map.begin(); + it != _msh_map.end(); ++it) + this->meshBox->addItem(QString::fromStdString(it->first)); + + this->directButton->setChecked(true); +} + +CondFromRasterDialog::~CondFromRasterDialog() +{ + delete _scale_validator; +} + +void CondFromRasterDialog::on_selectButton_pressed() +{ + QSettings settings("UFZ", "OpenGeoSys-5"); +#ifdef libgeotiff_FOUND + QString geotiffExtension(" *.tif"); +#else + QString geotiffExtension(""); +#endif + QString fileName = QFileDialog::getOpenFileName(this, "Select raster file", + settings.value("lastOpenedConditionsFileDirectory").toString(), QString( + "Raster files (*.asc *.grd);;") .arg(geotiffExtension)); + + if (!fileName.isEmpty()) + { + this->rasterEdit->setText(fileName); + + QDir dir = QDir(fileName); + settings.setValue("lastOpenedConditionsFileDirectory", dir.absolutePath()); + } +} + + +void CondFromRasterDialog::accept() +{ + std::string mesh_name (this->meshBox->currentText().toStdString()); + std::string raster_name (this->rasterEdit->text().toStdString()); + double scaling_factor = strtod(this->scalingEdit->text().toStdString().c_str(), 0); + std::vector< std::pair<size_t,double> > direct_values; + + if (mesh_name.empty()) + { + OGSError::box("No mesh selected."); + return; + } + if (raster_name.empty()) + { + OGSError::box("No raster selected."); + return; + } + + const MeshLib::CFEMesh* mesh = (_msh_map.find(mesh_name))->second; + //std::string direct_node_name(raster_name + ".txt"); + + if (this->directButton->isChecked()) + { + DirectConditionGenerator dcg; + direct_values = dcg.directToSurfaceNodes(*mesh, raster_name); + //dcg.writeToFile(direct_node_name); + } + else + { + if (scaling_factor <= 0) + { + OGSError::box("No valid scaling factor given."); + return; + } + MeshLib::CFEMesh* new_mesh = const_cast<MeshLib::CFEMesh*>(mesh); + DirectConditionGenerator dcg; + direct_values = dcg.directWithSurfaceIntegration(*new_mesh, raster_name, scaling_factor); + //dcg.writeToFile(direct_node_name); + } + //emit directNodesWritten(direct_node_name); + emit transmitDisValues(direct_values); + this->done(QDialog::Accepted); +} + +void CondFromRasterDialog::reject() +{ + this->done(QDialog::Rejected); +} + +void CondFromRasterDialog::on_integrateButton_toggled(bool isSelected) +{ + this->scalingEdit->setEnabled(isSelected); +} \ No newline at end of file diff --git a/DataView/CondFromRasterDialog.h b/DataView/CondFromRasterDialog.h new file mode 100644 index 00000000000..0537113915d --- /dev/null +++ b/DataView/CondFromRasterDialog.h @@ -0,0 +1,47 @@ +/** + * \file CondFromRasterDialog.h + * 2012/01/04 KR Initial implementation + */ + +#ifndef CONDFROMRASTERDIALOG_H +#define CONDFROMRASTERDIALOG_H + +#include "ui_CondFromRaster.h" +#include <QDialog> + +#include "ProjectData.h" +#include "GridAdapter.h" + +class StrictDoubleValidator; + +/** + * \brief A dialog window for creating DIRECT boundary conditions from raster files + */ +class CondFromRasterDialog : public QDialog, private Ui_CondFromRaster +{ + Q_OBJECT + +public: + CondFromRasterDialog(const std::map<std::string, MeshLib::CFEMesh*> &msh_map, QDialog* parent = 0); + ~CondFromRasterDialog(void); + +private: + const std::map<std::string, MeshLib::CFEMesh*> _msh_map; + StrictDoubleValidator* _scale_validator; + +private slots: + void on_integrateButton_toggled(bool isSelected); + void on_selectButton_pressed(); + + /// Instructions if the OK-Button has been pressed. + void accept(); + + /// Instructions if the Cancel-Button has been pressed. + void reject(); + +signals: + void directNodesWritten(std::string); + void transmitDisValues(std::vector< std::pair<size_t,double> >); +}; + +#endif //CONDFROMRASTERDIALOG_H diff --git a/DataView/CondObjectListItem.h b/DataView/CondObjectListItem.h index 7f4934de393..4ab7b837428 100644 --- a/DataView/CondObjectListItem.h +++ b/DataView/CondObjectListItem.h @@ -28,13 +28,14 @@ public: /// Constructor for the TreeItem specifying FEM Conditions. CondObjectListItem(const QList<QVariant> &data, TreeItem* parent, - const FEMCondition::CondType type, + FEMCondition* cond, const std::vector<GEOLIB::Point*>* points) - : TreeItem(data, parent), _vtkSource(VtkConditionSource::New()), _type(type), + : TreeItem(data, parent), _vtkSource(VtkConditionSource::New()), _type(cond->getCondType()), _cond_vec(new std::vector<FEMCondition*>) { + _cond_vec->push_back(cond); QString display_name = parent->data(0).toString().append(" - ").append( - QString::fromStdString(FEMCondition::condTypeToString(type))); + QString::fromStdString(FEMCondition::condTypeToString(_type))); static_cast<VtkConditionSource*>(_vtkSource)->setData( points, _cond_vec); static_cast<VtkConditionSource*>(_vtkSource)->SetName( display_name ); } diff --git a/DataView/ConditionWriter.ui b/DataView/ConditionWriter.ui new file mode 100644 index 00000000000..a7bd5995c64 --- /dev/null +++ b/DataView/ConditionWriter.ui @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ConditionWriter</class> + <widget class="QDialog" name="ConditionWriter"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>203</height> + </rect> + </property> + <property name="windowTitle"> + <string>Save FEM Conditions...</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0"> + <widget class="QLabel" name="geoLabel"> + <property name="text"> + <string>Geometry</string> + </property> + <property name="margin"> + <number>10</number> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="condTypeLabel"> + <property name="text"> + <string>Condition Type</string> + </property> + <property name="margin"> + <number>10</number> + </property> + </widget> + </item> + <item row="1" column="2" colspan="2"> + <widget class="QComboBox" name="geoBox"> + <item> + <property name="text"> + <string>All (XML files only)</string> + </property> + </item> + </widget> + </item> + <item row="2" column="2" colspan="2"> + <widget class="QComboBox" name="condTypeBox"> + <item> + <property name="text"> + <string>All (XML files only)</string> + </property> + </item> + <item> + <property name="text"> + <string>Boundary Conditions</string> + </property> + </item> + <item> + <property name="text"> + <string>Initial Conditions</string> + </property> + </item> + <item> + <property name="text"> + <string>Source Terms</string> + </property> + </item> + </widget> + </item> + <item row="4" column="2" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="fileNameLabel"> + <property name="text"> + <string>Filename</string> + </property> + <property name="margin"> + <number>10</number> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QLineEdit" name="fileNameEdit"/> + </item> + <item row="3" column="3"> + <widget class="QPushButton" name="fileNameButton"> + <property name="maximumSize"> + <size> + <width>30</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>ConditionWriter</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>ConditionWriter</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/DataView/ConditionWriterDialog.cpp b/DataView/ConditionWriterDialog.cpp new file mode 100644 index 00000000000..3480132224f --- /dev/null +++ b/DataView/ConditionWriterDialog.cpp @@ -0,0 +1,95 @@ +/** + * \file ConditionWriterDialog.cpp + * 2012/01/11 KR Initial implementation + */ + +#include "ConditionWriterDialog.h" +#include "FEMCondition.h" +#include "OGSError.h" + +#include <QFileDialog> +#include <QFileInfo> +#include <QSettings> + +ConditionWriterDialog::ConditionWriterDialog(const GEOLIB::GEOObjects *geo_objects, QDialog* parent) + : QDialog(parent) +{ + setupUi(this); + + std::vector<std::string> geo_names; + geo_objects->getGeometryNames(geo_names); + + for (size_t i=0; i<geo_names.size(); i++) + this->geoBox->addItem(QString::fromStdString(geo_names[i])); + +} + +ConditionWriterDialog::~ConditionWriterDialog() +{ +} + +void ConditionWriterDialog::on_fileNameButton_pressed() +{ + QString filetypes(""); + int geo_idx = this->geoBox->currentIndex(); + int cnd_idx = this->condTypeBox->currentIndex(); + if ((geo_idx == 0) || (cnd_idx == 0)) filetypes = "OpenGeoSys FEM Condition file (*.cnd)"; + else if ((geo_idx != 0) && (cnd_idx == 1)) filetypes = "OpenGeoSys FEM Condition file (*.cnd);;GeoSys Boundary Condition (*.bc)"; + else if ((geo_idx != 0) && (cnd_idx == 2)) filetypes = "OpenGeoSys FEM Condition file (*.cnd);;GeoSys Initial Condition (*.ic)"; + else if ((geo_idx != 0) && (cnd_idx == 3)) filetypes = "OpenGeoSys FEM Condition file (*.cnd);;GeoSys Source Condition (*.st)"; + + QSettings settings("UFZ", "OpenGeoSys-5"); + QString fileName = QFileDialog::getSaveFileName(this, "Select path", + settings.value("lastOpenedConditionsFileDirectory").toString(), filetypes); + + if (!fileName.isEmpty()) + { + this->fileNameEdit->setText(fileName); + + QDir dir = QDir(fileName); + settings.setValue("lastOpenedConditionsFileDirectory", dir.absolutePath()); + } +} + + +void ConditionWriterDialog::accept() +{ + const QString file_name = this->fileNameEdit->text(); + QFileInfo fi(file_name); + + if ((fi.suffix().toLower().compare("cnd") != 0) && + ((this->geoBox->currentIndex()==0) || (this->condTypeBox->currentIndex()==0))) + { + OGSError::box("Multiple geometries or multiple types of conditions\ncan only be saved to *.cnd files.","Inconsistent selection of parameters"); + } + else + { + QString geo_name = this->geoBox->currentText(); + if (this->geoBox->currentIndex() == 0) geo_name = ""; + + FEMCondition::CondType cond_type(FEMCondition::UNSPECIFIED);; + switch (this->condTypeBox->currentIndex()) + { + case 0: + cond_type = FEMCondition::UNSPECIFIED; break; + case 1: + cond_type = FEMCondition::BOUNDARY_CONDITION; break; + case 2: + cond_type = FEMCondition::INITIAL_CONDITION; break; + case 3: + cond_type = FEMCondition::SOURCE_TERM; break; + default: + std::cout << "Error in ConditionWriterDialog..." << std::endl; + } + + emit saveFEMConditionsRequested(geo_name, cond_type, file_name); + + this->done(QDialog::Accepted); + } +} + +void ConditionWriterDialog::reject() +{ + this->done(QDialog::Rejected); +} + diff --git a/DataView/ConditionWriterDialog.h b/DataView/ConditionWriterDialog.h new file mode 100644 index 00000000000..399ee350dcf --- /dev/null +++ b/DataView/ConditionWriterDialog.h @@ -0,0 +1,40 @@ +/** + * \file ConditionWriterDialog.h + * 2012/01/11 KR Initial implementation + */ + +#ifndef CONDITIONWRITERDIALOG_H +#define CONDITIONWRITERDIALOG_H + +#include "ui_ConditionWriter.h" +#include <QDialog> + +#include "GEOObjects.h" +#include "FEMCondition.h" + +/** + * \brief A dialog window for creating DIRECT boundary conditions from raster files + */ +class ConditionWriterDialog : public QDialog, private Ui_ConditionWriter +{ + Q_OBJECT + +public: + ConditionWriterDialog(const GEOLIB::GEOObjects* geoObjects, QDialog* parent = 0); + ~ConditionWriterDialog(void); + +private slots: + void on_fileNameButton_pressed(); + + /// Instructions if the OK-Button has been pressed. + void accept(); + + /// Instructions if the Cancel-Button has been pressed. + void reject(); + +signals: + void saveFEMConditionsRequested(const QString&, const FEMCondition::CondType, const QString&); + +}; + +#endif //CONDITIONWRITERDIALOG_H diff --git a/DataView/DataView.cpp b/DataView/DataView.cpp index c12bc332e30..c1802a5551b 100644 --- a/DataView/DataView.cpp +++ b/DataView/DataView.cpp @@ -22,6 +22,7 @@ #include <QSettings> #include "MeshIO/OGSMeshIO.h" +#include "Writer.h" // necessary to avoid Linker Error in Windows DataView::DataView( QWidget* parent /*= 0*/ ) : QTreeView(parent) @@ -49,7 +50,8 @@ void DataView::addMeshAction() if (!fileName.isEmpty()) { std::string name = fileName.toStdString(); - MeshLib::CFEMesh* msh = FileIO::OGSMeshIO::loadMeshFromFile(name); + FileIO::OGSMeshIO meshIO; + MeshLib::CFEMesh* msh = meshIO.loadMeshFromFile(name); if (msh) static_cast<MshModel*>(this->model())->addMesh(msh, name); } @@ -80,13 +82,17 @@ void DataView::contextMenuEvent( QContextMenuEvent* event ) QAction* checkMeshAction = menu.addAction("Check mesh quality..."); QAction* saveMeshAction = menu.addAction("Save mesh..."); menu.addSeparator(); - QAction* directSTAction = menu.addAction("Load DIRECT source terms..."); + QMenu direct_cond_menu("DIRECT Conditions"); + menu.addMenu(&direct_cond_menu); + QAction* addDirectAction = direct_cond_menu.addAction("Add..."); + QAction* loadDirectAction = direct_cond_menu.addAction("Load..."); menu.addSeparator(); QAction* removeMeshAction = menu.addAction("Remove mesh"); connect(editMeshAction, SIGNAL(triggered()), this, SLOT(openMshEditDialog())); connect(checkMeshAction, SIGNAL(triggered()), this, SLOT(checkMeshQuality())); connect(saveMeshAction, SIGNAL(triggered()), this, SLOT(writeMeshToFile())); - connect(directSTAction, SIGNAL(triggered()), this, SLOT(loadDIRECTSourceTerms())); + connect(addDirectAction, SIGNAL(triggered()), this, SLOT(addDIRECTSourceTerms())); + connect(loadDirectAction, SIGNAL(triggered()), this, SLOT(loadDIRECTSourceTerms())); connect(removeMeshAction, SIGNAL(triggered()), this, SLOT(removeMesh())); menu.exec(event->globalPos()); } @@ -100,10 +106,8 @@ void DataView::openMshEditDialog() static_cast<MshModel*>(this->model())->getMesh(index)->getCFEMesh(); MshEditDialog meshEdit(mesh); - connect(&meshEdit, - SIGNAL(mshEditFinished(MeshLib::CFEMesh *, - std::string &)), model, - SLOT(addMesh(MeshLib::CFEMesh *, std::string &))); + connect(&meshEdit, SIGNAL(mshEditFinished(MeshLib::CFEMesh*, std::string &)), + model, SLOT(addMesh(MeshLib::CFEMesh*, std::string &))); meshEdit.exec(); } @@ -118,23 +122,18 @@ int DataView::writeMeshToFile() const QSettings settings("UFZ", "OpenGeoSys-5"); QString mshName = QString::fromStdString( static_cast<MshModel*>(this->model())->getMesh(index)->getName()); - std::string fileName = QFileDialog::getSaveFileName(NULL, "Save mesh as", - settings.value("lastOpenedFileDirectory").toString(), - "GeoSys mesh file (*.msh)").toStdString(); + QString fileName = QFileDialog::getSaveFileName(NULL, "Save mesh as", + settings.value("lastOpenedMeshFileDirectory").toString(), + "GeoSys mesh file (*.msh)"); - if (!fileName.empty()) + if (!fileName.isEmpty()) { - std::ofstream out (fileName.c_str()); - if (out.is_open()) - { - FileIO::OGSMeshIO::write (mesh, out); - out.close(); - return 1; - } - else - std::cout << - "MshTabWidget::saveMeshFile() - Could not create file..." << - std::endl; + FileIO::OGSMeshIO meshIO; + meshIO.setMesh(mesh); + meshIO.writeToFile(fileName.toStdString().c_str()); + QDir dir = QDir(fileName); + settings.setValue("lastOpenedMeshFileDirectory", dir.absolutePath()); + return 1; } else OGSError::box("No file name entered."); @@ -142,6 +141,14 @@ int DataView::writeMeshToFile() const return 0; } +void DataView::addDIRECTSourceTerms() +{ + QModelIndex index = this->selectionModel()->currentIndex(); + const GridAdapter* grid = static_cast<MshModel*>(this->model())->getMesh(index); + emit requestCondSetupDialog(grid->getName(), GEOLIB::INVALID, 0, false); +} + + void DataView::loadDIRECTSourceTerms() { QModelIndex index = this->selectionModel()->currentIndex(); diff --git a/DataView/DataView.h b/DataView/DataView.h index d4529b4a2c8..215320a91dc 100644 --- a/DataView/DataView.h +++ b/DataView/DataView.h @@ -6,6 +6,7 @@ #define DATAVIEW_H #include "Point.h" +#include "GeoType.h" #include <QTreeView> class GridAdapter; @@ -57,6 +58,8 @@ private slots: /// Adds a new mesh. void addMeshAction(); + void addDIRECTSourceTerms(); + void loadDIRECTSourceTerms(); /// Remove the currently selected mesh. @@ -75,6 +78,7 @@ private slots: signals: void qualityCheckRequested(VtkMeshSource*); + void requestCondSetupDialog(const std::string&, const GEOLIB::GEOTYPE, const size_t, bool on_points); void requestMeshRemoval(const QModelIndex&); void requestDIRECTSourceTerms(const std::string, const std::vector<GEOLIB::Point*>*); void saveMeshAction(); diff --git a/DataView/DatabaseConnection.cpp b/DataView/DatabaseConnection.cpp index 77ff0c5d830..73cd556317a 100644 --- a/DataView/DatabaseConnection.cpp +++ b/DataView/DatabaseConnection.cpp @@ -173,22 +173,11 @@ bool DatabaseConnection::isConnected() } /** - * Loads a list of stations with a random colour + * Loads a list of stations. * \param listID The ID of the list that is requested * \return 1 if there were no errors, 0 and an error message otherwise. */ -int DatabaseConnection::loadStationList(const int &listID) -{ - return loadStationList(listID, GEOLIB::getRandomColor()); -} - -/** - * Loads a list of stations with a specified colour - * \param listID The ID of the list that is requested - * \param color The colour which will be assigned to the objects in the list - * \return 1 if there were no errors, 0 and an error message otherwise. - */ -int DatabaseConnection::loadStationList(int listID, const GEOLIB::Color* const color) +int DatabaseConnection::loadStationList(int listID) { if (_db.open()) { @@ -249,7 +238,7 @@ int DatabaseConnection::loadStationList(int listID, const GEOLIB::Color* const c stnQuery.value(2).toDouble(), stnQuery.value(3).toDouble(), stnQuery.value(4).toDouble()); - newStation->setColor(color); + stations->push_back(newStation); } @@ -259,7 +248,7 @@ int DatabaseConnection::loadStationList(int listID, const GEOLIB::Color* const c std::string temp_name (listName.toStdString()); if (!stations->empty()) - _geoObjects->addStationVec(stations, temp_name, color); + _geoObjects->addStationVec(stations, temp_name); _db.close(); //emit listLoaded(listName); diff --git a/DataView/DatabaseConnection.h b/DataView/DatabaseConnection.h index 4ca9409e70b..06728a899bb 100644 --- a/DataView/DatabaseConnection.h +++ b/DataView/DatabaseConnection.h @@ -36,7 +36,6 @@ public: int getStationID(const int &listID, const double &x, const double &y); void getListSelection(); bool isConnected(); - int loadStationList(int listID, const GEOLIB::Color* const color); int loadValues(const int &listID, const int &stationID, const QDateTime &startDate, @@ -50,7 +49,7 @@ public slots: QString dbname, QString user, QString pass); - int loadStationList(const int &listID); + int loadStationList(int listID); int setConnection(QString protocol, QString hostname, QString dbname, diff --git a/DataView/DiagramView/CMakeLists.txt b/DataView/DiagramView/CMakeLists.txt index 03169b83987..a7f258c7ccc 100644 --- a/DataView/DiagramView/CMakeLists.txt +++ b/DataView/DiagramView/CMakeLists.txt @@ -39,15 +39,14 @@ qt4_wrap_cpp( MOC_SOURCES ${MOC_HEADERS} ) # Include the headers which are generated by uic and moc # and include additional header include_directories( - . + ${CMAKE_SOURCE_DIR}/Qt/DataView/DiagramView ${CMAKE_BINARY_DIR}/Qt/DataView/DiagramView ${CMAKE_BINARY_DIR}/Qt/DataView - ../../../Base - ../../../GEO - ../../Base - ../../DataView - ../../../MathLib - ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/Base + ${CMAKE_SOURCE_DIR}/GEO + ${CMAKE_SOURCE_DIR}/Qt/Base + ${CMAKE_SOURCE_DIR}/Qt/DataView + ${CMAKE_SOURCE_DIR}/MathLib ) # Put moc files in a project folder diff --git a/DataView/DirectConditionGenerator.cpp b/DataView/DirectConditionGenerator.cpp new file mode 100644 index 00000000000..f0c95548a28 --- /dev/null +++ b/DataView/DirectConditionGenerator.cpp @@ -0,0 +1,157 @@ +/** + * \file DirectConditionGenerator.cpp + * 2012/01/04 KR Initial implementation + * + */ + +#include "DirectConditionGenerator.h" + +#include "VtkRaster.h" +#include "MshEditor.h" +#include "PointWithID.h" + +#include "fem_ele.h" + +const std::vector< std::pair<size_t,double> >& DirectConditionGenerator::directToSurfaceNodes(const MeshLib::CFEMesh &mesh, const std::string &filename) +{ + if (_direct_values.empty()) + { + double origin_x(0), origin_y(0), delta(0); + size_t imgwidth(0), imgheight(0); + + float* img = VtkRaster::loadDataFromASC(filename, origin_x, origin_y, imgwidth, imgheight, delta); + + const std::vector<GEOLIB::PointWithID*> surface_nodes ( MshEditor::getSurfaceNodes(mesh) ); + //std::vector<MeshLib::CNode*> nodes = mesh.nod_vector; + const size_t nNodes(surface_nodes.size()); + _direct_values.reserve(nNodes); + for (size_t i=0; i<nNodes; i++) + { + const double* coords (surface_nodes[i]->getData()); + + if (coords[0]>=origin_x && coords[0]<(origin_x+(delta*imgwidth)) && coords[1]>=origin_y && coords[1]<(origin_y+(delta*imgheight))) + { + int cell_x = static_cast<int>(floor((coords[0] - origin_x)/delta)); + int cell_y = static_cast<int>(floor((coords[1] - origin_y)/delta)); + + // if node outside of raster use raster boundary values + cell_x = (cell_x < 0) ? 0 : ((static_cast<size_t>(cell_x) > imgwidth) ? (imgwidth-1) : cell_x); + cell_y = (cell_y < 0) ? 0 : ((static_cast<size_t>(cell_y) > imgheight) ? (imgheight-1) : cell_y); + + size_t index = cell_y*imgwidth+cell_x; + if (fabs(img[index] + 9999) > std::numeric_limits<float>::min()) + _direct_values.push_back( std::pair<size_t, double>(surface_nodes[i]->getID(),img[index]) ); + } + } + + delete[] img; + + } + else + std::cout << "Error in DirectConditionGenerator::directToSurfaceNodes() - Data vector contains outdated values..." << std::endl; + + return _direct_values; +} + + +const std::vector< std::pair<size_t,double> >& DirectConditionGenerator::directWithSurfaceIntegration(MeshLib::CFEMesh &mesh, const std::string &filename, double scaling) +{ + double no_data_value (-9999); // TODO: get this from asc-reader! + + if (_direct_values.empty()) + { + mesh.MarkInterface_mHM_Hydro_3D(); // mark element faces on the surface + + double origin_x(0), origin_y(0), delta(0); + size_t imgwidth(0), imgheight(0); + double node_val[8] = {0,0,0,0,0,0,0,0}; // maximum possible number of nodes per face (just in case ...) + + FiniteElement::CElement* fem ( new FiniteElement::CElement(mesh.GetCoordinateFlag()) ); + + float* img; + if (filename.substr(filename.length()-3,3).compare("asc") == 0) + img = VtkRaster::loadDataFromASC(filename, origin_x, origin_y, imgwidth, imgheight, delta); + else if (filename.substr(filename.length()-3,3).compare("grd") == 0) + img = VtkRaster::loadDataFromSurfer(filename, origin_x, origin_y, imgwidth, imgheight, delta); + + const size_t nNodes(mesh.nod_vector.size()); + std::vector<double> val(nNodes, 0.0); + for(size_t i = 0; i < nNodes; i++) + mesh.nod_vector[i]->SetMark(false); + + // copied from CFEMesh::Precipitation2NeumannBC() by WW + size_t nFaces = mesh.face_vector.size(); + for(size_t i=0; i<nFaces; i++) + { + MeshLib::CElem* elem = mesh.face_vector[i]; + if (!elem->GetMark()) + continue; + + // if face is on the surface of the mesh + size_t nElemNodes = elem->GetNodesNumber(false); + for(size_t k=0; k<nElemNodes; k++) + node_val[k] = 0.0; + + // get values from the raster for all nodes of the face + for(size_t k=0; k<nElemNodes; k++) + { + double const* const pnt_k (elem->GetNode(k)->getData()); + int cell_x = static_cast<int>(floor((pnt_k[0] - origin_x) / delta)); + int cell_y = static_cast<int>(floor((pnt_k[1] - origin_y) / delta)); + + // if node outside of raster use raster boundary values + cell_x = (cell_x < 0) ? 0 : ((static_cast<size_t>(cell_x) > imgwidth) ? (imgwidth-1) : cell_x); + cell_y = (cell_y < 0) ? 0 : ((static_cast<size_t>(cell_y) > imgheight) ? (imgheight-1) : cell_y); + + node_val[k] = img[cell_y * imgwidth + cell_x]; + if (fabs(node_val[k] - no_data_value) < std::numeric_limits<double>::min()) + node_val[k] = 0.; + } + + // get area of the surface element face + elem->ComputeVolume(); + + // do the actual surface integration + fem->setOrder(mesh.getOrder() + 1); + fem->ConfigElement(elem); + fem->FaceIntegration(node_val); + + // add up the integrated values (nodes get values added for all faces they are part of) + for(size_t k=0; k<elem->GetNodesNumber(false); k++) + { + MeshLib::CNode* node = elem->GetNode(k); + node->SetMark(true); + val[node->GetIndex()] += node_val[k]; + } + } + + _direct_values.reserve(nNodes); + for(size_t k=0; k<nNodes; k++) + { + if (!mesh.nod_vector[k]->GetMark()) + continue; + // Assuming the unit of precipitation is mm/day + _direct_values.push_back( std::pair<size_t, double>(k, val[k] / scaling) ); + } + } + else + std::cout << "Error in DirectConditionGenerator::directWithSurfaceIntegration() - Data vector contains outdated values..." << std::endl; + + return _direct_values; +} + + +int DirectConditionGenerator::writeToFile(const std::string &name) const +{ + std::ofstream out( name.c_str(), std::ios::out ); + + if (out) + { + for (std::vector< std::pair<size_t,double> >::const_iterator it = _direct_values.begin(); it != _direct_values.end(); ++it) + out << it->first << "\t" << it->second << std::endl; + + out.close(); + } + return 0; +} + diff --git a/DataView/DirectConditionGenerator.h b/DataView/DirectConditionGenerator.h new file mode 100644 index 00000000000..e1839d73b32 --- /dev/null +++ b/DataView/DirectConditionGenerator.h @@ -0,0 +1,30 @@ +/** + * \file DirectConditionGenerator.h + * 2012/01/04 KR Initial implementation + * + */ + +#ifndef DIRECTCONDITIONGENERATOR_H +#define DIRECTCONDITIONGENERATOR_H + +#include "msh_mesh.h" + +class DirectConditionGenerator +{ +public: + DirectConditionGenerator() {}; + ~DirectConditionGenerator() {}; + + const std::vector< std::pair<size_t,double> >& directToSurfaceNodes(const MeshLib::CFEMesh &mesh, const std::string &filename); + + const std::vector< std::pair<size_t,double> >& directWithSurfaceIntegration(MeshLib::CFEMesh &mesh, const std::string &filename, double scaling); + + int writeToFile(const std::string &name) const; + +private: + std::vector< std::pair<size_t,double> > _direct_values; + +}; + +#endif // DIRECTCONDITIONGENERATOR_H + diff --git a/DataView/ElementTreeModel.cpp b/DataView/ElementTreeModel.cpp index 9abe05670b5..3b73f842ee0 100644 --- a/DataView/ElementTreeModel.cpp +++ b/DataView/ElementTreeModel.cpp @@ -54,13 +54,14 @@ void ElementTreeModel::setElement(const GridAdapter* grid, const size_t elem_ind TreeItem* nodeListItem = new TreeItem(nodeListData, elemItem); elemItem->appendChild(nodeListItem); - const std::vector<GEOLIB::Point*>* nodes = grid->getNodes(); + const std::vector<GEOLIB::Point*>* nodes_vec = grid->getNodes(); for (size_t i = 0; i < elem->nodes.size(); i++) { + const GEOLIB::Point* pnt = (*nodes_vec)[elem->nodes[i]]; QList<QVariant> nodeData; nodeData << "Node " + QString::number(elem->nodes[i]) << - QString::number((*(*nodes)[i])[0]) << QString::number((*(*nodes)[i])[1]) << - QString::number((*(*nodes)[i])[2]); + QString::number((*pnt)[0]) << QString::number((*pnt)[1]) << + QString::number((*pnt)[2]); TreeItem* nodeItem = new TreeItem(nodeData, nodeListItem); nodeListItem->appendChild(nodeItem); } diff --git a/DataView/FEMConditionSetup.ui b/DataView/FEMConditionSetup.ui index fbc20c328bd..32c1e35e950 100644 --- a/DataView/FEMConditionSetup.ui +++ b/DataView/FEMConditionSetup.ui @@ -15,7 +15,7 @@ </property> <layout class="QGridLayout" name="gridLayout"> <item row="1" column="0"> - <widget class="QLabel" name="label_2"> + <widget class="QLabel" name="processTypeLabel"> <property name="text"> <string>Process Type</string> </property> @@ -25,7 +25,7 @@ </widget> </item> <item row="4" column="0"> - <widget class="QLabel" name="label_3"> + <widget class="QLabel" name="disTypeLabel"> <property name="text"> <string>Distribution Type</string> </property> @@ -35,7 +35,7 @@ </widget> </item> <item row="5" column="0"> - <widget class="QLabel" name="label_4"> + <widget class="QLabel" name="valueLabel"> <property name="text"> <string>Value</string> </property> @@ -48,16 +48,10 @@ <widget class="QComboBox" name="processTypeBox"/> </item> <item row="4" column="1"> - <widget class="QComboBox" name="disTypeBox"> - <item> - <property name="text"> - <string>Constant (Direchlet)</string> - </property> - </item> - </widget> + <widget class="QComboBox" name="disTypeBox"/> </item> <item row="3" column="0"> - <widget class="QLabel" name="label_5"> + <widget class="QLabel" name="pvTypeLabel"> <property name="text"> <string>Primary Variable</string> </property> @@ -96,7 +90,7 @@ </spacer> </item> <item row="2" column="0"> - <widget class="QLabel" name="label"> + <widget class="QLabel" name="condTypeLabel"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> diff --git a/DataView/FEMConditionSetupDialog.cpp b/DataView/FEMConditionSetupDialog.cpp index 7bcb2b35988..e2759021119 100644 --- a/DataView/FEMConditionSetupDialog.cpp +++ b/DataView/FEMConditionSetupDialog.cpp @@ -8,6 +8,9 @@ #include "FEMEnums.h" #include "ProjectData.h" #include "StrictDoubleValidator.h" +#include "StringTools.h" +#include "LinearEditDialog.h" +#include "CondFromRasterDialog.h" #include "BoundaryCondition.h" #include "InitialCondition.h" @@ -17,46 +20,76 @@ FEMConditionSetupDialog::FEMConditionSetupDialog(const std::string &associated_g const GEOLIB::GEOTYPE type, const std::string &geo_name, const GEOLIB::GeoObject* const geo_object, + bool on_points, QDialog* parent) -: QDialog(parent), _cond(associated_geometry, FEMCondition::UNSPECIFIED), _secondValueEdit(NULL), - _first_value_validator(NULL), _second_value_validator(NULL) +: QDialog(parent), _cond(associated_geometry, FEMCondition::UNSPECIFIED), _set_on_points(on_points), + _combobox(NULL), directButton(NULL), _mesh(NULL), _first_value_validator(NULL) { _cond.setGeoType(type); _cond.setGeoName(geo_name); _cond.setGeoObj(geo_object); setupUi(this); - setupDialog(); +} - +FEMConditionSetupDialog::FEMConditionSetupDialog(const FEMCondition &cond, QDialog* parent) + : QDialog(parent), _cond(cond), _set_on_points(false), _combobox(NULL), directButton(NULL), + _mesh(NULL), _first_value_validator(NULL) +{ + setupUi(this); + setupDialog(); + setValuesFromCond(); } -FEMConditionSetupDialog::FEMConditionSetupDialog(FEMCondition &cond, QDialog* parent) - : QDialog(parent), _cond(cond), _secondValueEdit(NULL), - _first_value_validator(NULL), _second_value_validator(NULL) +FEMConditionSetupDialog::FEMConditionSetupDialog(const std::string &name, const MeshLib::CFEMesh* mesh, QDialog* parent) +: QDialog(parent), _cond(name, FEMCondition::UNSPECIFIED), _set_on_points(false), _combobox(NULL), directButton(NULL), + _mesh(mesh), _first_value_validator(NULL) { + _cond.setGeoType(GEOLIB::INVALID); + _cond.setGeoName(name); + _cond.setGeoObj(NULL); + + setupUi(this); setupDialog(); } FEMConditionSetupDialog::~FEMConditionSetupDialog() { - delete _secondValueEdit; + delete _combobox; + delete directButton; delete _first_value_validator; - delete _second_value_validator; } void FEMConditionSetupDialog::setupDialog() { - if (_cond.getGeoType() == GEOLIB::POLYLINE) + if (_cond.getGeoType() != GEOLIB::INVALID) { - this->disTypeBox->addItem("Linear (Direchlet)"); - //this->disTypeBox->addItem("Linear (Neumann)"); + this->disTypeBox->addItem("Constant (Direchlet)"); + if (_cond.getGeoType() == GEOLIB::POLYLINE) + this->disTypeBox->addItem("Linear (Direchlet)"); + + if (this->_set_on_points) + { + _combobox = new QComboBox; + _combobox->addItem("Elevation"); + static_cast<QGridLayout*>(this->layout())->addWidget(_combobox,5,1) ; + } + else + { + _first_value_validator = new StrictDoubleValidator(-1e+10, 1e+10, 5); + this->firstValueEdit->setText("0"); + this->firstValueEdit->setValidator (_first_value_validator); + } + } + else // direct on mesh + { + this->disTypeBox->addItem("Direct"); + //static_cast<QGridLayout*>(this->layout())->removeWidget(this->firstValueEdit); + directButton = new QPushButton("Calculate Values"); + static_cast<QGridLayout*>(this->layout())->addWidget(directButton,5,1); + connect(this->directButton, SIGNAL(pressed()), this, SLOT(directButton_pressed())); } - _first_value_validator = new StrictDoubleValidator(-1e+10, 1e+10, 5); - _second_value_validator = new StrictDoubleValidator(-1e+10, 1e+10, 5); - this->firstValueEdit->setText("0"); - this->firstValueEdit->setValidator (_first_value_validator); const std::list<std::string> process_names = FiniteElement::getAllProcessNames(); for (std::list<std::string>::const_iterator it = process_names.begin(); it != process_names.end(); ++it) @@ -72,47 +105,89 @@ void FEMConditionSetupDialog::setupDialog() */ } +void FEMConditionSetupDialog::setValuesFromCond() +{ + QString pcs_type = QString::fromStdString(FiniteElement::convertProcessTypeToString(_cond.getProcessType())); + this->processTypeBox->setCurrentIndex(this->processTypeBox->findText(pcs_type)); + + QString pv_type = QString::fromStdString(FiniteElement::convertPrimaryVariableToString(_cond.getProcessPrimaryVariable())); + this->pvTypeBox->setCurrentIndex(this->pvTypeBox->findText(pv_type)); + + int idx(0); + if (_cond.getCondType() == FEMCondition::INITIAL_CONDITION) + this->condTypeBox->setCurrentIndex(1); + else if (_cond.getCondType() == FEMCondition::SOURCE_TERM) + { + this->condTypeBox->setCurrentIndex(2); + on_condTypeBox_currentIndexChanged(2); + } + + if (_cond.getGeoType() != GEOLIB::INVALID) + { + if (_cond.getProcessDistributionType() == FiniteElement::CONSTANT || _cond.getProcessDistributionType() == FiniteElement::CONSTANT_NEUMANN) + { + this->disTypeBox->setCurrentIndex(0); + this->firstValueEdit->setText(QString::number(_cond.getDisValues()[0])); + } + else + { + this->disTypeBox->setCurrentIndex(1); + directButton = new QPushButton(QString::number(static_cast<int>(_cond.getDisValues().size())) + " values"); + } + } + else // direct on mesh + { + size_t nValues (_cond.getDisValues().size()); + this->directButton->setText(QString::number(static_cast<int>(_cond.getDisValues().size())) + " values"); + } +} + + void FEMConditionSetupDialog::accept() { _cond.setProcessType(static_cast<FiniteElement::ProcessType>(this->processTypeBox->currentIndex() + 1)); _cond.setProcessPrimaryVariable(static_cast<FiniteElement::PrimaryVariable>(this->pvTypeBox->currentIndex() + 1)); - QString dis_type_text = this->disTypeBox->currentText(); - if (condTypeBox->currentIndex()>1) + if (_cond.getGeoType() != GEOLIB::INVALID) { - if (this->disTypeBox->currentIndex()>0) - _cond.setProcessDistributionType(FiniteElement::LINEAR_NEUMANN); - else - _cond.setProcessDistributionType(FiniteElement::CONSTANT_NEUMANN); + if (condTypeBox->currentIndex()>1) + { + if (this->disTypeBox->currentIndex()>0) + _cond.setProcessDistributionType(FiniteElement::LINEAR_NEUMANN); + else + { + _cond.setProcessDistributionType(FiniteElement::CONSTANT_NEUMANN); + _cond.setConstantDisValue(this->firstValueEdit->text().toDouble()); + } + } + else + { + if (this->disTypeBox->currentIndex()>0) + _cond.setProcessDistributionType(FiniteElement::LINEAR); + else + { + _cond.setProcessDistributionType(FiniteElement::CONSTANT); + _cond.setConstantDisValue(this->firstValueEdit->text().toDouble()); + } + } } - else + else // direct on mesh + _cond.setProcessDistributionType(FiniteElement::DIRECT); + if (_cond.getDisValues().size()==0) { - if (this->disTypeBox->currentIndex()>0) - _cond.setProcessDistributionType(FiniteElement::LINEAR); - else - _cond.setProcessDistributionType(FiniteElement::CONSTANT); + OGSError::box("No distribution values specified!"); + return; } - std::vector<double> dis_values; - dis_values.push_back(strtod(this->firstValueEdit->text().toStdString().c_str(), 0)); - if (this->_secondValueEdit) - dis_values.push_back(strtod(this->_secondValueEdit->text().toStdString().c_str(), 0)); - _cond.setDisValue(dis_values); - - FEMCondition* new_cond(NULL); - switch(this->condTypeBox->currentIndex()) + if (!_set_on_points) { - case 0: - new_cond = new BoundaryCondition(_cond); - break; - case 1: - new_cond = new InitialCondition(_cond); - break; - default: - new_cond = new SourceTerm(_cond); + std::vector<FEMCondition*> conditions; + conditions.push_back(this->typeCast(_cond)); + emit createFEMCondition(conditions); } + else + this->copyCondOnPoints(); - emit addFEMCondition(new_cond); this->done(QDialog::Accepted); } @@ -127,44 +202,134 @@ void FEMConditionSetupDialog::on_condTypeBox_currentIndexChanged(int index) //if (index==1) // this->geoNameBox->addItem("Domain"); // remove "Domain" if IC is unselected - if (index>1) // source terms selected + if (_cond.getGeoType() != GEOLIB::INVALID) { - while (this->disTypeBox->count()>0) - this->disTypeBox->removeItem(0); - this->disTypeBox->addItem("Constant (Neumann)"); - if (_cond.getGeoType() == GEOLIB::POLYLINE) - this->disTypeBox->addItem("Linear (Neumann)"); + if (index>1) // source terms selected + { + while (this->disTypeBox->count()>0) + this->disTypeBox->removeItem(0); + this->disTypeBox->addItem("Constant (Neumann)"); + if (_cond.getGeoType() == GEOLIB::POLYLINE) + this->disTypeBox->addItem("Linear (Neumann)"); + } + else + { + while (this->disTypeBox->count()>0) + this->disTypeBox->removeItem(0); + this->disTypeBox->addItem("Constant (Direchlet)"); + if (_cond.getGeoType() == GEOLIB::POLYLINE) + this->disTypeBox->addItem("Linear (Direchlet)"); + } + } +} + + +void FEMConditionSetupDialog::on_disTypeBox_currentIndexChanged(int index) +{ + if (index>0) // linear + { + static_cast<QGridLayout*>(this->layout())->removeWidget(this->firstValueEdit); + directButton = new QPushButton("Calculate Values"); + connect(this->directButton, SIGNAL(pressed()), this, SLOT(directButton_pressed())); + static_cast<QGridLayout*>(this->layout())->addWidget(directButton,5,1); + } + else // constant + { + static_cast<QGridLayout*>(this->layout())->removeWidget(this->directButton); + delete directButton; + directButton = NULL; + static_cast<QGridLayout*>(this->layout())->addWidget(this->firstValueEdit,5,1); + } + +} + +void FEMConditionSetupDialog::directButton_pressed() +{ + if (this->_mesh == NULL) + { + const GEOLIB::Polyline* line = dynamic_cast<const GEOLIB::Polyline*>(_cond.getGeoObj()); + const std::vector<size_t> nodes = _cond.getDisNodes(); + const std::vector<double> values = _cond.getDisValues(); + LinearEditDialog dlg(*line, nodes, values); + connect(&dlg, SIGNAL(transmitDisValues(std::vector< std::pair<size_t,double> >)), + this, SLOT(addDisValues(std::vector< std::pair<size_t,double> >))); + dlg.exec(); } else { - while (this->disTypeBox->count()>0) - this->disTypeBox->removeItem(0); - this->disTypeBox->addItem("Constant (Direchlet)"); - if (_cond.getGeoType() == GEOLIB::POLYLINE) - this->disTypeBox->addItem("Linear (Direchlet)"); + std::map<std::string, MeshLib::CFEMesh*> msh_map; + msh_map.insert( std::pair<std::string, MeshLib::CFEMesh*>(this->_cond.getGeoName(), const_cast<MeshLib::CFEMesh*>(this->_mesh)) ); + CondFromRasterDialog dlg(msh_map); + //connect(&dlg, SIGNAL(directNodesWritten(std::string)), this, SLOT(direct_path_changed(std::string))); + connect(&dlg, SIGNAL(transmitDisValues(std::vector< std::pair<size_t,double> >)), + this, SLOT(addDisValues(std::vector< std::pair<size_t,double> >))); + dlg.exec(); } } +void FEMConditionSetupDialog::addDisValues(std::vector< std::pair<size_t,double> > direct_values) +{ + _cond.setDisValues(direct_values); + this->directButton->setText(QString::number(direct_values.size()) + " values added"); + //this->directButton->setEnabled(false); +} -void FEMConditionSetupDialog::on_disTypeBox_currentIndexChanged(int index) +FEMCondition* FEMConditionSetupDialog::typeCast(const FEMCondition &cond) { - if (index>0) // linear + FEMCondition* new_cond(NULL); + switch(this->condTypeBox->currentIndex()) + { + case 0: + new_cond = new BoundaryCondition(cond); + break; + case 1: + new_cond = new InitialCondition(cond); + break; + default: + new_cond = new SourceTerm(cond); + } + return new_cond; +} + +void FEMConditionSetupDialog::copyCondOnPoints() +{ + std::vector<FEMCondition*> conditions; + if (_cond.getGeoType() == GEOLIB::POLYLINE) { - if (!_secondValueEdit) + const GEOLIB::Polyline* ply = dynamic_cast<const GEOLIB::Polyline*>(_cond.getGeoObj()); + size_t nPoints = ply->getNumberOfPoints(); + for (size_t i=0; i<nPoints; i++) { - _secondValueEdit = new QLineEdit("0"); - _secondValueEdit->setValidator(_second_value_validator); - static_cast<QGridLayout*>(this->layout())->addWidget(_secondValueEdit,5,1) ; + FEMCondition* cond = new FEMCondition(_cond); + cond->setGeoObj(NULL); + cond->setGeoType(GEOLIB::POINT); + cond->setGeoName(_cond.getAssociatedGeometryName() + "_Point" + number2str(ply->getPointID(i))); + cond->clearDisValues(); + cond->setConstantDisValue((*ply->getPoint(i))[2]); + conditions.push_back(this->typeCast(*cond)); } + emit createFEMCondition(conditions); } - else // constant + else if (_cond.getGeoType() == GEOLIB::SURFACE) { - if (_secondValueEdit) + const GEOLIB::Surface* sfc = dynamic_cast<const GEOLIB::Surface*>(_cond.getGeoObj()); + size_t nTriangles = sfc->getNTriangles(); + for (size_t i=0; i<nTriangles; i++) { - static_cast<QGridLayout*>(this->layout())->removeWidget(_secondValueEdit); - delete _secondValueEdit; - _secondValueEdit = NULL; - } + const GEOLIB::Triangle* tri = (*sfc)[i]; + for (size_t j=0; j<3; j++) + { + FEMCondition* cond = new FEMCondition(_cond); + cond->setGeoObj(NULL); + cond->setGeoType(GEOLIB::POINT); + cond->setGeoName(_cond.getAssociatedGeometryName() + "_Point" + number2str((*tri)[j])); + cond->clearDisValues(); + cond->setConstantDisValue((*tri->getPoint(j))[2]); + conditions.push_back(this->typeCast(*cond)); + } + } + emit createFEMCondition(conditions); } - + else + std::cout << "Error discerning GeoType ..." << std::endl; } diff --git a/DataView/FEMConditionSetupDialog.h b/DataView/FEMConditionSetupDialog.h index ea9c66c58b1..84453433e5b 100644 --- a/DataView/FEMConditionSetupDialog.h +++ b/DataView/FEMConditionSetupDialog.h @@ -11,12 +11,17 @@ #include <QDialog> +class QComboBox; +class QPushButton; class StrictDoubleValidator; namespace GEOLIB { class GeoObject; } +namespace MeshLib { + class CFEMesh; +} /** * \brief A dialog window for adding FEM Conditions based @@ -32,19 +37,29 @@ public: const GEOLIB::GEOTYPE type, const std::string &geo_name, const GEOLIB::GeoObject* const geo_object, + bool on_points = false, QDialog* parent = 0); /// Constructor for editing an existing FEM condition. - FEMConditionSetupDialog(FEMCondition &cond, QDialog* parent = 0); + FEMConditionSetupDialog(const FEMCondition &cond, QDialog* parent = 0); + + /// Constructor for creating DIRECT FEM conditions on MeshNodes. + FEMConditionSetupDialog(const std::string &name, const MeshLib::CFEMesh* mesh, QDialog* parent = 0); + ~FEMConditionSetupDialog(void); private: + /// Sets layout of the dialog according to properties of the object void setupDialog(); + /// Inserts existing values if an existing FEMCondition is being edited + void setValuesFromCond(); FEMCondition _cond; - QLineEdit* _secondValueEdit; + bool _set_on_points; + QComboBox* _combobox; //needed for on_points & linear conds + QPushButton* directButton; // needed for direct conditions + const MeshLib::CFEMesh* _mesh; // needed for direct conditions StrictDoubleValidator* _first_value_validator; - StrictDoubleValidator* _second_value_validator; private slots: /// Instructions if the OK-Button has been pressed. @@ -57,8 +72,16 @@ private slots: void on_disTypeBox_currentIndexChanged(int index); + void directButton_pressed(); + + void addDisValues(std::vector< std::pair<size_t,double> > direct_values); + + void copyCondOnPoints(); + + FEMCondition* typeCast(const FEMCondition &cond); + signals: - void addFEMCondition(FEMCondition*); + void createFEMCondition(std::vector<FEMCondition*>); }; diff --git a/DataView/GEOModels.cpp b/DataView/GEOModels.cpp index c6f2079f033..ae9314fe023 100644 --- a/DataView/GEOModels.cpp +++ b/DataView/GEOModels.cpp @@ -11,6 +11,8 @@ #include "GeoTreeModel.h" #include "StationTreeModel.h" +#include "StringTools.h" + #include "OGSError.h" GEOModels::GEOModels( QObject* parent /*= 0*/ ) : @@ -38,9 +40,10 @@ void GEOModels::removeGeometry(std::string geo_name, GEOLIB::GEOTYPE type) void GEOModels::addPointVec( std::vector<GEOLIB::Point*>* points, std::string &name, - std::map<std::string, size_t>* name_pnt_id_map ) + std::map<std::string, size_t>* name_pnt_id_map, + double eps) { - GEOObjects::addPointVec(points, name, name_pnt_id_map); + GEOObjects::addPointVec(points, name, name_pnt_id_map, eps); _geoModel->addPointList(QString::fromStdString(name), this->getPointVecObj(name)); emit geoDataAdded(_geoModel, name, GEOLIB::POINT); } @@ -68,10 +71,9 @@ bool GEOModels::removePointVec( const std::string &name ) } void GEOModels::addStationVec( std::vector<GEOLIB::Point*>* stations, - std::string &name, - const GEOLIB::Color* const color ) + std::string &name) { - GEOObjects::addStationVec(stations, name, color); + GEOObjects::addStationVec(stations, name); _stationModel->addStationList(QString::fromStdString(name), stations); emit stationVectorAdded(_stationModel, name); @@ -210,26 +212,40 @@ void GEOModels::connectPolylineSegments(const std::string &geoName, void GEOModels::addNameForElement(const std::string &geometry_name, const GEOLIB::GEOTYPE object_type, size_t id, std::string new_name) { - switch(object_type) { - case GEOLIB::POINT: - { - GEOLIB::PointVec* pnt_vec = this->getPointVecObj(geometry_name); - pnt_vec->setNameForElement(id, new_name); - break; - } - case GEOLIB::POLYLINE: - { - GEOLIB::PolylineVec* ply_vec = this->getPolylineVecObj(geometry_name); - ply_vec->setNameForElement(id, new_name); - break; - } - case GEOLIB::SURFACE: - { - GEOLIB::SurfaceVec* sfc_vec = this->getSurfaceVecObj(geometry_name); - sfc_vec->setNameForElement(id, new_name); - break; - } - default: - std::cout << "Error in GEOModels::addNameForElement() - Unknown GEOTYPE..." << std::endl; + if (object_type == GEOLIB::POINT) + this->getPointVecObj(geometry_name)->setNameForElement(id, new_name); + else if (object_type == GEOLIB::POLYLINE) + this->getPolylineVecObj(geometry_name)->setNameForElement(id, new_name); + else if (object_type == GEOLIB::SURFACE) + this->getSurfaceVecObj(geometry_name)->setNameForElement(id, new_name); + else + std::cout << "Error in GEOModels::addNameForElement() - Unknown GEOTYPE..." << std::endl; +} + +void GEOModels::addNameForObjectPoints(const std::string &geometry_name, const GEOLIB::GEOTYPE object_type, const std::string &geo_object_name, const std::string &new_name) +{ + const GEOLIB::GeoObject* obj = this->getGEOObject(geometry_name, object_type, geo_object_name); + GEOLIB::PointVec* pnt_vec = this->getPointVecObj(geometry_name); + if (object_type == GEOLIB::POLYLINE) + { + const GEOLIB::Polyline* ply = dynamic_cast<const GEOLIB::Polyline*>(obj); + size_t nPoints = ply->getNumberOfPoints(); + for (size_t i=0; i<nPoints; i++) + pnt_vec->setNameForElement(ply->getPointID(i), new_name + "_Point" + number2str(ply->getPointID(i))); } + else if (object_type == GEOLIB::SURFACE) + { + const GEOLIB::Surface* sfc = dynamic_cast<const GEOLIB::Surface*>(obj); + size_t nTriangles = sfc->getNTriangles(); + for (size_t i=0; i<nTriangles; i++) + { + const GEOLIB::Triangle* tri = (*sfc)[i]; + pnt_vec->setNameForElement((*tri)[0], new_name + "_Point" + number2str((*tri)[0])); + pnt_vec->setNameForElement((*tri)[1], new_name + "_Point" + number2str((*tri)[1])); + pnt_vec->setNameForElement((*tri)[2], new_name + "_Point" + number2str((*tri)[2])); + } + } + else + std::cout << "Error in GEOModels::addNameForElement() - Unknown GEOTYPE..." << std::endl; } + diff --git a/DataView/GEOModels.h b/DataView/GEOModels.h index 1396567f33b..b90689c32c9 100644 --- a/DataView/GEOModels.h +++ b/DataView/GEOModels.h @@ -43,15 +43,15 @@ public slots: virtual void addPointVec(std::vector<GEOLIB::Point*>* points, std::string &name, - std::map<std::string, size_t>* name_pnt_id_map = NULL); + std::map<std::string, size_t>* name_pnt_id_map = NULL, + double eps = sqrt(std::numeric_limits<double>::min())); virtual bool appendPointVec(const std::vector<GEOLIB::Point*> &points, const std::string &name, std::vector<size_t>* ids = NULL); virtual bool removePointVec(const std::string &name); virtual void addStationVec(std::vector<GEOLIB::Point*>* stations, - std::string &name, - const GEOLIB::Color* const color); + std::string &name); void filterStationVec(const std::string &name, const std::vector<PropertyBounds> &bounds); virtual bool removeStationVec(const std::string &name); @@ -72,8 +72,12 @@ public slots: const std::string &name); virtual bool removeSurfaceVec(const std::string &name); + /// Adds the name 'new_name' for the geo-object specified by the parameters void addNameForElement(const std::string &geometry_name, const GEOLIB::GEOTYPE object_type, size_t id, std::string new_name); + /// Adds a generic name to all points that are part of the specified geo-object + void addNameForObjectPoints(const std::string &geometry_name, const GEOLIB::GEOTYPE object_type, const std::string &geo_object_name, const std::string &new_name); + /// Calls all necessary functions to connect polyline-segments and update all views and windows. void connectPolylineSegments(const std::string &geoName, std::vector<size_t> indexlist, diff --git a/DataView/GMSHPrefsDialog.h b/DataView/GMSHPrefsDialog.h index 760490f9dc6..98b9ce5c2ae 100644 --- a/DataView/GMSHPrefsDialog.h +++ b/DataView/GMSHPrefsDialog.h @@ -45,7 +45,7 @@ private slots: void reject(); signals: - void requestMeshing(std::vector<std::string> const &, size_t, double, double, double, bool); + void requestMeshing(std::vector<std::string> &, size_t, double, double, double, bool); }; #endif //GMSHPREFSDIALOG_H diff --git a/DataView/GeoTreeModel.cpp b/DataView/GeoTreeModel.cpp index 95617c0ddd0..3f48f3c4094 100644 --- a/DataView/GeoTreeModel.cpp +++ b/DataView/GeoTreeModel.cpp @@ -212,7 +212,7 @@ void GeoTreeModel::addChildren(GeoObjectListItem* sfcList, { QList<QVariant> surface; std::string sfc_name(""); - sfc_name = surface_vec->getNameOfElementByID(i, sfc_name); + surface_vec->getNameOfElementByID(i, sfc_name); surface << "Surface " + QString::number(i) << QString::fromStdString(sfc_name) << "" << ""; const GEOLIB::Surface &sfc(*(*surfaces)[i]); diff --git a/DataView/GeoTreeView.cpp b/DataView/GeoTreeView.cpp index 0a9daab7211..1623bc19bdc 100644 --- a/DataView/GeoTreeView.cpp +++ b/DataView/GeoTreeView.cpp @@ -21,7 +21,7 @@ void GeoTreeView::updateView() { setAlternatingRowColors(true); //resizeColumnToContents(0); - setColumnWidth(1,150); + setColumnWidth(0,150); setColumnWidth(1,50); setColumnWidth(2,50); } @@ -87,15 +87,27 @@ void GeoTreeView::contextMenuEvent( QContextMenuEvent* event ) } else { + if (!item) // Otherwise sometimes it crashes when (unmotivated ;-) ) clicking in a treeview + return; + GeoObjectListItem* parent = dynamic_cast<GeoObjectListItem*>(item->parentItem()); // The current index refers to a geo-object if (parent != NULL) { - QAction* addCondAction = menu.addAction("Set as FEM condition..."); + QMenu* cond_menu = new QMenu("Set FEM Condition"); + menu.addMenu(cond_menu); + QAction* addCondAction = cond_menu->addAction("On object..."); + QAction* addCondPointAction = cond_menu->addAction("On all points..."); QAction* addNameAction = menu.addAction("Set name..."); - connect(addCondAction, SIGNAL(triggered()), this, SLOT(setElementAsCondition())); + connect(addCondAction, SIGNAL(triggered()), this, SLOT(setObjectAsCondition())); connect(addNameAction, SIGNAL(triggered()), this, SLOT(setNameForElement())); + + if (parent->getType() == GEOLIB::POINT) + addCondPointAction->setEnabled(false); + else + connect(addCondPointAction, SIGNAL(triggered()), this, SLOT(setObjectPointsAsCondition())); + } // The current index refers to the name of a geometry-object else if (item->childCount() > 0) @@ -104,12 +116,12 @@ void GeoTreeView::contextMenuEvent( QContextMenuEvent* event ) { QAction* saveAction = menu.addAction("Save geometry..."); QAction* addCNDAction = menu.addAction("Load FEM Conditions..."); - QAction* saveCondAction = menu.addAction("Save FEM conditions..."); + //QAction* saveCondAction = menu.addAction("Save FEM conditions..."); menu.addSeparator(); QAction* removeAction = menu.addAction("Remove geometry"); connect(saveAction, SIGNAL(triggered()), this, SLOT(writeToFile())); connect(addCNDAction, SIGNAL(triggered()), this, SLOT(loadFEMConditions())); - connect(saveCondAction, SIGNAL(triggered()), this, SLOT(saveFEMConditions())); + //connect(saveCondAction, SIGNAL(triggered()), this, SLOT(saveFEMConditions())); connect(removeAction, SIGNAL(triggered()), this, SLOT(removeList())); } } @@ -138,14 +150,14 @@ void GeoTreeView::removeList() emit listRemoved((item->data(0).toString()).toStdString(), GEOLIB::INVALID); } -void GeoTreeView::setElementAsCondition() +void GeoTreeView::setElementAsCondition(bool set_on_points) { const TreeItem* item = static_cast<GeoTreeModel*>(model())->getItem( this->selectionModel()->currentIndex()); const size_t id = item->row(); const GEOLIB::GEOTYPE type = static_cast<GeoObjectListItem*>(item->parentItem())->getType(); const std::string geometry_name = item->parentItem()->parentItem()->data(0).toString().toStdString(); - emit requestCondSetupDialog(geometry_name, type, id); + emit requestCondSetupDialog(geometry_name, type, id, set_on_points); } void GeoTreeView::setNameForElement() @@ -175,12 +187,13 @@ void GeoTreeView::loadFEMConditions() this->selectionModel()->currentIndex()); emit loadFEMCondFileRequested(item->data(0).toString().toStdString()); } - +/* void GeoTreeView::saveFEMConditions() { TreeItem* item = static_cast<GeoTreeModel*>(model())->getItem( this->selectionModel()->currentIndex()); QString fileName = QFileDialog::getSaveFileName(NULL, - "Save FEM Conditions as", "", "GeoSys FEM Condition file (*.cnd)"); + "Save FEM Conditions as", "", "OpenGeoSys FEM Condition file (*.cnd);; GeoSys Boundary Condition (*.bc);; GeoSys Initial Condition (*.ic);; GeoSys Source Condition (*.st)"); emit saveFEMConditionsRequested(item->data(0).toString(), fileName); } +*/ diff --git a/DataView/GeoTreeView.h b/DataView/GeoTreeView.h index 466289aa82a..376d2f9080b 100644 --- a/DataView/GeoTreeView.h +++ b/DataView/GeoTreeView.h @@ -38,6 +38,8 @@ protected slots: private: /// Actions to be taken after a right mouse click is performed in the station view. void contextMenuEvent( QContextMenuEvent* e ); + /// Calls a FEMConditionSetupDialog. + void setElementAsCondition(bool set_on_points = false); private slots: /// Allows to add FEM Conditions to a process @@ -45,16 +47,16 @@ private slots: void on_Clicked(QModelIndex idx); /// Calls a LineEditDialog. void connectPolylines(); - /// Calls a FEMConditionSetupDialog. - void setElementAsCondition(); /// Calls a SetNameDialog. void setNameForElement(); + void setObjectAsCondition() { setElementAsCondition(false); }; + void setObjectPointsAsCondition() { setElementAsCondition(true); }; /// Saves a geometry in a file. void writeToFile() const; /// Removes a whole geometry or parts of it. void removeList(); /// Saves FEM Conditions associated with the given geometry - void saveFEMConditions(); + //void saveFEMConditions(); signals: void geoItemSelected(const vtkPolyDataAlgorithm*, int); @@ -63,10 +65,10 @@ signals: void listRemoved(std::string name, GEOLIB::GEOTYPE); void loadFEMCondFileRequested(std::string); void saveToFileRequested(QString, QString) const; - void requestCondSetupDialog(const std::string&, const GEOLIB::GEOTYPE, const size_t); + void requestCondSetupDialog(const std::string&, const GEOLIB::GEOTYPE, const size_t, bool on_points); void requestLineEditDialog(const std::string&); void requestNameChangeDialog(const std::string&, const GEOLIB::GEOTYPE, const size_t); - void saveFEMConditionsRequested(QString, QString); + //void saveFEMConditionsRequested(QString, QString); }; #endif //GEOTREEVIEW_H diff --git a/DataView/LinearEdit.ui b/DataView/LinearEdit.ui new file mode 100644 index 00000000000..7806f69b379 --- /dev/null +++ b/DataView/LinearEdit.ui @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>LinearEdit</class> + <widget class="QDialog" name="LinearEdit"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>174</width> + <height>347</height> + </rect> + </property> + <property name="windowTitle"> + <string>Linear Edit</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QComboBox" name="comboBox"> + <item> + <property name="text"> + <string>Values</string> + </property> + </item> + <item> + <property name="text"> + <string>Elevation</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QTableWidget" name="tableWidget"> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <column> + <property name="text"> + <string>Value</string> + </property> + </column> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>LinearEdit</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>LinearEdit</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/DataView/LinearEditDialog.cpp b/DataView/LinearEditDialog.cpp new file mode 100644 index 00000000000..f23b82573f5 --- /dev/null +++ b/DataView/LinearEditDialog.cpp @@ -0,0 +1,68 @@ +/** + * \file LinearEditDialog.cpp + * 2012/04/17 KR Initial implementation + */ + +#include "LinearEditDialog.h" + +LinearEditDialog::LinearEditDialog(const GEOLIB::Polyline &line, const std::vector<size_t> &dis_nodes, const std::vector<double> &dis_values, QDialog* parent) + : QDialog(parent), _line(line) +{ + setupUi(this); + setupDialog(dis_nodes, dis_values); +} + +void LinearEditDialog::setupDialog(const std::vector<size_t> &dis_nodes, const std::vector<double> &dis_values) +{ + size_t nPoints(_line.getNumberOfPoints()); + this->tableWidget->setRowCount(nPoints); + QList<QString> indexlist; + + for (size_t i=0; i<nPoints; i++) + { + indexlist.push_back(QString::number(i)); + QTableWidgetItem *newItem = new QTableWidgetItem(""); + tableWidget->setItem(i, 0, newItem); + } + QStringList vHeaders(indexlist); + tableWidget->setVerticalHeaderLabels(vHeaders); + + size_t nValues (dis_values.size()); + for (size_t i=0; i<nValues; i++) + tableWidget->item(dis_nodes[i],0)->setText(QString::number(dis_values[i])); +} + +LinearEditDialog::~LinearEditDialog() +{ +} + +void LinearEditDialog::on_comboBox_currentIndexChanged(int index) +{ + if (index>0) //elevation + { + size_t nRows = tableWidget->rowCount(); + for (size_t i=0; i<nRows; i++) + tableWidget->item(i,0)->setText(QString::number(_line[i]->getData()[2])); + } +} + +void LinearEditDialog::accept() +{ + std::vector< std::pair<size_t,double> > linear_values; + + size_t nRows = tableWidget->rowCount(); + for (size_t i=0; i<nRows; i++) + { + QString row_text (tableWidget->item(i,0)->text()); + if (row_text.length()>0) + linear_values.push_back( std::pair<size_t, double>(i, row_text.toDouble()) ); + } + + emit transmitDisValues(linear_values); + this->done(QDialog::Accepted); +} + +void LinearEditDialog::reject() +{ + this->done(QDialog::Rejected); +} diff --git a/DataView/LinearEditDialog.h b/DataView/LinearEditDialog.h new file mode 100644 index 00000000000..41fde93c145 --- /dev/null +++ b/DataView/LinearEditDialog.h @@ -0,0 +1,43 @@ +/** + * \file LinearEditDialog.h + * 2012/04/17 KR Initial implementation + */ + +#ifndef LINEAREDITDIALOG_H +#define LINEAREDITDIALOG_H + +#include "ui_LinearEdit.h" +#include <QDialog> + +#include "Polyline.h" + +/** + * \brief A dialog window for creating linear boundary conditions on polylines + */ +class LinearEditDialog : public QDialog, private Ui_LinearEdit +{ + Q_OBJECT + +public: + LinearEditDialog(const GEOLIB::Polyline &line, const std::vector<size_t> &dis_nodes, const std::vector<double> &dis_values, QDialog* parent = 0); + ~LinearEditDialog(void); + +private: + void setupDialog(const std::vector<size_t> &dis_nodes, const std::vector<double> &dis_values); + + const GEOLIB::Polyline _line; + +private slots: + void on_comboBox_currentIndexChanged(int index); + + /// Instructions if the OK-Button has been pressed. + void accept(); + + /// Instructions if the Cancel-Button has been pressed. + void reject(); + +signals: + void transmitDisValues(std::vector< std::pair<size_t,double> >); +}; + +#endif //LINEAREDITDIALOG_H diff --git a/DataView/MshEditDialog.cpp b/DataView/MshEditDialog.cpp index 43804784d9b..1337841ef93 100644 --- a/DataView/MshEditDialog.cpp +++ b/DataView/MshEditDialog.cpp @@ -25,12 +25,13 @@ MshEditDialog::MshEditDialog(const MeshLib::CFEMesh* mesh, QDialog* parent) this->gridLayoutLayerMapping->setColumnStretch(2, 10); size_t nLayers = mesh->getNumberOfMeshLayers(); - if (nLayers == 0) - nLayers = 1; // adapt to old files where 2D meshes officially had "0" layers which makes no sense - for (size_t i = 0; i < nLayers; i++) + for (size_t i = 0; i <= nLayers+1; i++) { - QString text = (i) ? "Layer" + QString::number(i) : "Surface"; + QString text(""); + if (i==0) text="Surface"; + else if (i>nLayers) text="Layer" + QString::number(nLayers) + "-Bottom"; + else text="Layer" + QString::number(i) + "-Top"; QLabel* label = new QLabel(text); QLineEdit* edit = new QLineEdit(); QPushButton* button = new QPushButton("..."); @@ -44,12 +45,14 @@ MshEditDialog::MshEditDialog(const MeshLib::CFEMesh* mesh, QDialog* parent) this->gridLayoutLayerMapping->addWidget(_labels[i], i, 0); this->gridLayoutLayerMapping->addWidget(_edits[i], i, 1); this->gridLayoutLayerMapping->addWidget(_buttons[i], i, 2); + + if (nLayers==0) break; // don't add bottom layer if mesh contains only surface } _noDataDeleteBox = new QCheckBox("Remove mesh nodes at NoData values"); _noDataDeleteBox->setChecked(false); _noDataDeleteBox->setEnabled(false); - if (nLayers == 1) + if (nLayers == 0) { _noDataDeleteBox->setEnabled(true); this->gridLayoutLayerMapping->addWidget(_noDataDeleteBox, 2, 1); @@ -80,34 +83,39 @@ void MshEditDialog::accept() { case 0: { - int nLayers = atoi(this->editNLayers->text().toStdString().c_str()); - double thickness = - strtod(replaceString(",", ".", - this->editThickness->text().toStdString()). - c_str(), 0); - + const int nLayers = atoi(this->editNLayers->text().toStdString().c_str()); + const double thickness = strtod(replaceString(",", ".", this->editThickness->text().toStdString()).c_str(), 0); new_mesh = MshLayerMapper::CreateLayers(_msh, nLayers, thickness); break; } case 1: { - size_t nLayers = _msh->getNumberOfMeshLayers(); - if (nLayers == 0) - nLayers = 1; // adapt to old files where 2D meshes officially had "0" layers which makes no sense - - for (size_t i = 0; i < nLayers; i++) + new_mesh = new MeshLib::CFEMesh(*_msh); + const size_t nLayers = _msh->getNumberOfMeshLayers(); + if (nLayers==0) { - std::string imgPath ( this->_edits[i]->text().toStdString() ); + const std::string imgPath ( this->_edits[0]->text().toStdString() ); if (!imgPath.empty()) - new_mesh = MshLayerMapper::LayerMapping( - _msh, - imgPath, - nLayers, - i, - _noDataDeleteBox-> - isChecked()); + MshLayerMapper::LayerMapping(new_mesh, imgPath, nLayers, 0, _noDataDeleteBox->isChecked()); + } + else + { + for (size_t i = 1; i <= nLayers+1; i++) + { + const std::string imgPath ( this->_edits[i]->text().toStdString() ); + if (!imgPath.empty()) + { + int result = MshLayerMapper::LayerMapping(new_mesh, imgPath, nLayers, i-1, _noDataDeleteBox->isChecked()); + if (result==0) break; + } + } + } + if (nLayers>0 && this->_edits[0]->text().length()>0) + { + MeshLib::CFEMesh* final_mesh = MshLayerMapper::blendLayersWithSurface(new_mesh, nLayers, this->_edits[0]->text().toStdString()); + delete new_mesh; + new_mesh = final_mesh; } - //if (nLayers>1) MshLayerMapper::CheckLayerMapping(new_mesh, nLayers, 1); //TODO !!! break; } default: diff --git a/DataView/MshLayerMapper.cpp b/DataView/MshLayerMapper.cpp index f79cb3cb525..31cdd370a68 100644 --- a/DataView/MshLayerMapper.cpp +++ b/DataView/MshLayerMapper.cpp @@ -4,9 +4,10 @@ */ #include "MshLayerMapper.h" -#include "OGSRaster.h" +#include "VtkRaster.h" #include "MshEditor.h" +#include "GridAdapter.h" #include "matrix_class.h" #include "msh_mesh.h" @@ -31,18 +32,22 @@ MeshLib::CFEMesh* MshLayerMapper::CreateLayers(const MeshLib::CFEMesh* mesh, } */ MeshLib::CFEMesh* new_mesh ( new MeshLib::CFEMesh() ); - size_t nNodes = mesh->nod_vector.size(); - size_t nElems = mesh->ele_vector.size(); + const size_t nNodes = mesh->nod_vector.size(); + const size_t nElems = mesh->ele_vector.size(); - for (size_t layer_id = 0; layer_id < nLayers; layer_id++) + for (size_t layer_id = 0; layer_id <= nLayers; layer_id++) { // add nodes for new layer size_t node_offset ( nNodes * layer_id ); -// TF unused variable double z_offset ( layer_id*thickness ); + const double z_offset ( layer_id*thickness ); for (size_t i = 0; i < nNodes; i++) - new_mesh->nod_vector.push_back(new MeshLib::CNode( node_offset + i, - mesh->nod_vector[i]-> - getData())); + { + const double* coords = mesh->nod_vector[i]->getData(); + new_mesh->nod_vector.push_back( new MeshLib::CNode(node_offset + i, + coords[0], + coords[1], + coords[2]-z_offset) ); + } if (layer_id > 0) // starting with the 2nd layer prism (or hex) elements can be created { @@ -50,35 +55,30 @@ MeshLib::CFEMesh* MshLayerMapper::CreateLayers(const MeshLib::CFEMesh* mesh, node_offset = (layer_id - 1) * nNodes; for (size_t i = 0; i < nElems; i++) { + const MeshLib::CElem* sfc_elem( mesh->ele_vector[i] ); MeshLib::CElem* elem( new MeshLib::CElem() ); - size_t nElemNodes = mesh->ele_vector[i]->getNodeIndices().Size(); - if (mesh->ele_vector[i]->GetElementType() == MshElemType::TRIANGLE) - elem->setElementProperties(MshElemType::PRISM); // extrude triangles to prism - else if (mesh->ele_vector[i]->GetElementType() == MshElemType::QUAD) - elem->setElementProperties(MshElemType::HEXAHEDRON); // extrude quads to hexes - else if (mesh->ele_vector[i]->GetElementType() == MshElemType::LINE) + size_t nElemNodes = sfc_elem->getNodeIndices().Size(); + if (sfc_elem->GetElementType() == MshElemType::TRIANGLE) + elem->setElementProperties(MshElemType::PRISM); // extrude triangles to prism + else if (sfc_elem->GetElementType() == MshElemType::QUAD) + elem->setElementProperties(MshElemType::HEXAHEDRON); // extrude quads to hexes + else if (sfc_elem->GetElementType() == MshElemType::LINE) continue; // line elements are ignored and not duplicated else { - std::cout << - "Error in MshLayerMapper::CreateLayers() - Method can only handle 2D mesh elements ..." - << std::endl; - std::cout << "Element " << i << " is of type \"" << - MshElemType2String(mesh->ele_vector[i]->GetElementType()) - << - "\"." << std::endl; + std::cout << "Error in MshLayerMapper::CreateLayers() - Method can only handle 2D mesh elements ..." << std::endl; + std::cout << "Element " << i << " is of type \"" << MshElemType2String(sfc_elem->GetElementType()) << "\"." << std::endl; delete new_mesh; return NULL; } - elem->SetPatchIndex(layer_id - 1); + elem->SetPatchIndex(nLayers - layer_id); elem->SetNodesNumber(2 * nElemNodes); elem->getNodeIndices().resize(2 * nElemNodes); for (size_t j = 0; j < nElemNodes; j++) { - long idx = mesh->ele_vector[i]->GetNodeIndex(j); - elem->SetNodeIndex(j, node_offset + idx); - elem->SetNodeIndex(j + nElemNodes, - node_offset + nNodes + idx); + long idx = sfc_elem->GetNodeIndex(j); + elem->SetNodeIndex(nElemNodes-j-1, node_offset + idx); + elem->SetNodeIndex(nElemNodes-j-1 + nElemNodes, node_offset + nNodes + idx); } new_mesh->ele_vector.push_back(elem); } @@ -88,103 +88,90 @@ MeshLib::CFEMesh* MshLayerMapper::CreateLayers(const MeshLib::CFEMesh* mesh, new_mesh->setNumberOfNodesFromNodesVectorSize (); new_mesh->setNumberOfMeshLayers(nLayers); - // HACK this crashes on linux systems probably because of uninitialised variables in the the element class new_mesh->ConstructGrid(); new_mesh->FillTransformMatrix(); return new_mesh; } -// KR, based on code by WW -MeshLib::CFEMesh* MshLayerMapper::LayerMapping(const MeshLib::CFEMesh* msh, +int MshLayerMapper::LayerMapping(MeshLib::CFEMesh* new_mesh, const std::string &rasterfile, const size_t nLayers, const size_t layer_id, bool removeNoDataValues) { - if (msh == NULL) - return NULL; - if (msh->getNumberOfMeshLayers() >= layer_id) + if (new_mesh == NULL) { - if (msh == NULL) - { - std::cout << - "Error in MshLayerMapper::LayerMapping() - Passed Mesh is NULL..." << - std::endl; - return NULL; - } - MeshLib::CFEMesh* new_mesh( new MeshLib::CFEMesh(*msh) ); + std::cout << + "Error in MshLayerMapper::LayerMapping() - Passed Mesh is NULL..." << + std::endl; + return 0; + } + if (new_mesh->getNumberOfMeshLayers() >= layer_id) + { double x0(0), y0(0), delta(1); size_t width(1), height(1); - double* elevation = OGSRaster::loadDataFromASC(QString::fromStdString( - rasterfile), x0, y0, width, - height, delta); + float* elevation = VtkRaster::loadDataFromASC(rasterfile, x0, y0, width,height, delta); if (elevation == NULL) { delete [] elevation; - return NULL; + return 0; } - std::pair<double, double> xDim(x0, x0 + width * delta); // extension in x-dimension - std::pair<double, double> yDim(y0, y0 + height * delta); // extension in y-dimension + const std::pair<double, double> xDim(x0, x0 + width * delta); // extension in x-dimension + const std::pair<double, double> yDim(y0, y0 + height * delta); // extension in y-dimension if (!meshFitsImage(new_mesh, xDim, yDim)) { delete [] elevation; - return NULL; + return 0; } - double locX[4]; - double locY[4]; - double locZ[4]; - - size_t nNodes = msh->nod_vector.size(); - size_t nNodesPerLayer = nNodes / nLayers; + const size_t nNodes = new_mesh->nod_vector.size(); + const size_t nNodesPerLayer = nNodes / (nLayers+1); - size_t firstNode = layer_id * nNodesPerLayer; - size_t lastNode = firstNode + nNodesPerLayer; + const size_t firstNode = layer_id * nNodesPerLayer; + const size_t lastNode = firstNode + nNodesPerLayer; std::vector<size_t> noData_nodes; - + const double half_delta = 0.5*delta; for(size_t i = firstNode; i < lastNode; i++) { - size_t xPos (static_cast<size_t>(floor( - (msh->nod_vector[i]->getData()[0] - - xDim.first) / delta))); - size_t yPos (static_cast<size_t>(floor( - (msh->nod_vector[i]->getData()[1] - - yDim.first) / delta))); - - locX[0] = xDim.first + xPos * delta; - locY[0] = yDim.first + yPos * delta; - locZ[0] = elevation[yPos * width + xPos]; - - locX[1] = xDim.first + (xPos + 1) * delta; - locY[1] = yDim.first + yPos * delta; - locZ[1] = elevation[yPos * width + (xPos + 1)]; - - locX[2] = xDim.first + (xPos + 1) * delta; - locY[2] = yDim.first + (yPos + 1) * delta; - locZ[2] = elevation[(yPos + 1) * width + (xPos + 1)]; - - locX[3] = xDim.first + xPos * delta; - locY[3] = yDim.first + (yPos + 1) * delta; - locZ[3] = elevation[(yPos + 1) * width + xPos]; - - bool noData(false); - for(size_t j = 0; j < 4; j++) - if(fabs(locZ[j] + 9999) < std::numeric_limits<double>::min()) - noData = true; - - if(!noData) + const double* coords = new_mesh->nod_vector[i]->getData(); + // position in raster + const double xPos ((coords[0] - xDim.first) / delta); + const double yPos ((coords[1] - yDim.first) / delta); + // raster cell index + const size_t xIdx (static_cast<size_t>(floor(xPos))); + const size_t yIdx (static_cast<size_t>(floor(yPos))); + + // deviation of mesh node from centre of raster cell ( in [-1:1) because it is normalised by delta/2 ) + const double xShift = (xPos-xIdx-half_delta)/half_delta; + const double yShift = (yPos-yIdx-half_delta)/half_delta; + + const int xShiftIdx = (xShift>=0) ? ceil(xShift) : floor(xShift); + const int yShiftIdx = (yShift>=0) ? ceil(yShift) : floor(yShift); + + // determining the neighbouring pixels that add weight to the interpolation + const size_t x_nb[4] = {0, xShiftIdx, xShiftIdx, 0}; + const size_t y_nb[4] = {0, 0, yShiftIdx, yShiftIdx}; + + double locZ[4]; + locZ[0] = elevation[2*(yIdx*width + xIdx)]; + if (fabs(locZ[0] + 9999) > std::numeric_limits<double>::min()) { - // Interpolate + for (size_t j=1; j<4; j++) + { + locZ[j] = elevation[2*((yIdx+y_nb[j])*width + (xIdx+x_nb[j]))]; + if (fabs(locZ[j] + 9999) < std::numeric_limits<double>::min()) + locZ[j]=locZ[0]; + } + double ome[4]; - double const* const coords (msh->nod_vector[i]->getData()); - double xi = 2.0 * (coords[0] - 0.5 * (locX[0] + locX[1])) / delta; - double eta = 2.0 * (coords[1] - 0.5 * (locY[1] + locY[2])) / delta; + double xi = 1-fabs(xShift); + double eta = 1-fabs(xShift); MPhi2D(ome, xi, eta); double z(0.0); @@ -195,14 +182,13 @@ MeshLib::CFEMesh* MshLayerMapper::LayerMapping(const MeshLib::CFEMesh* msh, } else { - //std::cout << "Warning: No elevation data available for node " << i << " (" << msh->nod_vector[i]->X() << ", " << msh->nod_vector[i]->Y() << ")." << std::endl; new_mesh->nod_vector[i]->SetZ(0); new_mesh->nod_vector[i]->SetMark(false); noData_nodes.push_back(i); } } - if ((nLayers == 1) && removeNoDataValues) + if ((nLayers == 0) && removeNoDataValues) { if (noData_nodes.size() < (new_mesh->nod_vector.size() - 2)) { @@ -226,17 +212,14 @@ MeshLib::CFEMesh* MshLayerMapper::LayerMapping(const MeshLib::CFEMesh* msh, std::cout << "Too many NoData values..." << std::endl; } - new_mesh->ConstructGrid(); - new_mesh->FillTransformMatrix(); - delete [] elevation; - return new_mesh; + return 1; } else std::cout << "Error in MshLayerMapper::LayerMapping() - Mesh has only " << - msh->getNumberOfMeshLayers() << " Layers, cannot assign layer " << layer_id << + new_mesh->getNumberOfMeshLayers() << " Layers, cannot assign layer " << layer_id << "..." << std::endl; - return NULL; + return 0; } // KR, based on code by WW (Note: this method has not been tested yet and will probably fail miserably!) @@ -273,345 +256,158 @@ bool MshLayerMapper::meshFitsImage(const MeshLib::CFEMesh* msh, return true; } -void MshLayerMapper::CheckLayerMapping(MeshLib::CFEMesh* mesh, const size_t nLayers, int integ) +MeshLib::CFEMesh* MshLayerMapper::blendLayersWithSurface(MeshLib::CFEMesh* mesh, const size_t nLayers, const std::string &dem_raster) { - double ref_dep = -999999999.0; - - size_t nNodesPerLayer = mesh->nod_vector.size() / (nLayers + 1); - - //18.02.2009 WW - if (integ) + // construct surface mesh from DEM + MeshLib::CFEMesh* dem = MshEditor::getMeshSurface(*mesh); + MshLayerMapper::LayerMapping(dem, dem_raster, 0, 0); + + const size_t nNodes = mesh->nod_vector.size(); + const size_t nNodesPerLayer = nNodes / (nLayers+1); + std::vector<bool> is_surface_node(nNodes, false); + std::vector<bool> nodes_below_surface(nNodes, false); + + // check if bottom layer nodes are below DEM + const size_t bottom_firstNode = nLayers * nNodesPerLayer; + const size_t bottom_lastNode = bottom_firstNode + nNodesPerLayer; + for(size_t i = bottom_firstNode; i < bottom_lastNode; i++) { - for (size_t i = 0; i < nNodesPerLayer; i++) - for (size_t k = 0; k < nLayers; k++) - { - MeshLib::CNode* node = mesh->nod_vector[k * nNodesPerLayer + i]; - if (k == 0) - node->SetBoundaryType('0'); // on the surface - else if (k == (nLayers - 1)) - node->SetBoundaryType('1'); // on the bottom - else - node->SetBoundaryType('I'); // interior node - } + nodes_below_surface[i]=true; + const double* coords = mesh->nod_vector[i]->getData(); + const double* dem_coords = dem->nod_vector[i-bottom_firstNode]->getData(); + if (coords[2] >= dem_coords[2]) + { + std::cout << "Warning: Node " << i << " (in bottom-layer) is above surface node " << (i-bottom_firstNode) << ". (" << coords[2] << " > " << dem_coords[2] << ")" << std::endl; + is_surface_node[i] = true; + } } - size_t flat(0); - for (size_t i = 0; i < nNodesPerLayer; i++) + // for all other layers: + // if node < dem-node: do nothing + // if node > dem-node: + // if first node above surface: map to dem and mark as surface node + // else remove node + for (int layer_id=nLayers-1; layer_id>=0; layer_id--) { - std::vector<long> tmp_connected_nodes; - flat = 0; + const size_t firstNode = layer_id * nNodesPerLayer; + const size_t lastNode = firstNode + nNodesPerLayer; - for (size_t k = 0; k < nLayers - 2; k++) // top layer is not checked + for(size_t i = firstNode; i < lastNode; i++) { - MeshLib::CNode* bNode = mesh->nod_vector[k * nNodesPerLayer + i]; // current node - MeshLib::CNode* tNode = mesh->nod_vector[(k + 1) * nNodesPerLayer + i]; // same node but one layer below - - if (!tNode->GetMark()) + if (is_surface_node[i+nNodesPerLayer]) + is_surface_node[i]=true; + else { - if (k == 0) - { - tmp_connected_nodes.clear(); - std::vector<size_t> const& connected_nodes ( - tNode->getConnectedNodes()); - const size_t n_connected_nodes (connected_nodes.size()); - for (size_t j = 0; j < n_connected_nodes; j++) - tmp_connected_nodes.push_back(connected_nodes[j]); - } - - tNode->SetZ(bNode->getData()[2]); // z coordinate changed to layer above - tNode->getConnectedNodes().clear(); - for (int j = k; j >= 0; j--) //WW/YW. 23.01.2009 + nodes_below_surface[i]=true; + MeshLib::CNode* node (mesh->nod_vector[i]); + const double* coords = node->getData(); + const double* dem_coords = dem->nod_vector[i-firstNode]->getData(); + if (coords[2] > dem_coords[2]) { - MeshLib::CNode* nNode = - mesh->nod_vector[j * nNodesPerLayer + i]; - if (nNode->GetMark()) - { - tNode->getConnectedNodes().push_back( - nNode->GetIndex()); - break; - } + const double new_coords[3] = { dem_coords[0], dem_coords[1], dem_coords[2] }; + node->SetCoordinates(new_coords); + is_surface_node[i] = true; } - flat++; - } - } - - //---- 27.01.2009. WW - if (flat == nLayers - 2 /*1*/) - { - MeshLib::CNode* bNode = mesh->nod_vector[nNodesPerLayer + i]; - bNode->SetMark(true); - bNode->getConnectedNodes().clear(); - for (size_t j = 0; j < tmp_connected_nodes.size(); j++) - bNode->getConnectedNodes().push_back(tmp_connected_nodes[j]); - - MeshLib::CNode* tNode = - mesh->nod_vector[(nLayers - 1) * nNodesPerLayer + i]; - tNode->SetMark(false); - bNode->SetZ(tNode->getData()[2]); - bNode->SetBoundaryType('1'); - // - for (size_t k = 1; k < nLayers; k++) - { - tNode = mesh->nod_vector[(k + 1) * nNodesPerLayer + i]; - tNode->SetZ(ref_dep); - tNode->getConnectedNodes().clear(); - tNode->getConnectedNodes().push_back(bNode->GetIndex()); } } } - std::vector<MeshLib::CElem*> new_elems; - std::vector<size_t> false_node_idx; - size_t nElems = mesh->ele_vector.size(); - for(size_t i = 0; i < nElems; i++) - { - MeshLib::CElem* elem = mesh->ele_vector[i]; - elem->SetMark(true); - - flat = 0; - for (size_t k = 0; k < 3; k++) //skip element when one node is marked ref_dep - - if ( fabs(elem->GetNode(k)->getData()[2] + ref_dep) < - std::numeric_limits<double>::min() || - fabs(elem->GetNode(k + 3)->getData()[2] + ref_dep) < - std::numeric_limits<double>::min() ) - { - flat = 1; - elem->SetMark(false); - break; - } - if (flat == 1) - continue; - - // If all nodes are okay, check if two z-values are identical - for (size_t k = 0; k < 3; k++) - if(fabs(elem->GetNode(k + - 3)->getData()[2] - elem->GetNode(k)->getData()[2]) < - std::numeric_limits<double>::min()) - false_node_idx.push_back(k); - - switch(false_node_idx.size()) - { - case 0: // everything okay, take the prism as it is - { - elem->SetMark(true); - break; - } - case 1: // one node of the prism is marked false, i.e. create two tetrahedron elements from the remaining 5 prism nodes - { - size_t a = false_node_idx[0]; - size_t b = (a + 2) % 3; - size_t c = (a + 1) % 3; - - if (elem->GetNode(a + 3)->GetBoundaryType() == '1') //24.02.2009. WW - elem->GetNode(a)->SetBoundaryType('1'); - - // create a new tetrahedron - MeshLib::CElem* new_elem( new MeshLib::CElem() ); - new_elem->SetMark(true); - new_elem->SetElementType(MshElemType::TETRAHEDRON); - new_elem->SetPatchIndex(elem->GetPatchIndex()); - new_elem->SetBoundaryType('I'); - new_elem->SetNodesNumber(4); - - Math_Group::vec<MeshLib::CNode*> nodes(4); - nodes[0] = mesh->nod_vector[elem->getNodeIndices()[a]]; - nodes[1] = mesh->nod_vector[elem->getNodeIndices()[b + 3]]; - nodes[2] = mesh->nod_vector[elem->getNodeIndices()[c + 3]]; - nodes[3] = mesh->nod_vector[elem->getNodeIndices()[c]]; - new_elem->SetNodes(nodes, true); - - new_elem->getNodeIndices().resize(4); - for (size_t k = 0; k < 4; k++) - new_elem->getNodeIndices()[k] = elem->GetNode(k)->GetIndex(); - new_elems.push_back(new_elem); - - // change prism-element to 2nd tetrahedron - elem->SetMark(true); - elem->SetElementType(MshElemType::TETRAHEDRON); - elem->SetNodesNumber(4); - - nodes[0] = mesh->nod_vector[elem->getNodeIndices()[b]]; - nodes[1] = mesh->nod_vector[elem->getNodeIndices()[a]]; - nodes[2] = mesh->nod_vector[elem->getNodeIndices()[c]]; - nodes[3] = mesh->nod_vector[elem->getNodeIndices()[b + 3]]; - elem->SetNodes(nodes, true); - - elem->getNodeIndices().resize(4); - for (size_t k = 0; k < 4; k++) - elem->getNodeIndices()[k] = elem->GetNode(k)->GetIndex(); - break; - } - case 2: // two nodes of the prism are marked false, i.e. create a tetrahedron element from the remaining 4 prism nodes - { - size_t a = false_node_idx[0]; - size_t b = (a + 2) % 3; - size_t c = (a + 1) % 3; - if (false_node_idx[1] == b) - a = c; - else if(false_node_idx[1] == c) - a = b; - - elem->SetMark(true); - elem->SetElementType(MshElemType::TETRAHEDRON); - elem->SetNodesNumber(4); - - Math_Group::vec<MeshLib::CNode*> nodes(4); - nodes[0] = mesh->nod_vector[elem->getNodeIndices()[b]]; - nodes[1] = mesh->nod_vector[elem->getNodeIndices()[a]]; - nodes[2] = mesh->nod_vector[elem->getNodeIndices()[c]]; - nodes[3] = mesh->nod_vector[elem->getNodeIndices()[a + 3]]; - elem->SetNodes(nodes, true); - - elem->getNodeIndices().resize(4); - for (size_t k = 0; k < 4; k++) - elem->getNodeIndices()[k] = elem->GetNode(k)->GetIndex(); - /* - //for j, l nodes if they becomes on top surface. 24.02.2009. WW - if (node_b->GetBoundaryType()=='1') - elem->nodes[0]->SetBoundaryType('1'); - if (node_t->GetBoundaryType()=='1') - elem->nodes[2]->SetBoundaryType('1'); - */ - break; - } - case 3: // three nodes of the prism is marked false, ditch the whole element - { - elem->SetMark(false); - break; - } - } - } - - // add the newly created elements to the elements vector - for(size_t i = 0; i < new_elems.size(); i++) - mesh->ele_vector.push_back(new_elems[i]); - - // correct indeces of elements and delete false elements - std::vector<MeshLib::CElem*>::iterator beg_e = mesh->ele_vector.begin( ), last_e; - long counter = 0; - while ( beg_e != mesh->ele_vector.end() ) + std::vector<GEOLIB::Point*> *nodes = new std::vector<GEOLIB::Point*>; + std::vector<int> node_index_map(nNodes, -1); + size_t node_count(0); + for (size_t j=0; j<nNodes; j++) { - last_e = beg_e++; - MeshLib::CElem* elem = *last_e; - if (elem->GetMark()) + if (nodes_below_surface[j]) { - elem->SetIndex(counter); - counter++; - /* KR unused variable - for (int j=0; j<elem->GetVertexNumber(); j++) - { - if (!elem->GetNode(j)->GetMark()) - { - MeshLib::CNode* node = mesh->nod_vector[elem->GetNode(j)->connected_nodes[0]]; - } - } - */ - } - else - { - delete elem; - beg_e = mesh->ele_vector.erase(last_e); - } - } - - // correct indeces of nodes and delete false nodes - counter = 0; - std::vector<MeshLib::CNode*>::iterator beg = mesh->nod_vector.begin( ), last; - while ( beg != mesh->nod_vector.end( ) ) - { - last = beg++; - MeshLib::CNode* node = *last; - if (node->GetMark()) - { - node->SetIndex(counter); - node->getConnectedElementIDs().clear(); - node->getConnectedNodes().clear(); - counter++; - } - else - { - delete node; - node = NULL; - beg = mesh->nod_vector.erase(last); - } + nodes->push_back(new GEOLIB::Point(mesh->nod_vector[j]->getData())); + node_index_map[j]=node_count++; + } } - // correct element indeces again after deleting nodes - nElems = mesh->ele_vector.size(); - for(size_t i = 0; i < nElems; i++) - for(int j = 0; j < mesh->ele_vector[i]->GetVertexNumber(); j++) - mesh->ele_vector[i]->getNodeIndices()[j] = - mesh->ele_vector[i]->GetNode(j)->GetIndex(); - - // delete elements if two of its nodes are identical (can this actually happen?????) - beg_e = mesh->ele_vector.begin(); - counter = 0; - bool flatf = false; - while ( beg_e != mesh->ele_vector.end( ) ) + const size_t nElems = mesh->ele_vector.size(); + std::vector<GridAdapter::Element*> *elements = new std::vector<GridAdapter::Element*>; + for (size_t j=0; j<nElems; j++) { - last_e = beg_e++; - MeshLib::CElem* elem = *last_e; - - //10.02.2009. WW !!!!!!!!!!!!!!!!!!!!!! - for (int j = 0; j < elem->GetVertexNumber(); j++) + const MeshLib::CElem* elem = mesh->ele_vector[j]; + + size_t count(0); + for (size_t i=0; i<6; i++) // check top surface of prism + if (nodes_below_surface[elem->GetNodeIndex(i)]) count++; + + if (count==6) // copy prism elements if all six nodes are valid { - flatf = false; - for (int k = j; k < elem->GetVertexNumber(); k++) - if (elem->GetNodeIndex(j) == elem->GetNodeIndex(k)) - { - flatf = true; - break; - } + GridAdapter::Element* prism = new GridAdapter::Element; + std::vector<size_t> elem_nodes; + for (size_t i=0; i<6; i++) + elem_nodes.push_back( node_index_map[elem->GetNodeIndex(i)] ); + prism->material = elem->GetPatchIndex(); + prism->type = MshElemType::PRISM; + prism->nodes = elem_nodes; + elements->push_back(prism); } - if (flatf) + else if (count==5) // change the current element to two tetrahedra if only five nodes are valid { - delete elem; - beg_e = mesh->ele_vector.erase(last_e); + GridAdapter::Element* tet1 = new GridAdapter::Element; + std::vector<size_t> elem_nodes; + if (nodes_below_surface[elem->GetNodeIndex(0)]) + elem_nodes.push_back( node_index_map[elem->GetNodeIndex(0)] ); + else + elem_nodes.push_back( node_index_map[elem->GetNodeIndex(1)] ); + for (size_t i=3; i<6; i++) + elem_nodes.push_back( node_index_map[elem->GetNodeIndex(i)] ); + tet1->material = elem->GetPatchIndex(); + tet1->type = MshElemType::TETRAHEDRON; + tet1->nodes = elem_nodes; + elements->push_back(tet1); + + GridAdapter::Element* tet2 = new GridAdapter::Element; + std::vector<size_t> elem_nodes2; + if (nodes_below_surface[elem->GetNodeIndex(0)]) + { + elem_nodes2.push_back( node_index_map[elem->GetNodeIndex(0)] ); + if (nodes_below_surface[elem->GetNodeIndex(1)]) + elem_nodes2.push_back( node_index_map[elem->GetNodeIndex(1)] ); + else + elem_nodes2.push_back( node_index_map[elem->GetNodeIndex(2)] ); + elem_nodes2.push_back( node_index_map[elem->GetNodeIndex(5)] ); + elem_nodes2.push_back( node_index_map[elem->GetNodeIndex(4)] ); + } + else + { + elem_nodes2.push_back( node_index_map[elem->GetNodeIndex(1)] ); + elem_nodes2.push_back( node_index_map[elem->GetNodeIndex(2)] ); + elem_nodes2.push_back( node_index_map[elem->GetNodeIndex(3)] ); + elem_nodes2.push_back( node_index_map[elem->GetNodeIndex(5)] ); + } + tet2->material = elem->GetPatchIndex(); + tet2->type = MshElemType::TETRAHEDRON; + tet2->nodes = elem_nodes2; + elements->push_back(tet2); } - else + else if (count==4) // change the current element to a tetrahedron if only four nodes are valid { - elem->SetIndex(counter); - counter++; - /* KR unused variable - for (int j=0; j<elem->GetVertexNumber(); j++) - { - if (!elem->GetNode(j)->GetMark()) - { - MeshLib::CNode* node = mesh->nod_vector[elem->GetNode(j)->connected_nodes[0]]; - } - } - */ - } - } + std::vector<size_t> elem_nodes; + for (size_t i=0; i<3; i++) + if (nodes_below_surface[elem->GetNodeIndex(i)]) + elem_nodes.push_back( node_index_map[elem->GetNodeIndex(i)] ); - mesh->ConnectedElements2Node(); - - // delete nodes that are not connected to any element (can this happen???) - counter = 0; - beg = mesh->nod_vector.begin( ); - while ( beg != mesh->nod_vector.end( ) ) - { - last = beg++; - MeshLib::CNode* node = *last; - if ( node->getConnectedElementIDs().empty() ) - { - delete node; - node = NULL; - beg = mesh->nod_vector.erase(last); - } - else - { - node->SetIndex(counter); - counter++; + if (elem_nodes.size()==1) // make sure than only one node is from the upper layer and three from the lower + { + for (size_t i=3; i<6; i++) + elem_nodes.push_back( node_index_map[elem->GetNodeIndex(i)] ); + GridAdapter::Element* tet = new GridAdapter::Element; + tet->material = elem->GetPatchIndex(); + tet->type = MshElemType::TETRAHEDRON; + tet->nodes = elem_nodes; + elements->push_back(tet); + } } + // else remove element, if less than four nodes are valid } - - nElems = mesh->ele_vector.size(); - for (size_t i = 0; i < nElems; i++) - for (int j = 0; j < mesh->ele_vector[i]->GetVertexNumber(); j++) - mesh->ele_vector[i]->getNodeIndices()[j] = - mesh->ele_vector[i]->GetNode(j)->GetIndex(); - - mesh->ConstructGrid(); + GridAdapter grid; + grid.setNodeVector(nodes); + grid.setElements(elements); + MeshLib::CFEMesh* struct_mesh = new MeshLib::CFEMesh(*grid.getCFEMesh()); + return struct_mesh; } + diff --git a/DataView/MshLayerMapper.h b/DataView/MshLayerMapper.h index da1efe476b5..daf3833971a 100644 --- a/DataView/MshLayerMapper.h +++ b/DataView/MshLayerMapper.h @@ -36,16 +36,14 @@ public: double thickness); /// Maps the z-values of nodes in the designated layer of the given mesh according to the given raster. - static MeshLib::CFEMesh* LayerMapping(const MeshLib::CFEMesh* msh, + static int LayerMapping(MeshLib::CFEMesh* msh, const std::string &rasterfile, const size_t nLayers, const size_t layer_id, bool removeNoDataValues = false); - /// \brief Checks for overlapping nodes between between layers and corrects these errors. - /// Note: this method has not been tested yet and will probably fail miserably! Please contact KR - /// if you intend to use it! - static void CheckLayerMapping(MeshLib::CFEMesh* mesh, const size_t nLayers, int integ); + /// Blends a mesh with the surface given by dem_raster. Nodes and elements above the surface are either removed or adapted to fit the surface. + static MeshLib::CFEMesh* blendLayersWithSurface(MeshLib::CFEMesh* mesh, const size_t nLayers, const std::string &dem_raster); private: /// Checks if the given mesh is within the dimensions given by xDim and yDim. diff --git a/DataView/MshModel.cpp b/DataView/MshModel.cpp index 1afa1fa2561..b508d2c056d 100644 --- a/DataView/MshModel.cpp +++ b/DataView/MshModel.cpp @@ -38,11 +38,22 @@ int MshModel::columnCount( const QModelIndex &parent /*= QModelIndex()*/ ) const void MshModel::addMesh(MeshLib::CFEMesh* mesh, std::string &name) { _project.addMesh(mesh, name); - this->addMeshObject(new GridAdapter(mesh), name); + GridAdapter* grid = new GridAdapter(mesh); + grid->setName(name); + this->addMeshObject(grid); } -void MshModel::addMeshObject(GridAdapter* mesh, std::string &name) +void MshModel::addMesh(GridAdapter* mesh) { + MeshLib::CFEMesh* ogsmesh( const_cast<MeshLib::CFEMesh*>(mesh->getCFEMesh()) ); + std::string msh_name = mesh->getName(); + _project.addMesh(ogsmesh, msh_name); + this->addMeshObject(mesh); +} + +void MshModel::addMeshObject(GridAdapter* mesh) +{ + std::string name(mesh->getName()); std::cout << "name: " << name << std::endl; QFileInfo fi(QString::fromStdString(name)); name = fi.baseName().toStdString(); @@ -56,17 +67,18 @@ void MshModel::addMeshObject(GridAdapter* mesh, std::string &name) // display elements const std::vector<GridAdapter::Element*>* elems = mesh->getElements(); - size_t nElems (elems->size()); + const size_t nElems (elems->size()); for (size_t i = 0; i < nElems; i++) { + const GridAdapter::Element* current_element = (*elems)[i]; QList<QVariant> elemData; elemData << "Element " + QString::number(i) << QString::fromStdString( - MshElemType2String((*elems)[i]->type)); + MshElemType2String(current_element->type)); QString nodestxt(""); - size_t nNodes((*elems)[i]->nodes.size()); + const size_t nNodes(current_element->nodes.size()); for (size_t j = 0; j < nNodes; j++) - nodestxt.append(QString::number((*elems)[i]->nodes[j]) + ", "); + nodestxt.append(QString::number(current_element->nodes[j]) + ", "); elemData << nodestxt.left(nodestxt.length() - 2); TreeItem* elem = new TreeItem(elemData, newMesh); @@ -121,7 +133,6 @@ bool MshModel::removeMesh(const QModelIndex &idx) return false; } - //std::cout << "MshModel::removeMesh() - Specified index does not exist." << std::endl; return false; } @@ -152,7 +163,7 @@ void MshModel::updateModel() if (this->getMesh(it->first) == NULL) // if GridAdapter does not yet exist, create one. { std::string name = it->first; - addMeshObject(new GridAdapter(it->second), name); + addMeshObject(new GridAdapter(it->second)); } } @@ -182,39 +193,4 @@ VtkMeshSource* MshModel::vtkSource(const std::string &name) const return NULL; } -/* - bool MshModel::isUniqueMeshName(std::string &name) - { - int count(0); - bool isUnique(false); - std::string cpName; - - while (!isUnique) - { - isUnique = true; - cpName = name; - - count++; - // If the original name already exists we start to add numbers to name for - // as long as it takes to make the name unique. - if (count>1) cpName = cpName + "-" + number2str(count); - - for (int i=0; i<_rootItem->childCount(); i++) - { - TreeItem* item = _rootItem->child(i); - if (item->data(0).toString().toStdString().compare(cpName) == 0) isUnique = false; - } - } - - // At this point cpName is a unique name and isUnique is true. - // If cpName is not the original name, "name" is changed and isUnique is set to false, - // indicating that a vector with the original name already exists. - if (count>1) - { - isUnique = false; - name = cpName; - } - return isUnique; - } - */ diff --git a/DataView/MshModel.h b/DataView/MshModel.h index 06890a0c89a..c64edaa90c4 100644 --- a/DataView/MshModel.h +++ b/DataView/MshModel.h @@ -30,7 +30,9 @@ public: public slots: /// Adds a new mesh - void addMesh(MeshLib::CFEMesh* mesh, std::string &name); + void addMesh(GridAdapter* mesh); + /// Adds a new mesh + void addMesh(MeshLib::CFEMesh* mesh, std::string &name); // needs only to be a slot for MshLayerMapper. Otherwise normal function would be okay. /// Returns the mesh with the given index. const GridAdapter* getMesh(const QModelIndex &idx) const; /// Returns the mesh with the given name. @@ -48,7 +50,7 @@ public slots: private: /// Adds the mesh to the GUI-Mesh-Model und -View - void addMeshObject(GridAdapter* mesh, std::string &name); + void addMeshObject(GridAdapter* mesh); /// Checks if the name of the mesh is already exists, if so it generates a unique name. //bool isUniqueMeshName(std::string &name); diff --git a/DataView/NetCdfConfigure.ui b/DataView/NetCdfConfigure.ui new file mode 100644 index 00000000000..18ed8e38a2c --- /dev/null +++ b/DataView/NetCdfConfigure.ui @@ -0,0 +1,801 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>NetCdfConfigure</class> + <widget class="QDialog" name="NetCdfConfigure"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>477</width> + <height>460</height> + </rect> + </property> + <property name="cursor"> + <cursorShape>SizeAllCursor</cursorShape> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Variable</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="comboBoxVariable"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item row="1" column="0" colspan="3"> + <widget class="QGroupBox" name="groupBoxDimensions"> + <property name="minimumSize"> + <size> + <width>450</width> + <height>100</height> + </size> + </property> + <property name="title"> + <string>Dimensions for the Axis</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="3"> + <widget class="QDoubleSpinBox" name="doubleSpinBoxDim1End"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="minimumSize"> + <size> + <width>110</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>110</width> + <height>16777215</height> + </size> + </property> + <property name="wrapping"> + <bool>false</bool> + </property> + <property name="frame"> + <bool>true</bool> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="accelerated"> + <bool>false</bool> + </property> + <property name="maximum"> + <double>10000000.000000000000000</double> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QDoubleSpinBox" name="doubleSpinBoxDim1Start"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="minimumSize"> + <size> + <width>110</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="maximum"> + <double>10000000.000000000000000</double> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QDoubleSpinBox" name="doubleSpinBoxDim2Start"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="minimumSize"> + <size> + <width>110</width> + <height>0</height> + </size> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="maximum"> + <double>10000000.000000000000000</double> + </property> + </widget> + </item> + <item row="2" column="3"> + <widget class="QDoubleSpinBox" name="doubleSpinBoxDim2End"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="minimumSize"> + <size> + <width>110</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>110</width> + <height>16777215</height> + </size> + </property> + <property name="font"> + <font> + <italic>false</italic> + </font> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="maximum"> + <double>10000000.000000000000000</double> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Value Start</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Value End</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="comboBoxDim1"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="comboBoxDim2"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_4"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Lat</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_8"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Lon</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="8" column="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="8" column="0" colspan="2"> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="2"> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0" colspan="3"> + <widget class="QGroupBox" name="groupBox"> + <property name="minimumSize"> + <size> + <width>450</width> + <height>0</height> + </size> + </property> + <property name="title"> + <string>Other Dimensions</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <widget class="QLabel" name="label_9"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Time</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_10"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Others</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="comboBoxDim3"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="comboBoxDim4"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QSpinBox" name="spinBoxDim4"> + <property name="minimumSize"> + <size> + <width>110</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>110</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QDateTimeEdit" name="dateTimeEditDim3"> + <property name="minimumSize"> + <size> + <width>110</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>110</width> + <height>16777215</height> + </size> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="dateTime"> + <datetime> + <hour>0</hour> + <minute>0</minute> + <second>0</second> + <year>1900</year> + <month>1</month> + <day>1</day> + </datetime> + </property> + <property name="date"> + <date> + <year>1900</year> + <month>1</month> + <day>1</day> + </date> + </property> + <property name="maximumDateTime"> + <datetime> + <hour>23</hour> + <minute>59</minute> + <second>59</second> + <year>2200</year> + <month>12</month> + <day>31</day> + </datetime> + </property> + <property name="minimumDateTime"> + <datetime> + <hour>0</hour> + <minute>0</minute> + <second>0</second> + <year>1900</year> + <month>1</month> + <day>1</day> + </datetime> + </property> + <property name="displayFormat"> + <string>dd.MM.yyyy</string> + </property> + <property name="calendarPopup"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="3" column="3"> + <spacer name="horizontalSpacer_8"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="3"> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="3" column="0" colspan="3"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="minimumSize"> + <size> + <width>450</width> + <height>0</height> + </size> + </property> + <property name="title"> + <string>Parameters</string> + </property> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="0" column="0"> + <widget class="QLabel" name="label_5"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Resolution</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <spacer name="horizontalSpacer_9"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <widget class="QDoubleSpinBox" name="doubleSpinBoxResolution"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="decimals"> + <number>3</number> + </property> + <property name="minimum"> + <double>0.000000000000000</double> + </property> + <property name="maximum"> + <double>10000.000000000000000</double> + </property> + <property name="singleStep"> + <double>1.000000000000000</double> + </property> + <property name="value"> + <double>1.000000000000000</double> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>m</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="7" column="0" colspan="3"> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>Object</string> + </property> + <layout class="QGridLayout" name="gridLayout_6"> + <item row="0" column="0"> + <widget class="QLabel" name="label_12"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Name</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEditName"> + <property name="minimumSize"> + <size> + <width>220</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>110</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="0" column="2"> + <spacer name="horizontalSpacer_6"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="4" column="0" colspan="3"> + <widget class="QGroupBox" name="groupBoxMesh"> + <property name="minimumSize"> + <size> + <width>450</width> + <height>50</height> + </size> + </property> + <property name="title"> + <string>Output</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="2"> + <widget class="QLabel" name="label_2"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Mesh Element Type</string> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QComboBox" name="comboBoxMeshElemType"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <item> + <property name="text"> + <string>Quad</string> + </property> + </item> + <item> + <property name="text"> + <string>Triangle</string> + </property> + </item> + </widget> + </item> + <item row="2" column="2"> + <widget class="QLabel" name="label_3"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Use Intensity as</string> + </property> + </widget> + </item> + <item row="2" column="3"> + <widget class="QComboBox" name="comboBoxUseIntensity"> + <item> + <property name="text"> + <string>Material</string> + </property> + </item> + <item> + <property name="text"> + <string>Evelation</string> + </property> + </item> + </widget> + </item> + <item row="1" column="0"> + <widget class="QRadioButton" name="radioMesh"> + <property name="text"> + <string>Mesh</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QRadioButton" name="radioImage"> + <property name="text"> + <string>Raster</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>50</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>50</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="4"> + <spacer name="horizontalSpacer_7"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="4"> + <spacer name="horizontalSpacer_10"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>NetCdfConfigure</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>NetCdfConfigure</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/DataView/NetCdfConfigureDialog.cpp b/DataView/NetCdfConfigureDialog.cpp new file mode 100644 index 00000000000..1ba643d1c63 --- /dev/null +++ b/DataView/NetCdfConfigureDialog.cpp @@ -0,0 +1,448 @@ +//file NetCDFConfigureDialog.cpp +//CH Initial implementation + +#include "NetCdfConfigureDialog.h" + +#include "VtkMeshConverter.h" +#include "GridAdapter.h" +#include "VtkGeoImageSource.h" +#include "VtkRaster.h" + +#include <QMessageBox> +#include <QSettings> + +#include <vtkImageImport.h> + +// Constructor +NetCdfConfigureDialog::NetCdfConfigureDialog(const std::string &fileName, QDialog* parent) + : QDialog(parent), _currentFile(new NcFile(fileName.c_str(), NcFile::ReadOnly)), + _currentInitialDateTime(QDateTime()), _currentMesh(NULL), _currentRaster(NULL), _currentPath(fileName) +{ + setupUi(this); + + setVariableSelect(); // set up variables of the file in the combobox + comboBoxVariable->setCurrentIndex(valueWithMaxDim()); //pre-select the variable with the biggest number of dimensions...valueWithMaxDim() + + _currentVar = _currentFile->get_var(comboBoxVariable->currentIndex()); + + setDimensionSelect(); + + lineEditName->setText(setName()); + + this->radioMesh->setChecked(true); + +} + +NetCdfConfigureDialog::~NetCdfConfigureDialog() +{ +} + +// Instructions if the OK-Button has been pressed. +void NetCdfConfigureDialog::accept() +{ + QMessageBox valueErrorBox; + if (_currentVar->num_dims() < 3){ + valueErrorBox.setText("Selected Variable has not enough dimensions."); + valueErrorBox.exec(); + }else if (doubleSpinBoxDim2Start->value() == doubleSpinBoxDim2Start->maximum()){ + valueErrorBox.setText("Lon has invalid extend."); + valueErrorBox.exec(); + }else if(doubleSpinBoxDim1Start->value() == doubleSpinBoxDim1Start->maximum()){ + valueErrorBox.setText("Lat has invalid extend."); + valueErrorBox.exec(); + }else{ + createDataObject(); + delete _currentFile; + this->done(QDialog::Accepted); + } +} + +// Instructions if the Cancel-Button has been pressed. +void NetCdfConfigureDialog::reject() +{ + delete _currentFile; + this->done(QDialog::Rejected); +} + +int NetCdfConfigureDialog::valueWithMaxDim() +{ + int idMaxDim = 0; + for (int i=0; i < _currentFile->num_dims(); i++) + { + if ((_currentFile->get_var(i)->num_dims()) > 0) idMaxDim = i + 1; + } + return idMaxDim; +} + +void NetCdfConfigureDialog::on_comboBoxVariable_currentIndexChanged(int id) +{ + _currentVar = _currentFile->get_var(id); + setDimensionSelect(); +} + +//set up x-axis/lat +void NetCdfConfigureDialog::on_comboBoxDim1_currentIndexChanged(int id) +{ + if (id == -1) id = 0; + double firstValue=0, lastValue=0; + size_t size = 0; + getDimEdges(id,size,firstValue,lastValue); + doubleSpinBoxDim1Start->setValue(firstValue); + doubleSpinBoxDim1End->setValue(lastValue); + doubleSpinBoxResolution->setValue(getResolution()); +} + +//set up y-axis/lon +void NetCdfConfigureDialog::on_comboBoxDim2_currentIndexChanged(int id) +{ + if (_currentVar->num_dims() > 1) + { + if (id == -1) id = 0; + double firstValue=0, lastValue=0; + size_t size = 0; + getDimEdges(id,size,firstValue,lastValue); + doubleSpinBoxDim2Start->setValue(firstValue); + doubleSpinBoxDim2End->setValue(lastValue); + } +} + +//set up time +void NetCdfConfigureDialog::on_comboBoxDim3_currentIndexChanged(int id) +{ + if (_currentVar->num_dims() > 2) + { + if (id == -1) id = 0; + double firstValue=0, lastValue=0; + size_t size = 0; + getDimEdges(id,size,firstValue,lastValue); + + QTime firstTime(0,0,0), lastTime(0,0,0); + int firstDaysToAdd = 0, lastDaysToAdd = 0; + + getDaysTime(firstValue,firstTime,firstDaysToAdd); + getDaysTime(lastValue,lastTime,lastDaysToAdd); + + QDate initialDate(1960,1,1); + QTime initialTime(0,0); + + QDateTime initialDateTime; + initialDateTime.setDate(initialDate); + initialDateTime.setTime(initialTime); + + QDateTime firstDateTime = initialDateTime.addDays(firstDaysToAdd); + firstDateTime.setTime(firstTime); + + QDateTime lastDateTime = initialDateTime.addDays(lastDaysToAdd); + lastDateTime.setTime(lastTime); + + dateTimeEditDim3->setDateTime(firstDateTime); + dateTimeEditDim3->setMinimumDateTime(firstDateTime); + dateTimeEditDim3->setMaximumDateTime(lastDateTime); + + _currentInitialDateTime = initialDateTime; + lineEditName->setText(setName()); + } +} + +//set up additional dimension +void NetCdfConfigureDialog::on_comboBoxDim4_currentIndexChanged(int id) +{ + if (_currentVar->num_dims() > 3) + { + if (id == -1) id = 0; + double firstValue=0, lastValue=0; + size_t size = 0; + getDimEdges(id,size,firstValue,lastValue); + spinBoxDim4->setValue(firstValue); + spinBoxDim4->setMinimum(firstValue); + spinBoxDim4->setMaximum(lastValue); + } +} + +void NetCdfConfigureDialog::setVariableSelect() +{ + for (int i=0; i<(_currentFile->num_vars()); i++) + { + NcVar *focusedVar = _currentFile->get_var(i); + if (focusedVar->num_dims() > 0) comboBoxVariable->addItem(focusedVar->name()); + } +} + +void NetCdfConfigureDialog::setDimensionSelect() +{ + comboBoxDim1->clear(); + comboBoxDim2->clear(); + comboBoxDim3->clear(); + comboBoxDim4->clear(); + for (int i=0; i < _currentVar->num_dims(); i++) //write dimension-names into selection-boxes + { + comboBoxDim1->addItem(_currentVar->get_dim(i)->name()); + comboBoxDim2->addItem(_currentVar->get_dim(i)->name()); + comboBoxDim3->addItem(_currentVar->get_dim(i)->name()); + comboBoxDim4->addItem(_currentVar->get_dim(i)->name()); + } + if (_currentVar->num_dims() < 4) + { + comboBoxDim4->setEnabled(false);comboBoxDim4->clear(); + spinBoxDim4->setEnabled(false);spinBoxDim4->setValue(0); + }else{ //pre-set dimension selection, typical for 4-d-nc-files: + comboBoxDim4->setEnabled(true); + spinBoxDim4->setEnabled(true); + comboBoxDim1->setCurrentIndex(2);on_comboBoxDim1_currentIndexChanged(2); + comboBoxDim2->setCurrentIndex(3);on_comboBoxDim2_currentIndexChanged(3); + comboBoxDim3->setCurrentIndex(0);on_comboBoxDim3_currentIndexChanged(0); + comboBoxDim4->setCurrentIndex(1);on_comboBoxDim4_currentIndexChanged(1); + } + if (_currentVar->num_dims() == 3) //pre-set dimension selection, typical for 3-d-nc-files: + { + comboBoxDim1->setCurrentIndex(1);on_comboBoxDim1_currentIndexChanged(1); + comboBoxDim2->setCurrentIndex(2);on_comboBoxDim2_currentIndexChanged(2); + comboBoxDim3->setCurrentIndex(0);on_comboBoxDim3_currentIndexChanged(0); + } + if (_currentVar->num_dims() < 3) + { + comboBoxDim3->setEnabled(false);comboBoxDim3->clear(); + dateTimeEditDim3->setEnabled(false);dateTimeEditDim3->setDateTime(_currentInitialDateTime); + + }else{ + comboBoxDim3->setEnabled(true); + dateTimeEditDim3->setEnabled(true); + } + if (_currentVar->num_dims() < 2) + { + comboBoxDim2->setEnabled(false);comboBoxDim2->clear(); + doubleSpinBoxDim2Start->setValue(0); doubleSpinBoxDim2End->setValue(0); + }else{ + comboBoxDim2->setEnabled(true); + } + +} + +void NetCdfConfigureDialog::getDimEdges(int dimId, size_t &size, double &firstValue, double &lastValue) +{ + if ((_currentFile->get_var(_currentVar->get_dim(dimId)->name())) != NULL) + { + NcVar *tmpVarOfDim = _currentFile->get_var(_currentVar->get_dim(dimId)->name()); + if ((tmpVarOfDim->num_dims()) == 1) + { + int sizeOfDim = tmpVarOfDim->get_dim(0)->size(); + size = sizeOfDim; + double arrayOfDimStart[1] = {0}; + size_t edgeOfArray[1] = {1}; + long edgeOrigin[1] = {0}; + tmpVarOfDim->set_cur(edgeOrigin); + tmpVarOfDim->get(arrayOfDimStart,edgeOfArray); + firstValue = arrayOfDimStart[0]; + double arrayOfDimEnd[1] = {0}; + edgeOrigin[0] = sizeOfDim - 1; + tmpVarOfDim->set_cur(edgeOrigin); + tmpVarOfDim->get(arrayOfDimEnd,edgeOfArray); + lastValue = arrayOfDimEnd[0]; + } + }else{ + size = 0; + firstValue = 0; + lastValue = 0; + } +} + +void NetCdfConfigureDialog::getDaysTime(double minSince, QTime &time, int &days) +{ + long tmpMin = (long) minSince; + long minuits = tmpMin % 60; + long tmpHours = tmpMin / 60; + long hours = tmpHours % 24; + days = (int) (tmpHours / 24); + time.setHMS(hours,minuits,0); +} + +long NetCdfConfigureDialog::convertDateToMinutes(QDateTime initialDateTime, QDate selectedDate, QTime selectedTime) +{ + int tmpInitialToSelectedDate = (selectedDate.daysTo(initialDateTime.date())); + long selectedDays = - tmpInitialToSelectedDate * 24 * 60; + long selectedMinutes = (selectedTime.hour() * 60) + selectedTime.minute() + selectedDays; + return selectedMinutes; +} + +int NetCdfConfigureDialog::getTimeStep() +{ + NcVar* timeVar = _currentFile->get_var(comboBoxDim2->currentIndex()); + + int datesToMinutes = convertDateToMinutes(_currentInitialDateTime,dateTimeEditDim3->date(),dateTimeEditDim3->time()); + + double timeArray[1] = {datesToMinutes}; + double currentTime = timeVar->get_index(timeArray); + if (currentTime < 0) currentTime=0; //if the value isn't found in the array, set it to 0 as default... + return currentTime; +} + +int NetCdfConfigureDialog::getDim4() +{ + NcVar* dim3Var = _currentFile->get_var(comboBoxDim4->currentIndex()); + double timeArray[1] = {spinBoxDim4->value()}; + double currentValueDim3 = dim3Var->get_index(timeArray); + if (currentValueDim3 < 0) currentValueDim3=0; //if the value isn't found in the array, set it to 0 as default... + return currentValueDim3; +} + +double NetCdfConfigureDialog::getResolution() +{ + if (comboBoxDim1->currentIndex() > -1) + { + NcVar *latVar = _currentFile->get_var(comboBoxDim1->currentIndex()); + double firstValue=0, lastValue=0; + size_t size=0; + getDimEdges(latVar->id(),size,firstValue,lastValue); + if (size < 2) + { + return 1; + } + else + { + double interval = fabs(lastValue-firstValue); + double resolution = (double)interval/(size-1); + return resolution; + } + } + else + { + return 0; + } +} + +void NetCdfConfigureDialog::createDataObject() +{ + size_t* length = new size_t[_currentVar->num_dims()]; + double originLon = 0, originLat = 0; + double lastLon = 0, lastLat = 0; + size_t sizeLon = 0, sizeLat = 0; + getDimEdges(comboBoxDim1->currentIndex(), sizeLat, originLat, lastLat); + getDimEdges(comboBoxDim2->currentIndex(), sizeLon, originLon, lastLon); + + for(int i=0; i < _currentVar->num_dims(); i++) length[i]=1; + + // set array edges: lat x lon + length[comboBoxDim1->currentIndex()]=sizeLat; + length[comboBoxDim2->currentIndex()]=sizeLon; + + // set up array + double* data_array = new double[sizeLat*sizeLon]; + for(size_t i=0; i < (sizeLat*sizeLon); i++) data_array[i]=0; + + //Time-Dimension: + if (_currentVar->num_dims() > 2) + { + long* newOrigin = new long[_currentVar->num_dims()]; + for (int i=0; i < _currentVar->num_dims(); i++) newOrigin[i]=0; + newOrigin[comboBoxDim3->currentIndex()] = getTimeStep(); //set origin to selected time + _currentVar->set_cur(newOrigin); + //Dimension 4: + if (_currentVar->num_dims() > 3) newOrigin[comboBoxDim4->currentIndex()] = getDim4(); //if there are is a 4th dimension + delete newOrigin; + } + + _currentVar->get(data_array,length); //create Array of Values + + for (size_t i=0; i < (sizeLat*sizeLon); i++) + { + //data_array[i] = data_array[i] - 273; // convert from kalvin to celsius + if (data_array[i] < -9999 ) data_array[i] = -9999; // all values < -10000, set to "no-value" + } + + double origin_x = (originLon < lastLon) ? originLon : lastLon; + double origin_y = (originLat < lastLat) ? originLat : lastLat; + double originNetCdf[3] = {origin_x, origin_y, 0}; + + double resolution = (doubleSpinBoxResolution->value()); + + if (originLat > lastLat) // reverse lines in vertical direction if the original file has its origin in the northwest corner + this->reverseNorthSouth(data_array, sizeLon, sizeLat); + + if (this->radioMesh->isChecked()) + { + MshElemType::type meshElemType = MshElemType::QUAD; + UseIntensityAs::type useIntensity = UseIntensityAs::MATERIAL; + if ((comboBoxMeshElemType->currentIndex()) == 1) + { + meshElemType = MshElemType::TRIANGLE; + }else{ + meshElemType = MshElemType::QUAD; + } + if ((comboBoxUseIntensity->currentIndex()) == 1) + { + useIntensity = UseIntensityAs::ELEVATION; + }else{ + useIntensity = UseIntensityAs::MATERIAL; + } + + _currentMesh = VtkMeshConverter::convertImgToMesh(data_array,originNetCdf,sizeLon,sizeLat,resolution,meshElemType,useIntensity); + } + else + { + vtkImageImport* image = VtkRaster::loadImageFromArray(data_array, originNetCdf[0], originNetCdf[1], sizeLon, sizeLat, resolution, -9999.0); + _currentRaster = VtkGeoImageSource::New(); + _currentRaster->setImage(image, QString::fromStdString(this->getName()), originNetCdf[0], originNetCdf[1], resolution); + } + + delete[] length; + delete[] data_array; +} + +QString NetCdfConfigureDialog::setName() +{ + std::string name; + name.append(_currentPath); + name.erase(0,name.find_last_of("/")+1); + name.erase(name.find_last_of(".")); + QString qstr = QString::fromStdString(name); + return qstr; +} + +std::string NetCdfConfigureDialog::getName() +{ + std::string name = (lineEditName->text()).toStdString(); + QString date = dateTimeEditDim3->date().toString(Qt::LocalDate); + name.append(" - ").append(date.toStdString()); + return name; +} + +void NetCdfConfigureDialog::reverseNorthSouth(double* data, size_t width, size_t height) +{ + double* cp_array = new double[width*height]; + + for (size_t i=0; i<height; i++) + { + for (size_t j=0; j<width; j++) + { + size_t old_index((width*height)-(width*(i+1))); + size_t new_index(width*i); + cp_array[new_index+j] = data[old_index+j]; + } + } + + size_t length(height*width); + for (size_t i=0; i<length; i++) + data[i] = cp_array[i]; + + delete[] cp_array; +} + +void NetCdfConfigureDialog::on_radioMesh_toggled(bool isTrue) +{ + if (isTrue) // output set to "mesh" + { + this->label_2->setEnabled(true); + this->label_3->setEnabled(true); + this->comboBoxMeshElemType->setEnabled(true); + this->comboBoxUseIntensity->setEnabled(true); + } + else // output set to "raster" + { + this->label_2->setEnabled(false); + this->label_3->setEnabled(false); + this->comboBoxMeshElemType->setEnabled(false); + this->comboBoxUseIntensity->setEnabled(false); + } +} + + diff --git a/DataView/NetCdfConfigureDialog.h b/DataView/NetCdfConfigureDialog.h new file mode 100644 index 00000000000..debce10ad6e --- /dev/null +++ b/DataView/NetCdfConfigureDialog.h @@ -0,0 +1,58 @@ +//file NetCDFConfigureDialog.cpp +//CH Initial implementation + +#ifndef NETCDFCONFIGUREDIALOG_H +#define NETCDFCONFIGUREDIALOG_H + +#include <vtknetcdf/netcdfcpp.h> +#include <QDialog> +#include "ui_NetCdfConfigure.h" + +class GridAdapter; +class VtkGeoImageSource; + +class NetCdfConfigureDialog : public QDialog, private Ui_NetCdfConfigure +{ + Q_OBJECT + +public: + NetCdfConfigureDialog(const std::string &fileName, QDialog* parent = 0); + ~NetCdfConfigureDialog(void); + GridAdapter* getMesh() { return _currentMesh; }; + std::string getName(); + VtkGeoImageSource* getRaster() { return _currentRaster; }; + +private slots: + void accept(); + void reject(); + void on_comboBoxVariable_currentIndexChanged(int id); + void on_comboBoxDim1_currentIndexChanged(int id); + void on_comboBoxDim2_currentIndexChanged(int id); + void on_comboBoxDim3_currentIndexChanged(int id); + void on_comboBoxDim4_currentIndexChanged(int id); + void on_radioMesh_toggled(bool isTrue); + +private: + void setVariableSelect(); + void setDimensionSelect(); + void getDimEdges(int dimId,size_t &size, double &firstValue, double &lastValue); + void getDaysTime(double minSince, QTime &time, int &days); + long convertDateToMinutes(QDateTime initialDateTime,QDate selectedDate, QTime selectedTime); + void createDataObject(); + int valueWithMaxDim(); + int getTimeStep(); + int getDim4(); + double getResolution(); + QString setName(); + void reverseNorthSouth(double* data, size_t width, size_t height); + + NcFile *_currentFile; + NcVar *_currentVar; + QDateTime _currentInitialDateTime; + GridAdapter* _currentMesh; + VtkGeoImageSource* _currentRaster; + std::string _currentPath; +}; + +#endif //NETCDFCONFIGUREDIALOG_H + diff --git a/DataView/OGSRaster.cpp b/DataView/OGSRaster.cpp deleted file mode 100644 index b5727f52c59..00000000000 --- a/DataView/OGSRaster.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/** - * \file OGSRaster.cpp - * 11/01/2010 KR Initial implementation - */ - -#include <cmath> -#include <iomanip> -#include <iostream> -#include <sstream> - -#include <QFileInfo> -#include <QImage> -#include <QPointF> - -#include "OGSError.h" -#include "OGSRaster.h" -#include "StringTools.h" - -#ifdef libgeotiff_FOUND -#include "geo_tiffp.h" -#include "xtiffio.h" -#endif - -bool OGSRaster::loadImage(const QString &fileName, QImage &raster, QPointF &origin, - double &scalingFactor, bool autoscale /* = true */, bool mirrorX /* = false */) -{ - QFileInfo fileInfo(fileName); - origin.setX(0); - origin.setY(0); - scalingFactor = 1; - - if (fileInfo.suffix().toLower() == "asc") - { - if (!loadImageFromASC(fileName, raster, origin, scalingFactor, autoscale)) - return false; - if (mirrorX) - raster = raster.transformed(QTransform(1, 0, 0, -1, 0, 0), Qt::FastTransformation); - } -#ifdef libgeotiff_FOUND - else if (fileInfo.suffix().toLower() == "tif") - { - if (!loadImageFromTIFF(fileName, raster, origin, scalingFactor)) - return false; - if (!mirrorX) - raster = raster.transformed(QTransform(1, 0, 0, -1, 0, 0), Qt::FastTransformation); - } -#endif - else if (!loadImageFromFile(fileName, raster)) - return false; - return true; -} - -bool OGSRaster::loadImageFromASC(const QString &fileName, - QImage &raster, - QPointF &origin, - double &cellsize, - bool autoscale) -{ - std::ifstream in( fileName.toStdString().c_str() ); - - if (!in.is_open()) - { - std::cout << "OGSRaster::loadImageFromASC() - Could not open file..." << std::endl; - return false; - } - - ascHeader header; - - if (readASCHeader(header, in)) - { - int index = 0, gVal; - double value, minVal = 65536, maxVal = 0; - double* pixVal (new double[header.ncols * header.nrows]); - QImage img(header.ncols, header.nrows, QImage::Format_ARGB32); - - std::string s; - // read the file into a double-array - for (int j = 0; j < header.nrows; j++) - { - index = j * header.ncols; - for (int i = 0; i < header.ncols; i++) - { - in >> s; - pixVal[index + i] = strtod(replaceString(",", ".", s).c_str(),0); - if (pixVal[index + i] != header.noData) - { // find intensity bounds but ignore noData values - minVal = (pixVal[index + i] < minVal) ? pixVal[index + i] : minVal; - maxVal = (pixVal[index + i] > maxVal) ? pixVal[index + i] : maxVal; - } - } - } - in.close(); - - // calculate scaling factor for contrast stretching - double scalingFactor = 255.0 / (maxVal - minVal); - - // write re-calculated image intensities to QImage - // the formula used for contrast adjustment is p_new = (value - minval) * (g_max-g_min)/(maxval-minval) - for (int j = 0; j < header.nrows; j++) - { - index = j * header.ncols; - for (int i = 0; i < header.ncols; i++) - { // scale intensities and set nodata values to zero (black) - if (pixVal[index + i] != header.noData) - { - value = pixVal[index + i]; - gVal = (autoscale) ? - static_cast<int> (floor((value -minVal) * scalingFactor)) : static_cast<int> (value); - //gVal = value; // saudi arabia - img.setPixel(i,j, qRgba(gVal, gVal, gVal, 255)); - } - else - img.setPixel(i,j, qRgba(0, 0, 0, 0)); - } - } - - delete [] pixVal; - origin.setX(header.x); - origin.setY(header.y); - cellsize = header.cellsize; - raster = img; - return true; - } - OGSError::box("Error reading file header."); - return false; -} - -bool OGSRaster::readASCHeader(ascHeader &header, std::ifstream &in) -{ - std::string line, tag, value; - - in >> tag; - if (tag.compare("ncols") == 0) - { - in >> value; - header.ncols = atoi(value.c_str()); - } - else - return false; - in >> tag; - if (tag.compare("nrows") == 0) - { - in >> value; - header.nrows = atoi(value.c_str()); - } - else - return false; - in >> tag; - if (tag.compare("xllcorner") == 0) - { - in >> value; - header.x = strtod(replaceString(",", ".", value).c_str(),0); - } - else - return false; - in >> tag; - if (tag.compare("yllcorner") == 0) - { - in >> value; - header.y = strtod(replaceString(",", ".", value).c_str(),0); - } - else - return false; - in >> tag; - if (tag.compare("cellsize") == 0) - { - in >> value; - header.cellsize = strtod(replaceString(",", ".", value).c_str(),0); - } - else - return false; - in >> tag; - if (tag.compare("NODATA_value") == 0) - { - in >> value; - header.noData = atoi(value.c_str()); - } - else - return false; - - // correct raster position by half a pixel for correct visualisation - // argh! wrong! correction has to happen in visualisation object, otherwise the actual data is wrong - //header.x = header.x + (header.cellsize / 2); - //header.y = header.y + (header.cellsize / 2); - - return true; -} - -double* OGSRaster::loadDataFromASC(const QString &fileName, - double &x0, - double &y0, - size_t &width, - size_t &height, - double &delta) -{ - std::ifstream in( fileName.toStdString().c_str() ); - - if (!in.is_open()) - { - std::cout << "OGSRaster::loadImageFromASC() - Could not open file..." << std::endl; - return NULL; - } - - ascHeader header; - - if (readASCHeader(header, in)) - { - x0 = header.x; - y0 = header.y; - width = header.ncols; - height = header.nrows; - delta = header.cellsize; - - double* values = new double[header.ncols * header.nrows]; - - int index(0); - std::string s(""); - // read the file into a double-array - for (int j = 0; j < header.nrows; j++) - { - index = (header.nrows - j - 1) * header.ncols; - for (int i = 0; i < header.ncols; i++) - { - in >> s; - values[index + i] = strtod(replaceString(",", ".", s).c_str(),0); - } - } - - in.close(); - return values; - } - return NULL; -} - -#ifdef libgeotiff_FOUND -bool OGSRaster::loadImageFromTIFF(const QString &fileName, - QImage &raster, - QPointF &origin, - double &cellsize) -{ - TIFF* tiff = XTIFFOpen(fileName.toStdString().c_str(), "r"); - - if (tiff) - { - GTIF* geoTiff = GTIFNew(tiff); - - if (geoTiff) - { - int imgWidth = 0, imgHeight = 0, nImages = 0, pntCount = 0; - double* pnts = 0; - - // get actual number of images in the tiff file - do { - nImages++; - } while (TIFFReadDirectory(tiff)); - if (nImages > 1) - std::cout << "OGSRaster::loadImageFromTIFF() - File contains " << - nImages << " images. This method is not tested for this case." << - std::endl; - - // get image size - TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &imgWidth); - TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &imgHeight); - - // get cellsize - // Note: GeoTiff allows anisotropic pixels. This is not supported here and equilateral pixels are assumed. - if (TIFFGetField(tiff, GTIFF_PIXELSCALE, &pntCount, &pnts)) - { - if (pnts[0] != pnts[1]) - std::cout << - "OGSRaster::loadImageFromTIFF() - Warning: Original raster data has anisotrop pixel size!" - << std::endl; - cellsize = pnts[0]; - } - - // get upper left point / origin - if (TIFFGetField(tiff, GTIFF_TIEPOINTS, &pntCount, &pnts)) - { - origin.setX(pnts[3]); - origin.setY(pnts[4] - (imgHeight * cellsize)); // the origin should be the lower left corner of the img - } - - // read pixel values - uint32* pixVal = - (uint32*) _TIFFmalloc(imgWidth * imgHeight * sizeof (uint32)); - if ((imgWidth > 0) && (imgHeight > 0)) - if (!TIFFReadRGBAImage(tiff, imgWidth, imgHeight, pixVal, 0)) - { - std::cout << - "OGSRaster::loadImageFromTIFF() - Error reading GeoTIFF file." - << std::endl; - _TIFFfree(pixVal); - GTIFFree(geoTiff); - XTIFFClose(tiff); - return false; - } - - // read colormap if it exists - uint16* cmap_red = NULL, * cmap_green = NULL, * cmap_blue = NULL; - int colormap_used = TIFFGetField(tiff, - TIFFTAG_COLORMAP, - &cmap_red, - &cmap_green, - &cmap_blue); - - int lineindex = 0, idx = 0; - QImage img(imgWidth, imgHeight, QImage::Format_ARGB32); - - int* pxl (new int[4]); - for (int j = 0; j < imgHeight; j++) - { - lineindex = j * imgWidth; - for (int i = 0; i < imgWidth; i++) - { // scale intensities and set nodata values to white (i.e. the background colour) - idx = TIFFGetR(pixVal[lineindex + i]); - if (colormap_used) - img.setPixel(i,j, - qRgba(cmap_red[idx] >> 8, - cmap_green[idx] >> 8, - cmap_blue[idx] >> 8, 255)); - else - { - //img.setPixel(i,j, qRgba(TIFFGetB(pixVal[idx]), TIFFGetG(pixVal[idx]), TIFFGetR(pixVal[idx]), TIFFGetA(pixVal[idx]))); - uint32toRGBA(pixVal[lineindex + i], pxl); - img.setPixel(i,j, - qRgba(pxl[0], pxl[1], pxl[2], pxl[3])); - } - } - } - delete [] pxl; - - raster = img; - - _TIFFfree(pixVal); - GTIFFree(geoTiff); - XTIFFClose(tiff); - return true; - } - - XTIFFClose(tiff); - std::cout << - "OGSRaster::loadImageFromTIFF() - File not recognised as GeoTIFF-Image." << - std::endl; - return false; - } - - std::cout << "OGSRaster::loadImageFromTIFF() - File not recognised as TIFF-Image." << - std::endl; - return false; -} -#endif - -bool OGSRaster::loadImageFromFile(const QString &fileName, QImage &raster) -{ - return raster.load(fileName); -} - -void OGSRaster::convertToGreyscale(QImage &raster, const int &min, const int &max) -{ - int value = 0; - double scalingFactor = 255.0 / (max - min); - - for (int i = 0; i < raster.width(); i++) - for (int j = 0; j < raster.height(); j++) - { - QRgb pix = raster.pixel(i,j); - value = - static_cast<int>(floor(((0.3 * qRed(pix) + 0.6 * qGreen(pix) + - 0.1 * - qBlue(pix)) - min) * scalingFactor)); - raster.setPixel(i, j, qRgb(value, value, value)); - } -} - -int* OGSRaster::getGreyscaleData(QImage &raster, const int &min, const int &max) -{ - int index = 0; - double scalingFactor = 255.0 / (max - min); - int* pixVal (new int[raster.height() * raster.width()]); - - for (int j = 0; j < raster.height(); j++) - { - index = j * raster.width(); - for (int i = 0; i < raster.width(); i++) - { - QRgb pix = raster.pixel(i,j); - pixVal[index + - i] = - static_cast<int>(floor(((0.3 * qRed(pix) + 0.6 * qGreen(pix) + - 0.1 * - qBlue(pix)) - min) * scalingFactor)); - } - } - return pixVal; -} - -int OGSRaster::getMaxValue(const QImage &raster) -{ - int value, maxVal = 0; - for (int i = 0; i < raster.width(); i++) - for (int j = 0; j < raster.height(); j++) - { - value = qGreen(raster.pixel(i,j)); - maxVal = (value > maxVal) ? value : maxVal; - } - return maxVal; -} - -int OGSRaster::getMinValue(const QImage &raster) -{ - int value, minVal = 65536; - for (int i = 0; i < raster.width(); i++) - for (int j = 0; j < raster.height(); j++) - { - value = qGreen(raster.pixel(i,j)); - minVal = (value < minVal) ? value : minVal; - } - return minVal; -} - -void OGSRaster::uint32toRGBA(const unsigned int s, int* p) -{ - p[3] = s / (256 * 256 * 256); - int r = s % (256 * 256 * 256); - p[2] = r / (256 * 256); - r %= (256 * 256); - p[1] = r / 256; - p[0] = r % 256; -} diff --git a/DataView/OGSRaster.h b/DataView/OGSRaster.h deleted file mode 100644 index c1fc6092d7b..00000000000 --- a/DataView/OGSRaster.h +++ /dev/null @@ -1,134 +0,0 @@ -/** - * \file OGSRaster.h - * 11/01/2010 KR Initial implementation - * - */ -#ifndef OGSRASTER_H -#define OGSRASTER_H - -#include <fstream> - -class QImage; -class QPointF; -class QString; - -/** - * \brief Loading of raster data such as images or ArcGIS-data. - * - * The OGSRaster class enables loading of raster data such as images or ArcGIS-data. Supported image formats are specified - * by the Qt class QPixmap. Georeferenced data can be imported via the GeoTIFF- or asc-format . - */ -class OGSRaster -{ - /// Data structure for the asc-file header. - struct ascHeader - { - int ncols; - int nrows; - double x; - double y; - double cellsize; - int noData; - }; - -public: - /** - * \brief Loads an image- or raster-file into an QImage. - * - * Public method for loading all data formats. Internally the method automatically differentiates between - * images and georeferenced files and then calls the appropriate method for reading the file. - * \param fileName Filename of the file that should be loaded. - * \param raster The QImage into which the raster data will be written. - * \param origin The upper left corner of the data set, the default value is (0,0). - * \param scalingFactor The size of each pixel in the image which is needed for re-scaling the data, the default value is 1. - * \param autoscale Determines if the histogram of the raster will be contrast-stretched to [0, 255]. If false, the streching process will be skipped. - * \param mirrorX Mirror around x-axis. - * \return True if the raster data was loaded correctly, false otherwise. - */ - static bool loadImage(const QString &fileName, - QImage &raster, - QPointF &origin, - double &scalingFactor, - bool autoscale = true, - bool mirrorX = false); - - /** - * \brief Loads an ASC file into a double array - * - * \param fileName Filename of the file that should be loaded. - * \param x0 The x-coordinate of the origin. - * \param y0 The y-coordinate of the origin. - * \param width The width of the image. - * \param height The height of the image - * \param delta The size of each pixel in the image which is needed for re-scaling the data. - * \return True if the raster data was loaded correctly, false otherwise. - */ - static double* loadDataFromASC(const QString &fileName, - double& x0, - double &y0, - size_t &width, - size_t &height, - double &delta); - - /// Converts raster to an 8 bit greyscale image that is contrast-stretched in [min:max]. - static void convertToGreyscale(QImage &raster, const int &min = 0, const int &max = 255); - - /// Returns an int-array containing the raster converted an 8 bit greyscale values that are contrast-stretched in [min:max]. - static int* getGreyscaleData(QImage &raster, const int &min = 0, const int &max = 255); - - /// Returns the maximum intensity of raster. - static int getMaxValue(const QImage &raster); - - /// Returns the minimum intensity of raster. - static int getMinValue(const QImage &raster); - -private: - /** - * Loads ArcGIS asc-files to a QPixmap object and automatically does a contrast stretching to adjust values to 8 bit greyscale images. - * \param fileName Filename of the file that should be loaded. - * \param raster The QPixmap into which the raster data will be written. - * \param origin The upper left corner of the data set - * \param scalingFactor - * \param autoscale - * \return True if the raster data was loaded correctly, false otherwise. - */ - static bool loadImageFromASC(const QString &fileName, - QImage &raster, - QPointF &origin, - double &scalingFactor, - bool autoscale = true); - - /** - * Loads ArcGIS asc-files to a QPixmap object and automatically does a contrast stretching to adjust values to 8 bit greyscale images. - * \param fileName Filename of the file that should be loaded. - * \param raster The QPixmap into which the raster data will be written. - * \param origin The upper left corner of the data set - * \param scalingFactor - * \return True if the raster data was loaded correctly, false otherwise. - */ -#ifdef libgeotiff_FOUND - static bool loadImageFromTIFF(const QString &fileName, - QImage &raster, - QPointF &origin, - double &scalingFactor); -#endif - - /** - * Loads image files into a QPixmap object. Since images are not geo-referenced no origin point will be returned. - * \param fileName Filename of the file that should be loaded. - * \param raster The QPixmap into which the raster data will be written. - * \return True if the raster data was loaded correctly, false otherwise. - */ - static bool loadImageFromFile(const QString &fileName, QImage &raster); - - /** - * Reads the header of an ArcGIS asc-file. - * \param header The ascHeader-object into which all the information will be written. - * \param in FileInputStream used for reading the data. - * \return True if the header could be read correctly, false otherwise. - */ - static bool readASCHeader(ascHeader &header, std::ifstream &in); - static void uint32toRGBA(const unsigned int s, int* p); -}; - -#endif //OGSRASTER_H diff --git a/DataView/ProcessModel.cpp b/DataView/ProcessModel.cpp index 773164ca21c..806c6f7b179 100644 --- a/DataView/ProcessModel.cpp +++ b/DataView/ProcessModel.cpp @@ -48,57 +48,50 @@ void ProcessModel::addConditionItem(FEMCondition* c) CondObjectListItem* condParent = this->getCondParent(processParent, c->getCondType()); if (condParent == NULL) - condParent = this->createCondParent(processParent, c->getCondType(), c->getAssociatedGeometryName()); + condParent = this->createCondParent(processParent, c); + else + condParent->addCondition(c); - if (condParent) + QList<QVariant> condData; + condData << QString::fromStdString(c->getGeoName()) + << QString::fromStdString(c->getGeoTypeAsString()); + CondItem* condItem = new CondItem(condData, condParent, c); + condParent->appendChild(condItem); + // add information on primary variable + QList<QVariant> pvData; + pvData << QString::fromStdString(convertPrimaryVariableToString(c->getProcessPrimaryVariable())); + TreeItem* pvInfo = new TreeItem(pvData, condItem); + // add distribution information + QList<QVariant> disData; + disData << QString::fromStdString(convertDisTypeToString(c->getProcessDistributionType())); + std::vector<size_t> dis_nodes = c->getDisNodes(); + std::vector<double> dis_values = c->getDisValues(); + TreeItem* disInfo; + if (c->getProcessDistributionType() == FiniteElement::CONSTANT || + c->getProcessDistributionType() == FiniteElement::CONSTANT_NEUMANN) { - QList<QVariant> condData; - condData << QString::fromStdString(c->getGeoName()) - << QString::fromStdString(c->getGeoTypeAsString()); - CondItem* condItem = new CondItem(condData, condParent, c); - condParent->appendChild(condItem); - // add process information - //QList<QVariant> pcsData; - //pcsData << QString::fromStdString(convertProcessTypeToString(c->getProcessType())); - //TreeItem* pcsInfo = new TreeItem(pcsData, condItem); - // add information on primary variable - QList<QVariant> pvData; - pvData << QString::fromStdString(convertPrimaryVariableToString(c->getProcessPrimaryVariable())); - TreeItem* pvInfo = new TreeItem(pvData, condItem); - // add distribution information - QList<QVariant> disData; - disData << QString::fromStdString(convertDisTypeToString(c->getProcessDistributionType())); - std::vector<double> dis_value = c->getDisValue(); - TreeItem* disInfo; - if (c->getProcessDistributionType() == FiniteElement::CONSTANT || - c->getProcessDistributionType() == FiniteElement::CONSTANT_NEUMANN) - { - disData << dis_value[0]; - disInfo = new TreeItem(disData, condItem); - } - else + disData << dis_values[0]; + disInfo = new TreeItem(disData, condItem); + } + else + { + size_t nVals = dis_values.size(); + disData << static_cast<int>(nVals); + disInfo = new TreeItem(disData, condItem); + for (size_t i = 0; i < nVals; i++) { - size_t nVals = dis_value.size() / 2; - disData << static_cast<int>(nVals); - disInfo = new TreeItem(disData, condItem); - for (size_t i = 0; i < nVals; i++) - { - QList<QVariant> linData; - linData << dis_value[2 * i] << dis_value[2 * i + 1]; - TreeItem* linInfo = new TreeItem(linData, disInfo); - disInfo->appendChild(linInfo); - } + QList<QVariant> linData; + linData << static_cast<int>(dis_nodes[i]) << dis_values[i]; + TreeItem* linInfo = new TreeItem(linData, disInfo); + disInfo->appendChild(linInfo); } + } - //condItem->appendChild(pcsInfo); - condItem->appendChild(pvInfo); - condItem->appendChild(disInfo); + //condItem->appendChild(pcsInfo); + condItem->appendChild(pvInfo); + condItem->appendChild(disInfo); - condParent->addCondition(c); - reset(); - } - else - std::cout << "Error in ProcessModel::addConditionItem() - Parent object not found..." << std::endl; + reset(); } void ProcessModel::addCondition(FEMCondition* condition) @@ -237,19 +230,19 @@ CondObjectListItem* ProcessModel::getCondParent(TreeItem* parent, const FEMCondi return NULL; } -CondObjectListItem* ProcessModel::createCondParent(ProcessItem* parent, const FEMCondition::CondType cond_type, const std::string &geometry_name) +CondObjectListItem* ProcessModel::createCondParent(ProcessItem* parent, FEMCondition* cond) { - QString condType(QString::fromStdString(FEMCondition::condTypeToString(cond_type))); + QString condType(QString::fromStdString(FEMCondition::condTypeToString(cond->getCondType()))); QList<QVariant> condData; condData << condType << ""; - const std::vector<GEOLIB::Point*>* pnts = _project.getGEOObjects()->getPointVec(geometry_name); + const std::vector<GEOLIB::Point*>* pnts = _project.getGEOObjects()->getPointVec(cond->getAssociatedGeometryName()); if (pnts) { - CondObjectListItem* cond = new CondObjectListItem(condData, parent, cond_type, pnts); - parent->appendChild(cond); - emit conditionAdded(this, parent->getItem()->getProcessType(), cond_type); - return cond; + CondObjectListItem* cond_list = new CondObjectListItem(condData, parent, cond, pnts); + parent->appendChild(cond_list); + emit conditionAdded(this, parent->getItem()->getProcessType(), cond->getCondType()); + return cond_list; } return NULL; @@ -266,3 +259,11 @@ vtkPolyDataAlgorithm* ProcessModel::vtkSource(const FiniteElement::ProcessType p } return NULL; } + +void ProcessModel::replaceCondition(const QModelIndex &idx, FEMCondition* condition) +{ + // remove old condition + this->getItem(idx)->parentItem()->removeChildren(this->getItem(idx)->row(),1); + //add new condition + this->addCondition(condition); +} diff --git a/DataView/ProcessModel.h b/DataView/ProcessModel.h index 0970502eeae..ff445aaa286 100644 --- a/DataView/ProcessModel.h +++ b/DataView/ProcessModel.h @@ -56,6 +56,9 @@ public slots: /// Removes all processes from the model void removeAllProcesses(); + /// Remove the given TreeItem and replace it with another condition (this is used for editing FEMConditions) + void replaceCondition(const QModelIndex &idx, FEMCondition* condition); + private: /// Adds a new FEM condition to the condition tree model. void addConditionItem(FEMCondition* condition); @@ -64,7 +67,7 @@ private: //bool removeConditionItem(const QModelIndex &idx); /// Creates the TreeItem for one of the condition subtrees. - CondObjectListItem* createCondParent(ProcessItem* parent, const FEMCondition::CondType type, const std::string &geometry_name); + CondObjectListItem* createCondParent(ProcessItem* parent, FEMCondition* cond); /// Returns the subtree-item for a given type of condtion. CondObjectListItem* getCondParent(TreeItem* parent, const FEMCondition::CondType type) ; diff --git a/DataView/ProcessView.cpp b/DataView/ProcessView.cpp index d71ef1beab4..c4e40d69fcd 100644 --- a/DataView/ProcessView.cpp +++ b/DataView/ProcessView.cpp @@ -8,9 +8,11 @@ #include "ProcessItem.h" #include "CondObjectListItem.h" +#include "CondItem.h" #include "ProcessModel.h" #include "ProcessView.h" - +#include "FEMConditionSetupDialog.h" +#include "SelectMeshDialog.h" ProcessView::ProcessView(QWidget* parent) : QTreeView(parent) { @@ -40,28 +42,28 @@ void ProcessView::contextMenuEvent( QContextMenuEvent* event ) { Q_UNUSED(event); - ProcessItem* pcs_item = dynamic_cast<ProcessItem*>(static_cast<ProcessModel*>(this->model())-> - getItem(this->selectionModel()->currentIndex())); - CondObjectListItem* cond_item = - dynamic_cast<CondObjectListItem*>(static_cast<ProcessModel*>(this->model())-> - getItem(this->selectionModel()->currentIndex())); + const QModelIndex idx(this->selectionModel()->currentIndex()); + QMenu menu; - if (pcs_item || cond_item) + if (this->isProcessItem(idx)) + { + QAction* saveCondAction = menu.addAction("Save FEM Conditions..."); + QAction* removePCSAction = menu.addAction("Remove process"); + connect(saveCondAction, SIGNAL(triggered()), this, SLOT(saveConditions())); + connect(removePCSAction, SIGNAL(triggered()), this, SLOT(removeProcess())); + } + else if (this->isListItem(idx)) { - QMenu menu; - if (cond_item) - { - QAction* removeCondAction = menu.addAction("Remove conditions"); - connect(removeCondAction, SIGNAL(triggered()), this, SLOT(removeCondition())); - } - - if (pcs_item) - { - QAction* removePCSAction = menu.addAction("Remove process"); - connect(removePCSAction, SIGNAL(triggered()), this, SLOT(removeProcess())); - } - menu.exec(event->globalPos()); + QAction* removeCondAction = menu.addAction("Remove conditions"); + connect(removeCondAction, SIGNAL(triggered()), this, SLOT(removeCondition())); } + else if (this->isConditionItem(idx)) + { + QAction* editCondAction = menu.addAction("Edit condition"); + connect(editCondAction, SIGNAL(triggered()), this, SLOT(editCondition())); + } + + menu.exec(event->globalPos()); } void ProcessView::removeCondition() @@ -76,6 +78,29 @@ void ProcessView::removeCondition() } } +void ProcessView::editCondition() +{ + CondItem* item = dynamic_cast<CondItem*>(static_cast<ProcessModel*>(this->model())->getItem(this->selectionModel()->currentIndex())); + + if (item) + { + FEMConditionSetupDialog dlg(*(item->getItem())); + connect(&dlg, SIGNAL(createFEMCondition(std::vector<FEMCondition*>)), this, SLOT(replaceCondition(std::vector<FEMCondition*>))); + dlg.exec(); + } +} + +void ProcessView::replaceCondition(std::vector<FEMCondition*> conditions) +{ + static_cast<ProcessModel*>(this->model())->replaceCondition(this->selectionModel()->currentIndex(), conditions[0]); + this->reset(); +} + +void ProcessView::saveConditions() +{ + emit saveConditionsRequested(); +} + void ProcessView::removeProcess() { ProcessItem* item = dynamic_cast<ProcessItem*>(static_cast<ProcessModel*>(this->model())->getItem(this->selectionModel()->currentIndex())); @@ -86,3 +111,24 @@ void ProcessView::removeProcess() emit processRemoved(pcs_type); } } + +bool ProcessView::isProcessItem(const QModelIndex &idx) const +{ + ProcessItem* pcs_item = dynamic_cast<ProcessItem*>(static_cast<ProcessModel*>(this->model())->getItem(idx)); + if (pcs_item) return true; + return false; +} + +bool ProcessView::isListItem(const QModelIndex &idx) const +{ + CondObjectListItem* cond_item = dynamic_cast<CondObjectListItem*>(static_cast<ProcessModel*>(this->model())->getItem(idx)); + if (cond_item) return true; + return false; +} + +bool ProcessView::isConditionItem(const QModelIndex &idx) const +{ + CondObjectListItem* cond_item = dynamic_cast<CondObjectListItem*>(static_cast<ProcessModel*>(this->model())->getItem(idx.parent())); + if (cond_item) return true; + return false; +} \ No newline at end of file diff --git a/DataView/ProcessView.h b/DataView/ProcessView.h index d868fa21c75..ba378765217 100644 --- a/DataView/ProcessView.h +++ b/DataView/ProcessView.h @@ -36,16 +36,24 @@ protected slots: private: /// Actions to be taken after a right mouse click is performed in the station view. void contextMenuEvent( QContextMenuEvent* e ); + bool isProcessItem(const QModelIndex &idx) const; + bool isListItem(const QModelIndex &idx) const; + bool isConditionItem(const QModelIndex &idx) const; private slots: void on_Clicked(QModelIndex idx); + void editCondition(); void removeCondition(); void removeProcess(); + void replaceCondition(std::vector<FEMCondition*> conditions); + void saveConditions(); signals: void conditionsRemoved(const FiniteElement::ProcessType, const std::string&, const FEMCondition::CondType); void itemSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); void processRemoved(const FiniteElement::ProcessType); + void saveConditionsRequested(); }; #endif //PROCESSVIEW_H + diff --git a/DataView/SHPImportDialog.cpp b/DataView/SHPImportDialog.cpp index fa62d79785a..2a5ea954c0c 100644 --- a/DataView/SHPImportDialog.cpp +++ b/DataView/SHPImportDialog.cpp @@ -112,7 +112,8 @@ void SHPImportDialog::setupDialog() void SHPImportDialog::accept() { - if (_listName->text().compare("") == 0) + QString list_name(_listName->text()); + if (list_name.compare("") == 0) { OGSError::box("Please insert a name for the data in this file."); return; @@ -122,20 +123,20 @@ void SHPImportDialog::accept() if (_fileType == 1 && _choice1->isChecked()) _shpInterface->readSHPFile(_filename, SHPInterface::POINT, - _listName->text().toStdString()); + list_name.toStdString()); if (_fileType == 1 && _choice2->isChecked()) _shpInterface->readSHPFile(_filename, SHPInterface::STATION, - _listName->text().toStdString()); + list_name.toStdString()); if (_fileType == 2 && _choice1->isChecked()) _shpInterface->readSHPFile(_filename, SHPInterface::POLYLINE, - _listName->text().toStdString()); + list_name.toStdString()); if (_fileType == 2 && _choice2->isChecked()) _shpInterface->readSHPFile(_filename, SHPInterface::POLYGON, - _listName->text().toStdString()); - emit shpLoaded(_listName->text()); + list_name.toStdString()); + emit shpLoaded(list_name); } this->done(QDialog::Accepted); } diff --git a/DataView/SelectMeshDialog.cpp b/DataView/SelectMeshDialog.cpp new file mode 100644 index 00000000000..7d80b9820d6 --- /dev/null +++ b/DataView/SelectMeshDialog.cpp @@ -0,0 +1,61 @@ +/** + * \file QComboBox.cpp + * 2012/04/20 KR Initial implementation + */ + +#include "SelectMeshDialog.h" +#include "GeoObject.h" + +#include <QDialogButtonBox> +#include <QLabel> +#include <QComboBox> +#include <QVBoxLayout> + +SelectMeshDialog::SelectMeshDialog(const GEOLIB::GeoObject* geo_object, const std::list<std::string> &msh_names, QDialog* parent) : + QDialog(parent), _geo_object(geo_object) +{ + setupDialog(msh_names); + show(); +} + +SelectMeshDialog::~SelectMeshDialog() +{ + delete _buttonBox; + delete _layout; + delete _msh_names; + delete _txt_label; +} + +void SelectMeshDialog::setupDialog(const std::list<std::string> &msh_names) +{ + _layout = new QVBoxLayout(this); + QString dialog_text("Select Mesh"); + _txt_label = new QLabel(this); + _txt_label->setText(dialog_text); + + + _msh_names = new QComboBox(); + for (std::list<std::string>::const_iterator it=msh_names.begin(); it != msh_names.end(); ++it) + _msh_names->addItem(QString::fromStdString(*it)); + + setWindowTitle("Select Mesh..."); + _layout->addWidget( _txt_label ); + _layout->addWidget( _msh_names ); + _buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(_buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + _layout->addWidget( _buttonBox ); + + setLayout(_layout); +} + +void SelectMeshDialog::accept() +{ + //emit requestNameChange(_parent_name, GEOLIB::convertGeoType(_object_type_name), _id, _new_name->text().toStdString()); + this->done(QDialog::Accepted); +} + +void SelectMeshDialog::reject() +{ + this->done(QDialog::Rejected); +} diff --git a/DataView/SelectMeshDialog.h b/DataView/SelectMeshDialog.h new file mode 100644 index 00000000000..a64cf195e6d --- /dev/null +++ b/DataView/SelectMeshDialog.h @@ -0,0 +1,57 @@ +/** + * \file SelectMeshDialog.h + * 2012/04/20 KR Initial implementation + */ + +#ifndef SELECTMESHDIALOG_H +#define SELECTMESHDIALOG_H + +#include <QDialog> + +namespace GEOLIB { + class GeoObject; +} + +class QDialogButtonBox; +class QLabel; +class QComboBox; +class QVBoxLayout; + +/** + * \brief Small dialog for setting a name for an object. + */ +class SelectMeshDialog : public QDialog +{ + Q_OBJECT + +public: + /// Constructor + SelectMeshDialog(const GEOLIB::GeoObject* geo_object, + const std::list<std::string> &msh_names, + QDialog* parent = 0); + ~SelectMeshDialog(); + + QDialogButtonBox* _buttonBox; /// The buttons used in this dialog. + +private: + /// Constructs a dialog window + void setupDialog(const std::list<std::string> &msh_names); + + QLabel* _txt_label; + QComboBox* _msh_names; + QVBoxLayout* _layout; + const GEOLIB::GeoObject* _geo_object; + + +private slots: + /// Instructions if the OK-Button has been pressed. + void accept(); + + /// Instructions if the Cancel-Button has been pressed. + void reject(); + +signals: + //void requestNameChange(const std::string&, const GEOLIB::GEOTYPE, size_t, std::string); +}; + +#endif //SELECTMESHDIALOG_H diff --git a/DataView/StationTreeView.cpp b/DataView/StationTreeView.cpp index 400765c85d4..376b76a67a7 100644 --- a/DataView/StationTreeView.cpp +++ b/DataView/StationTreeView.cpp @@ -62,6 +62,9 @@ void StationTreeView::contextMenuEvent( QContextMenuEvent* event ) QModelIndex index = this->selectionModel()->currentIndex(); ModelTreeItem* item = static_cast<ModelTreeItem*>(index.internalPointer()); + if (!item) // Otherwise sometimes it crashes when (unmotivated ;-) ) clicking in a treeview + return; + // The current index refers to a parent item (e.g. a listname) if (item->childCount() > 0) { diff --git a/DataView/StratView/CMakeLists.txt b/DataView/StratView/CMakeLists.txt index 4dfeb264fe0..52172483f51 100644 --- a/DataView/StratView/CMakeLists.txt +++ b/DataView/StratView/CMakeLists.txt @@ -32,13 +32,12 @@ qt4_wrap_cpp( MOC_SOURCES ${MOC_HEADERS} ) # Include the headers which are generated by uic and moc # and include additional header include_directories( - . + ${CMAKE_SOURCE_DIR}/Qt/DataView/StratView ${CMAKE_BINARY_DIR}/Qt/DataView/StratView - ../../../Base - ../../../GEO - ../../../MathLib - ../../Base - ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/Base + ${CMAKE_SOURCE_DIR}/GEO + ${CMAKE_SOURCE_DIR}/MathLib + ${CMAKE_SOURCE_DIR}/Qt/Base ) # Put moc files in a project folder diff --git a/DataView/ncvalues.h b/DataView/ncvalues.h new file mode 100644 index 00000000000..fbf7747c71c --- /dev/null +++ b/DataView/ncvalues.h @@ -0,0 +1,279 @@ +/********************************************************************* + * Copyright 1992, University Corporation for Atmospheric Research + * See netcdf/README file for copying and redistribution conditions. + * + * Purpose: interface for classes of typed arrays for netCDF + * + * $Header: /upc/share/CVS/netcdf-3/cxx/ncvalues.h,v 1.7 2006/07/26 21:12:06 russ Exp $ + *********************************************************************/ + +#ifndef Ncvalues_def +#define Ncvalues_def + +#include <iostream> +#include <sstream> +#include <limits.h> +#include <vtknetcdf/netcdf.h> + +// Documentation warned this might change and now it has, for +// consistency with C interface +typedef signed char ncbyte; + +#define NC_UNSPECIFIED ((nc_type)0) + +// C++ interface dates from before netcdf-3, still uses some netcdf-2 names +#ifdef NO_NETCDF_2 +#define NC_LONG NC_INT +#define FILL_LONG NC_FILL_INT +typedef int nclong; +#define NC_FATAL 1 +#define NC_VERBOSE 2 +#endif + +enum NcType +{ + ncNoType = NC_UNSPECIFIED, + ncByte = NC_BYTE, + ncChar = NC_CHAR, + ncShort = NC_SHORT, + ncInt = NC_INT, + ncLong = NC_LONG, // deprecated, someday want to use for 64-bit ints + ncFloat = NC_FLOAT, + ncDouble = NC_DOUBLE +}; + +#define ncBad_ncbyte ncBad_byte +static const ncbyte ncBad_byte = NC_FILL_BYTE; +static const char ncBad_char = NC_FILL_CHAR; +static const short ncBad_short = NC_FILL_SHORT; +static const nclong ncBad_nclong = FILL_LONG; // deprecated +static const int ncBad_int = NC_FILL_INT; +static const long ncBad_long = FILL_LONG; // deprecated +static const float ncBad_float = NC_FILL_FLOAT; +static const double ncBad_double = NC_FILL_DOUBLE; + +// macros to glue tokens together to form new names (used to be in generic.h) +#define name2(a,b) a ## b +#define declare(clas,t) name2(clas,declare)(t) +#define implement(clas,t) name2(clas,implement)(t) +// This is the same as the name2 macro, but we need to define our own +// version since rescanning something generated with the name2 macro +// won't necessarily cause name2 to be expanded again. +#define makename2(z, y) makename2_x(z, y) +#define makename2_x(z, y) z##y + +#define NcVal(TYPE) makename2(NcValues_,TYPE) + +#define NcValuesdeclare(TYPE) \ +class MSCPP_EXTRA NcVal(TYPE) : public NcValues \ +{ \ + public: \ + NcVal(TYPE)( void ); \ + NcVal(TYPE)(long Num); \ + NcVal(TYPE)(long Num, const TYPE* vals); \ + NcVal(TYPE)(const NcVal(TYPE)&); \ + virtual NcVal(TYPE)& operator=(const NcVal(TYPE)&); \ + virtual ~NcVal(TYPE)( void ); \ + virtual void* base( void ) const; \ + virtual int bytes_for_one( void ) const; \ + virtual ncbyte as_ncbyte( long n ) const; \ + virtual char as_char( long n ) const; \ + virtual short as_short( long n ) const; \ + virtual int as_int( long n ) const; \ + virtual int as_nclong( long n ) const; \ + virtual long as_long( long n ) const; \ + virtual float as_float( long n ) const; \ + virtual double as_double( long n ) const; \ + virtual char* as_string( long n ) const; \ + virtual int invalid( void ) const; \ + private: \ + TYPE* the_values; \ + std::ostream& print(std::ostream&) const; \ +}; + +#define NcTypeEnum(TYPE) makename2(_nc__,TYPE) +#define _nc__ncbyte ncByte +#define _nc__char ncChar +#define _nc__short ncShort +#define _nc__int ncInt +#define _nc__nclong ncLong +#define _nc__long ncLong +#define _nc__float ncFloat +#define _nc__double ncDouble +#define NcValuesimplement(TYPE) \ +NcVal(TYPE)::NcVal(TYPE)( void ) \ + : NcValues(NcTypeEnum(TYPE), 0), the_values(0) \ +{} \ + \ +NcVal(TYPE)::NcVal(TYPE)(long Num, const TYPE* vals) \ + : NcValues(NcTypeEnum(TYPE), Num) \ +{ \ + the_values = new TYPE[Num]; \ + for(int i = 0; i < Num; i++) \ + the_values[i] = vals[i]; \ +} \ + \ +NcVal(TYPE)::NcVal(TYPE)(long Num) \ + : NcValues(NcTypeEnum(TYPE), Num), the_values(new TYPE[Num]) \ +{} \ + \ +NcVal(TYPE)::NcVal(TYPE)(const NcVal(TYPE)& v) : \ + NcValues(v) \ +{ \ + delete[] the_values; \ + the_values = new TYPE[v.the_number]; \ + for(int i = 0; i < v.the_number; i++) \ + the_values[i] = v.the_values[i]; \ +} \ + \ +NcVal(TYPE)& NcVal(TYPE)::operator=(const NcVal(TYPE)& v) \ +{ \ + if ( &v != this) { \ + NcValues::operator=(v); \ + delete[] the_values; \ + the_values = new TYPE[v.the_number]; \ + for(int i = 0; i < v.the_number; i++) \ + the_values[i] = v.the_values[i]; \ + } \ + return *this; \ +} \ + \ +void* NcVal(TYPE)::base( void ) const \ +{ \ + return the_values; \ +} \ + \ +NcVal(TYPE)::~NcVal(TYPE)( void ) \ +{ \ + delete[] the_values; \ +} \ + \ +int NcVal(TYPE)::invalid( void ) const \ +{ \ + for(int i=0;i<the_number;i++) \ + if (the_values[i] == makename2(ncBad_,TYPE)) return 1; \ + return 0; \ +} \ + + +#define Ncbytes_for_one_implement(TYPE) \ +int NcVal(TYPE)::bytes_for_one( void ) const \ +{ \ + return sizeof(TYPE); \ +} + +#define as_ncbyte_implement(TYPE) \ +ncbyte NcVal(TYPE)::as_ncbyte( long n ) const \ +{ \ + if (the_values[n] < 0 || the_values[n] > UCHAR_MAX) \ + return ncBad_byte; \ + return (ncbyte) the_values[n]; \ +} + +#define as_char_implement(TYPE) \ +char NcVal(TYPE)::as_char( long n ) const \ +{ \ + if (the_values[n] < CHAR_MIN || the_values[n] > CHAR_MAX) \ + return ncBad_char; \ + return (char) the_values[n]; \ +} + +#define as_short_implement(TYPE) \ +short NcVal(TYPE)::as_short( long n ) const \ +{ \ + if (the_values[n] < SHRT_MIN || the_values[n] > SHRT_MAX) \ + return ncBad_short; \ + return (short) the_values[n]; \ +} + +#define NCINT_MIN INT_MIN +#define NCINT_MAX INT_MAX +#define as_int_implement(TYPE) \ +int NcVal(TYPE)::as_int( long n ) const \ +{ \ + if (the_values[n] < NCINT_MIN || the_values[n] > NCINT_MAX) \ + return ncBad_int; \ + return (int) the_values[n]; \ +} + +#define NCLONG_MIN INT_MIN +#define NCLONG_MAX INT_MAX +#define as_nclong_implement(TYPE) \ +nclong NcVal(TYPE)::as_nclong( long n ) const \ +{ \ + if (the_values[n] < NCLONG_MIN || the_values[n] > NCLONG_MAX) \ + return ncBad_nclong; \ + return (nclong) the_values[n]; \ +} + +#define as_long_implement(TYPE) \ +long NcVal(TYPE)::as_long( long n ) const \ +{ \ + if (the_values[n] < LONG_MIN || the_values[n] > LONG_MAX) \ + return ncBad_long; \ + return (long) the_values[n]; \ +} + +#define as_float_implement(TYPE) \ +inline float NcVal(TYPE)::as_float( long n ) const \ +{ \ + return (float) the_values[n]; \ +} + +#define as_double_implement(TYPE) \ +inline double NcVal(TYPE)::as_double( long n ) const \ +{ \ + return (double) the_values[n]; \ +} + +#define as_string_implement(TYPE) \ +char* NcVal(TYPE)::as_string( long n ) const \ +{ \ + char* s = new char[32]; \ + std::ostringstream ostr; \ + ostr << the_values[n]; \ + ostr.str().copy(s, std::string::npos); \ + s[ostr.str().length()] = 0; \ + return s; \ +} + +class MSCPP_EXTRA NcValues // ABC for value blocks +{ + public: + NcValues( void ); + NcValues(NcType, long); + virtual ~NcValues( void ); + virtual long num( void ); + virtual std::ostream& print(std::ostream&) const = 0; + virtual void* base( void ) const = 0; + virtual int bytes_for_one( void ) const = 0; + + // The following member functions provide conversions from the value + // type to a desired basic type. If the value is out of range, the + // default "fill-value" for the appropriate type is returned. + virtual ncbyte as_ncbyte( long n ) const = 0; // nth value as a byte + virtual char as_char( long n ) const = 0; // nth value as char + virtual short as_short( long n ) const = 0; // nth value as short + virtual int as_int( long n ) const = 0; // nth value as int + virtual int as_nclong( long n ) const = 0; // nth value as nclong + virtual long as_long( long n ) const = 0; // nth value as long + virtual float as_float( long n ) const = 0; // nth value as floating-point + virtual double as_double( long n ) const = 0; // nth value as double + virtual char* as_string( long n ) const = 0; // value as string + + protected: + NcType the_type; + long the_number; + friend std::ostream& operator<< (std::ostream&, const NcValues&); +}; + +declare(NcValues,ncbyte) +declare(NcValues,char) +declare(NcValues,short) +declare(NcValues,int) +declare(NcValues,nclong) +declare(NcValues,long) +declare(NcValues,float) +declare(NcValues,double) + +#endif \ No newline at end of file diff --git a/Gui/CMakeLists.txt b/Gui/CMakeLists.txt index 7c5479c8ad5..749b63b7b82 100644 --- a/Gui/CMakeLists.txt +++ b/Gui/CMakeLists.txt @@ -1,11 +1,17 @@ # Source files SET( SOURCES mainwindow.cpp + ${CMAKE_SOURCE_DIR}/UTL/FileConverter/OGSFileConverter/OGSFileConverter.cpp + ${CMAKE_SOURCE_DIR}/UTL/FileConverter/OGSFileConverter/FileListDialog.cpp + ${CMAKE_SOURCE_DIR}/UTL/FileConverter/OGSFileConverter/ConversionTools.cpp ) # Moc Header files SET( MOC_HEADERS mainwindow.h + ${CMAKE_SOURCE_DIR}/UTL/FileConverter/OGSFileConverter/OGSFileConverter.h + ${CMAKE_SOURCE_DIR}/UTL/FileConverter/OGSFileConverter/FileListDialog.h + ${CMAKE_SOURCE_DIR}/UTL/FileConverter/OGSFileConverter/ConversionTools.h ) # Header files @@ -16,6 +22,8 @@ SET( HEADERS # UI files SET( UIS mainwindow.ui + ${CMAKE_SOURCE_DIR}/UTL/FileConverter/OGSFileConverter/OGSFileConverter.ui + ${CMAKE_SOURCE_DIR}/UTL/FileConverter/OGSFileConverter/FileList.ui ) @@ -35,29 +43,26 @@ INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR}/Qt/DataView/DiagramView ${CMAKE_BINARY_DIR}/Qt/VtkVis ${CMAKE_BINARY_DIR}/Qt/VtkAct - ../../Base - ../../MathLib - ../../GEO - ../../FileIO - ../../MSH - ../../MSHGEOTOOLS - ../../FEM - ../Base - ../DataView - ../DataView/StratView - ../DataView/DiagramView - ../VtkVis - ../VtkAct + ${CMAKE_SOURCE_DIR}/Base + ${CMAKE_SOURCE_DIR}/MathLib + ${CMAKE_SOURCE_DIR}/GEO + ${CMAKE_SOURCE_DIR}/FileIO + ${CMAKE_SOURCE_DIR}/MSH + ${CMAKE_SOURCE_DIR}/MSHGEOTOOLS + ${CMAKE_SOURCE_DIR}/FEM + ${CMAKE_SOURCE_DIR}/Qt/Base + ${CMAKE_SOURCE_DIR}/Qt/DataView + ${CMAKE_SOURCE_DIR}/Qt/DataView/StratView + ${CMAKE_SOURCE_DIR}/Qt/DataView/DiagramView + ${CMAKE_SOURCE_DIR}/Qt/VtkVis + ${CMAKE_SOURCE_DIR}/Qt/VtkAct + ${CMAKE_SOURCE_DIR}/UTL/FileConverter/OGSFileConverter ) IF (Shapelib_FOUND) INCLUDE_DIRECTORIES( ${Shapelib_INCLUDE_DIR} ) ENDIF () # Shapelib_FOUND -if (OGS_COMPILE_QVTK) - INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/Qt/QVTK ../QVTK) -endif (OGS_COMPILE_QVTK) - # Put moc files in a project folder SOURCE_GROUP("UI Files" REGULAR_EXPRESSION "\\w*\\.ui") SOURCE_GROUP("Moc Files" REGULAR_EXPRESSION "moc_.*") @@ -87,6 +92,8 @@ TARGET_LINK_LIBRARIES( ogs-gui QVTK VtkVis VtkAct + vtkNetCDF + vtkNetCDF_cxx ) IF (Shapelib_FOUND) @@ -97,10 +104,6 @@ IF (libgeotiff_FOUND) TARGET_LINK_LIBRARIES( ogs-gui ${libgeotiff_LIBRARIES} ) ENDIF () # libgeotiff_FOUND -IF (libtiff_FOUND) - TARGET_LINK_LIBRARIES( ogs-gui ${libtiff_LIBRARIES} ) -ENDIF () # libtiff_FOUND - ADD_DEPENDENCIES ( ogs-gui VtkVis OGSProject ) IF(MSVC) @@ -115,12 +118,12 @@ ENDIF() # OGS_BUILD_INFO ### OpenSG support ### IF (OGS_USE_OPENSG) USE_OPENSG(ogs-gui) - INCLUDE_DIRECTORIES( ../OpenSG ) + INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/Qt/OpenSG ) TARGET_LINK_LIBRARIES( ogs-gui OgsOpenSG ) ENDIF (OGS_USE_OPENSG) IF(OGS_USE_VRPN) - INCLUDE_DIRECTORIES( ../Vrpn ${CMAKE_BINARY_DIR}/Qt/Vrpn ) + INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/Qt/Vrpn ${CMAKE_BINARY_DIR}/Qt/Vrpn ) TARGET_LINK_LIBRARIES( ogs-gui ${VRPN_LIBRARIES} OgsVrpn ) ENDIF() @@ -133,17 +136,17 @@ IF (OGS_VRED_PLUGIN) ADD_DEFINITIONS( -DBOOST_PYTHON_DYNAMIC_LIB ) - + INCLUDE_DIRECTORIES( #${VRED_DIR}/include/vred - ${VRED_DIR}/include/boost-1.34-vc8.0 - ${VRED_DIR}/include/python-2.52-vc8.0 - #${VRED_DIR}/include/zlib-1.23 - #${VRED_DIR}/include/OpenSG - #${VRED_DIR}/include/OpenSG/OpenSG + ${VRED_DIR}/include/boost-1.34-vc8.0 + ${VRED_DIR}/include/python-2.52-vc8.0 + #${VRED_DIR}/include/zlib-1.23 + #${VRED_DIR}/include/OpenSG + #${VRED_DIR}/include/OpenSG/OpenSG ) LINK_DIRECTORIES( ${VRED_DIR}/bin/WIN32 ) - + ADD_LIBRARY( ogs-gui-vred SHARED ${SOURCES} ${HEADERS} @@ -163,14 +166,13 @@ IF (OGS_VRED_PLUGIN) QtDataView StratView ${Shapelib_LIBRARIES} - ${libtiff_LIBRARIES} ${libgeotiff_LIBRARIES} QVTK VtkVis VtkAct #boost_python-vc80-mt-1_34_1 ) - + ADD_DEPENDENCIES ( ogs-gui-vred VtkVis OGSProject ) ENDIF (OGS_VRED_PLUGIN) @@ -180,20 +182,20 @@ ENDIF (OGS_VRED_PLUGIN) IF (OGS_PACKAGING) INSTALL (TARGETS ogs-gui RUNTIME DESTINATION bin COMPONENT ogs_gui) - + IF(MSVC) SET(OGS_GUI_EXE ${OGS_EXECUTABLE}-gui.exe) ELSE(MSVC) SET(OGS_GUI_EXE ${OGS_EXECUTABLE}-gui) ENDIF(MSVC) - + INCLUDE(GetPrerequisites) if (EXISTS ${OGS_GUI_EXE}) GET_PREREQUISITES(${OGS_GUI_EXE} OGS_GUI_DEPENDENCIES 1 1 "/usr/local/lib;/;${VTK_DIR};${OpenSG_LIBRARY_DIRS}" "") MESSAGE (STATUS "ogs-gui depends on:") FOREACH(DEPENDENCY ${OGS_GUI_DEPENDENCIES}) IF(NOT ${DEPENDENCY} STREQUAL "not") # Some bug on Linux? - message("${DEPENDENCY}") + message("${DEPENDENCY}") GP_RESOLVE_ITEM ("/" "${DEPENDENCY}" ${OGS_GUI_EXE} "/usr/local/lib;/;${VTK_DIR}" DEPENDENCY_PATH) SET (DEPENDENCY_PATHS ${DEPENDENCY_PATHS} ${DEPENDENCY_PATH}) ENDIF() diff --git a/Gui/mainwindow.cpp b/Gui/mainwindow.cpp index 4496f3822cc..b79de50b708 100644 --- a/Gui/mainwindow.cpp +++ b/Gui/mainwindow.cpp @@ -16,12 +16,16 @@ //dialogs #include "DBConnectionDialog.h" +#include "CondFromRasterDialog.h" +#include "ConditionWriterDialog.h" #include "DiagramPrefsDialog.h" #include "FEMConditionSetupDialog.h" +#include "OGSFileConverter.h" #include "GMSHPrefsDialog.h" #include "LineEditDialog.h" #include "ListPropertiesDialog.h" #include "MshQualitySelectionDialog.h" +#include "NetCdfConfigureDialog.h" #include "NewProcessDialog.h" #include "SetNameDialog.h" #include "VisPrefsDialog.h" @@ -33,7 +37,7 @@ #include "DatabaseConnection.h" #include "OGSError.h" -#include "OGSRaster.h" +#include "VtkRaster.h" #include "RecentFiles.h" #include "TreeModelIterator.h" #include "VtkBGImageSource.h" @@ -41,15 +45,14 @@ #include "VtkVisPipeline.h" #include "VtkVisPipelineItem.h" -//test +// FEM Conditions #include "BoundaryCondition.h" #include "InitialCondition.h" -#include "MathIO/CRSIO.h" -#include "Raster.h" #include "SourceTerm.h" #include "rf_bc_new.h" #include "rf_ic_new.h" #include "rf_st_new.h" +#include "FEMIO/BoundaryConditionIO.h" // FileIO includes #include "FEFLOWInterface.h" @@ -71,6 +74,7 @@ // MSH #include "msh_mesh.h" +#include "MeshGrid.h" // MSHGEOTOOLS #include "ExtractMeshNodes.h" @@ -115,7 +119,7 @@ Problem* aproblem = NULL; using namespace FileIO; MainWindow::MainWindow(QWidget* parent /* = 0*/) - : QMainWindow(parent), _db (NULL), _project() + : QMainWindow(parent), _db (NULL), _project(), _import_files_menu(NULL) { setupUi(this); @@ -156,12 +160,12 @@ MainWindow::MainWindow(QWidget* parent /* = 0*/) this, SLOT(showLineEditDialog(const std::string &))); // open line edit dialog connect(geoTabWidget->treeView, SIGNAL(requestNameChangeDialog(const std::string&, const GEOLIB::GEOTYPE, size_t)), this, SLOT(showGeoNameDialog(const std::string&, const GEOLIB::GEOTYPE, size_t))); - connect(geoTabWidget->treeView, SIGNAL(requestCondSetupDialog(const std::string&, const GEOLIB::GEOTYPE, size_t)), - this, SLOT(showCondSetupDialog(const std::string&, const GEOLIB::GEOTYPE, size_t))); + connect(geoTabWidget->treeView, SIGNAL(requestCondSetupDialog(const std::string&, const GEOLIB::GEOTYPE, size_t, bool)), + this, SLOT(showCondSetupDialog(const std::string&, const GEOLIB::GEOTYPE, size_t, bool))); connect(geoTabWidget->treeView, SIGNAL(loadFEMCondFileRequested(std::string)), this, SLOT(loadFEMConditions(std::string))); // add FEM Conditions - connect(geoTabWidget->treeView, SIGNAL(saveFEMConditionsRequested(QString, QString)), - this, SLOT(writeFEMConditionsToFile(QString, QString))); + //connect(geoTabWidget->treeView, SIGNAL(saveFEMConditionsRequested(QString, QString)), + // this, SLOT(writeFEMConditionsToFile(QString, QString))); connect(_geoModels, SIGNAL(geoDataAdded(GeoTreeModel *, std::string, GEOLIB::GEOTYPE)), this, SLOT(updateDataViews())); connect(_geoModels, SIGNAL(geoDataRemoved(GeoTreeModel *, std::string, GEOLIB::GEOTYPE)), @@ -179,8 +183,10 @@ MainWindow::MainWindow(QWidget* parent /* = 0*/) _elementModel, SLOT(clearView())); connect(mshTabWidget->treeView, SIGNAL(qualityCheckRequested(VtkMeshSource*)), this, SLOT(showMshQualitySelectionDialog(VtkMeshSource*))); + connect(mshTabWidget->treeView, SIGNAL(requestCondSetupDialog(const std::string&, const GEOLIB::GEOTYPE, size_t, bool)), + this, SLOT(showCondSetupDialog(const std::string&, const GEOLIB::GEOTYPE, size_t, bool))); connect(mshTabWidget->treeView, SIGNAL(requestDIRECTSourceTerms(const std::string, const std::vector<GEOLIB::Point*>*)), - this, SLOT(loadDIRECTSourceTerms(const std::string, const std::vector<GEOLIB::Point*>*))); + this, SLOT(loadDIRECTSourceTermsFromASCII(const std::string, const std::vector<GEOLIB::Point*>*))); // Setup connections for process model to GUI connect(modellingTabWidget->treeView, SIGNAL(conditionsRemoved(const FiniteElement::ProcessType, const std::string&, const FEMCondition::CondType)), @@ -189,6 +195,8 @@ MainWindow::MainWindow(QWidget* parent /* = 0*/) _processModel, SLOT(removeProcess(const FiniteElement::ProcessType))); connect(modellingTabWidget, SIGNAL(requestNewProcess()), this, SLOT(showNewProcessDialog())); + connect(modellingTabWidget->treeView, SIGNAL(saveConditionsRequested()), + this, SLOT(showConditionWriterDialog())); // VisPipeline Connects connect(_geoModels, SIGNAL(geoDataAdded(GeoTreeModel *, std::string, GEOLIB::GEOTYPE)), @@ -249,9 +257,8 @@ MainWindow::MainWindow(QWidget* parent /* = 0*/) SIGNAL(elementPicked(const GridAdapter *, const size_t)), mshTabWidget->elementView, SLOT(updateView())); - connect(vtkVisTabWidget->vtkVisPipelineView, - SIGNAL(meshAdded(MeshLib::CFEMesh *, std::string &)), - _meshModels, SLOT(addMesh(MeshLib::CFEMesh *, std::string &))); + connect(vtkVisTabWidget->vtkVisPipelineView, SIGNAL(meshAdded(GridAdapter*)), + _meshModels, SLOT(addMesh(GridAdapter*))); // Stack the data dock widgets together tabifyDockWidget(geoDock, mshDock); @@ -273,7 +280,8 @@ MainWindow::MainWindow(QWidget* parent /* = 0*/) _screenGeometries.push_back(desktopWidget->availableGeometry((int)i)); // Setup import files menu - menu_File->insertMenu(action_Exit, createImportFilesMenu()); + _import_files_menu = createImportFilesMenu(); + menu_File->insertMenu(action_Exit, _import_files_menu); // Setup recent files menu RecentFiles* recentFiles = new RecentFiles(this, SLOT(openRecentFile()), @@ -368,6 +376,7 @@ MainWindow::MainWindow(QWidget* parent /* = 0*/) MainWindow::~MainWindow() { + delete _import_files_menu; delete _db; delete _vtkVisPipeline; delete _meshModels; @@ -429,12 +438,12 @@ void MainWindow::showVisDockWidget(bool show) void MainWindow::open() { QSettings settings("UFZ", "OpenGeoSys-5"); - QString fileName = QFileDialog::getOpenFileName( this, "Select data file to open",settings.value("lastOpenedFileDirectory").toString(), + QString fileName = QFileDialog::getOpenFileName( this, "Select data file to open",settings.value("lastOpenedOgsFileDirectory").toString(), "Geosys files (*.gsp *.gli *.gml *.msh *.stn);;Project files (*.gsp);;GeoSys FEM Conditions (*.cnd *.bc *.ic *.st);;GLI files (*.gli);;MSH files (*.msh);;STN files (*.stn);;All files (* *.*)"); if (!fileName.isEmpty()) { QDir dir = QDir(fileName); - settings.setValue("lastOpenedFileDirectory", dir.absolutePath()); + settings.setValue("lastOpenedOgsFileDirectory", dir.absolutePath()); loadFile(fileName); } } @@ -492,7 +501,7 @@ void MainWindow::save() { std::string schemaName(_fileFinder.getPath("OpenGeoSysProject.xsd")); XmlGspInterface xml(&_project, schemaName); - xml.writeFile(fileName); + xml.writeToFile(fileName.toStdString()); } else if (fi.suffix().toLower() == "geo") { @@ -501,13 +510,19 @@ void MainWindow::save() // 2. if "useStationsAsConstraints"-parameter is true, GMSH-Interface will also integrate all stations that are currently loaded // if "useSteinerPoints"-parameter is true, additional points will be inserted in large areas without information // 3. after the geo-file is created the merged geometry is deleted again as it is no longer needed - GMSHInterface gmsh_io(fileName.toStdString()); std::vector<std::string> names; this->_project.getGEOObjects()->getGeometryNames(names); std::string merge_name("MergedGeometry"); _geoModels->mergeGeometries (names, merge_name); - gmsh_io.writeGMSHInputFile(merge_name, - *(this->_project.getGEOObjects()), true, true); + names.clear(); + names.push_back(merge_name); + + double param1(0.5); // mesh density scaling on normal points + double param2(0.05); // mesh density scaling on station points + size_t param3(2); // points per leaf + GMSHInterface gmsh_io(*(this->_project.getGEOObjects()), true, FileIO::GMSH::AdaptiveMeshDensity, param1, param2, param3, names); + gmsh_io.writeToFile(fileName.toStdString()); + this->_project.getGEOObjects()->removeSurfaceVec(merge_name); this->_project.getGEOObjects()->removePolylineVec(merge_name); this->_project.getGEOObjects()->removePointVec(merge_name); @@ -539,9 +554,12 @@ void MainWindow::loadFile(const QString &fileName) QTime myTimer0; myTimer0.start(); #endif - // FileIO::readGLIFileV4 (fileName.toStdString(), _geoModels); std::string unique_name; - readGLIFileV4(fileName.toStdString(), _geoModels, unique_name); + std::vector<std::string> errors; + if (! readGLIFileV4(fileName.toStdString(), _geoModels, unique_name, errors)) { + for (size_t k(0); k<errors.size(); k++) + OGSError::box(QString::fromStdString(errors[k])); + } #ifndef NDEBUG std::cout << myTimer0.elapsed() << " ms" << std::endl; #endif @@ -591,10 +609,14 @@ void MainWindow::loadFile(const QString &fileName) // OpenGeoSys mesh files else if (fi.suffix().toLower() == "msh") { + FileIO::OGSMeshIO meshIO; std::string name = fileName.toStdString(); - MeshLib::CFEMesh* msh = FileIO::OGSMeshIO::loadMeshFromFile(name); + MeshLib::CFEMesh* msh = meshIO.loadMeshFromFile(name); if (msh) - _meshModels->addMesh(msh, name); + { + std::string mesh_name = fi.baseName().toStdString(); + _meshModels->addMesh(msh, mesh_name); + } else OGSError::box("Failed to load a mesh file."); } @@ -614,7 +636,7 @@ void MainWindow::loadFile(const QString &fileName) std::string name = fi.baseName().toStdString(); if (GMSInterface::readBoreholesFromGMS(boreholes, fileName.toStdString())) - _geoModels->addStationVec(boreholes, name, GEOLIB::getRandomColor()); + _geoModels->addStationVec(boreholes, name); else OGSError::box("Error reading GMS file."); } @@ -641,7 +663,7 @@ void MainWindow::loadFile(const QString &fileName) } // NetCDF files - // YW 07.2010 + // CH 01.2012 else if (fi.suffix().toLower() == "nc") { #ifndef NDEBUG @@ -650,17 +672,21 @@ void MainWindow::loadFile(const QString &fileName) std::cout << "NetCDF Read ...\n" << std::flush; #endif std::string name = fileName.toStdString(); - std::vector<GEOLIB::Point*>* pnt_vec = - new std::vector<GEOLIB::Point*>(); - /* Data dimensions. */ - size_t len_rlat, len_rlon; - FileIO::NetCDFInterface::readNetCDFData(name, pnt_vec, _geoModels, - len_rlat, len_rlon); - MeshLib::CFEMesh* mesh = FileIO::NetCDFInterface::createMeshFromPoints(pnt_vec, - len_rlat, - len_rlon); - //GridAdapter* grid = new GridAdapter(mesh); - _meshModels->addMesh(mesh, name); + GridAdapter* mesh; + + NetCdfConfigureDialog dlg(name); + dlg.exec(); + if (dlg.getMesh() != NULL) + { + mesh = dlg.getMesh(); + mesh->setName(dlg.getName()); + _meshModels->addMesh(mesh); + } + if (dlg.getRaster() != NULL) + { + _vtkVisPipeline->addPipelineItem(dlg.getRaster()); + } + #ifndef NDEBUG std::cout << myTimer.elapsed() << " ms" << std::endl; #endif @@ -813,17 +839,17 @@ void MainWindow::importRaster() QString geotiffExtension(""); #endif QString fileName = QFileDialog::getOpenFileName(this, "Select raster file to import", - settings.value("lastOpenedFileDirectory").toString(), QString( - "Raster files (*.asc *.bmp *.jpg *.png%1);;") .arg(geotiffExtension)); + settings.value("lastOpenedRasterFileDirectory").toString(), QString( + "Raster files (*.asc *.grd *.bmp *.jpg *.png%1);;") .arg(geotiffExtension)); if (!fileName.isEmpty()) { VtkGeoImageSource* geoImage = VtkGeoImageSource::New(); - geoImage->setImageFilename(fileName); + geoImage->readImage(fileName); _vtkVisPipeline->addPipelineItem(geoImage); QDir dir = QDir(fileName); - settings.setValue("lastOpenedFileDirectory", dir.absolutePath()); + settings.setValue("lastOpenedRasterFileDirectory", dir.absolutePath()); } } @@ -836,27 +862,24 @@ void MainWindow::importRasterAsPoly() QString geotiffExtension(""); #endif QString fileName = QFileDialog::getOpenFileName(this, "Select raster file to import", - settings.value("lastOpenedFileDirectory").toString(), QString( + settings.value("lastOpenedRasterFileDirectory").toString(), QString( "Raster files (*.asc *.bmp *.jpg *.png%1);;") .arg( geotiffExtension)); if (!fileName.isEmpty()) { QImage raster; - QPointF origin; - double scalingFactor; - OGSRaster::loadImage(fileName, raster, origin, scalingFactor, false); - //OGSRaster::loadImage(fileName, raster, origin, scalingFactor, true, true); - + double origin[2]; + double cellSize; + vtkImageAlgorithm* imageAlgorithm = VtkRaster::loadImage( + fileName.toStdString(), origin[0], origin[1], cellSize); VtkBGImageSource* bg = VtkBGImageSource::New(); - bg->SetOrigin(origin.x(), origin.y()); - bg->SetCellSize(scalingFactor); - bg->SetRaster(raster); + bg->SetRaster(imageAlgorithm, origin[0], origin[1], cellSize); bg->SetName(fileName); _vtkVisPipeline->addPipelineItem(bg); QDir dir = QDir(fileName); - settings.setValue("lastOpenedFileDirectory", dir.absolutePath()); + settings.setValue("lastOpenedRasterFileDirectory", dir.absolutePath()); } } @@ -865,7 +888,7 @@ void MainWindow::importShape() { QSettings settings("UFZ", "OpenGeoSys-5"); QString fileName = QFileDialog::getOpenFileName(this, "Select shape file to import", - settings.value("lastOpenedFileDirectory").toString(), + settings.value("lastOpenedShapeFileDirectory").toString(), "ESRI Shape files (*.shp );;"); QFileInfo fi(fileName); @@ -875,7 +898,7 @@ void MainWindow::importShape() dlg.exec(); QDir dir = QDir(fileName); - settings.setValue("lastOpenedFileDirectory", dir.absolutePath()); + settings.setValue("lastOpenedShapeFileDirectory", dir.absolutePath()); } } #endif @@ -916,10 +939,10 @@ void MainWindow::importTetGen() { QSettings settings("UFZ", "OpenGeoSys-5"); QString node_fname(QFileDialog::getOpenFileName(this, "Select TetGen node file", - settings.value("lastOpenedFileDirectory").toString(), + settings.value("lastOpenedTetgenFileDirectory").toString(), "TetGen node files (*.node);;")); QString element_fname(QFileDialog::getOpenFileName(this, "Select TetGen element file", - settings.value("lastOpenedFileDirectory").toString(), + settings.value("lastOpenedTetgenFileDirectory").toString(), "TetGen element files (*.ele);;")); if (!node_fname.isEmpty() && !element_fname.isEmpty()) { @@ -930,7 +953,7 @@ void MainWindow::importTetGen() _meshModels->addMesh(msh, name); } else OGSError::box("Failed to load a TetGen mesh."); - settings.setValue("lastOpenedFileDirectory", QDir(node_fname).absolutePath()); + settings.setValue("lastOpenedTetgenFileDirectory", QDir(node_fname).absolutePath()); } } @@ -939,8 +962,7 @@ void MainWindow::importVtk() QSettings settings("UFZ", "OpenGeoSys-5"); QStringList fileNames = QFileDialog::getOpenFileNames(this, "Select VTK file(s) to import", - settings.value( - "lastOpenedFileDirectory"). + settings.value("lastOpenedVtkFileDirectory"). toString(), "VTK files (*.vtk *.vti *.vtr *.vts *.vtp *.vtu);;"); foreach(QString fileName, fileNames) { @@ -948,7 +970,7 @@ void MainWindow::importVtk() { _vtkVisPipeline->loadFromFile(fileName); QDir dir = QDir(fileName); - settings.setValue("lastOpenedFileDirectory", dir.absolutePath()); + settings.setValue("lastOpenedVtkFileDirectory", dir.absolutePath()); } } } @@ -997,14 +1019,11 @@ void MainWindow::showAddPipelineFilterItemDialog(QModelIndex parentIndex) dlg.exec(); } - void MainWindow::loadFEMConditions(std::string geoName) { QSettings settings("UFZ", "OpenGeoSys-5"); QString fileName = QFileDialog::getOpenFileName( this, "Select data file to open", - settings.value( - "lastOpenedFileDirectory"). - toString(), + settings.value("lastOpenedFileDirectory").toString(), "Geosys FEM condition files (*.cnd *.bc *.ic *.st);;All files (* *.*)"); QDir dir = QDir(fileName); settings.setValue("lastOpenedFileDirectory", dir.absolutePath()); @@ -1066,9 +1085,28 @@ void MainWindow::loadFEMConditionsFromFile(const QString &fileName, std::string } } } + this->addFEMConditions(conditions); +} + +void MainWindow::addFEMConditions(const std::vector<FEMCondition*> conditions) +{ if (!conditions.empty()) { - this->_processModel->addConditions(conditions); + for (size_t i = 0; i < conditions.size(); i++) + { + + if (conditions[i]->getProcessDistributionType() == FiniteElement::DIRECT) + { + std::vector<GEOLIB::Point*> *points = GEOLIB::PointVec::deepcopy(_meshModels->getMesh(conditions[i]->getAssociatedGeometryName())->getNodes()); + GEOLIB::PointVec pnt_vec("MeshNodes", points); + std::vector<GEOLIB::Point*> *cond_points = pnt_vec.getSubset(conditions[i]->getDisNodes()); + std::string geo_name = conditions[i]->getGeoName(); + this->_geoModels->addPointVec(cond_points, geo_name); + conditions[i]->setGeoName(geo_name); // this might have been changed upon inserting it into geo_objects + } + + this->_processModel->addCondition(conditions[i]); + } for (std::list<CBoundaryCondition*>::iterator it = bc_list.begin(); it != bc_list.end(); ++it) @@ -1083,36 +1121,106 @@ void MainWindow::loadFEMConditionsFromFile(const QString &fileName, std::string } } -void MainWindow::writeFEMConditionsToFile(QString geoName, QString fileName) +// Legacy function (only required for ascii st-files): reads values for 'direct' source terms +void MainWindow::loadDIRECTSourceTermsFromASCII(const std::string mshname, const std::vector<GEOLIB::Point*>* points) { - std::string schemaName(_fileFinder.getPath("OpenGeoSysCond.xsd")); - XmlCndInterface xml(&_project, schemaName); - xml.writeFile(fileName, geoName); + std::string geo_name(mshname); + + QSettings settings("UFZ", "OpenGeoSys-5"); + QString fileName = QFileDialog::getOpenFileName( this, "Select data file to open", + settings.value("lastOpenedFileDirectory").toString(), + "Geosys FEM condition files (*.st);;All files (* *.*)"); + QFileInfo fi(fileName); + std::string file_path = fi.absoluteDir().absolutePath().toStdString() + "/"; + + if (!fileName.isEmpty()) + { + std::string st_file_name (file_path); + STRead(st_file_name.append(fi.baseName().toStdString()), *_geoModels, geo_name); + + for (std::vector<CSourceTerm*>::const_iterator it = st_vector.begin(); it != st_vector.end(); + ++it) + { + if ((*it)->getProcessDistributionType() == FiniteElement::DIRECT) + { + CSourceTerm ast = **it; + SourceTerm* st = new SourceTerm(ast, mshname); + std::vector< std::pair<size_t, double> > node_values; + SourceTerm::getDirectNodeValues(file_path + (*it)->fname, node_values); + st->setGeoName(mshname); + st->setDisValues(node_values); + + std::vector<GEOLIB::Point*> *points2 = GEOLIB::PointVec::deepcopy(points); + GEOLIB::PointVec pnt_vec("MeshNodes", points2); + std::vector<GEOLIB::Point*> *cond_points = pnt_vec.getSubset(st->getDisNodes()); + std::string geometry_name = st->getGeoName(); + this->_geoModels->addPointVec(cond_points, geometry_name); + this->_processModel->addCondition(st); + } + } + } +} + +void MainWindow::writeFEMConditionsToFile(const QString &geoName, const FEMCondition::CondType type, const QString &fileName) +{ + QFileInfo fi(fileName); + if (fi.suffix().compare("cnd") == 0 ) + { + std::string schemaName(_fileFinder.getPath("OpenGeoSysCond.xsd")); + XmlCndInterface xml(&_project, schemaName); + xml.setNameForExport(geoName.toStdString()); + xml.setConditionType(type); + xml.writeToFile(fileName.toStdString()); + } + else + { + const std::vector<FEMCondition*> conds = _project.getConditions(); + for (size_t i=0; i<conds.size(); i++) + { + if ((conds[i]->getCondType() == type) && + (QString::fromStdString(conds[i]->getAssociatedGeometryName()) == geoName)) + { + if (type == FEMCondition::BOUNDARY_CONDITION) + bc_list.push_back(new CBoundaryCondition(static_cast<BoundaryCondition*>(conds[i]))); + else if (type == FEMCondition::INITIAL_CONDITION) + ic_vector.push_back(new CInitialCondition(static_cast<InitialCondition*>(conds[i]))); + else if (type == FEMCondition::SOURCE_TERM) + st_vector.push_back(new CSourceTerm(static_cast<SourceTerm*>(conds[i]))); + } + } + if (type == FEMCondition::BOUNDARY_CONDITION) + BCWrite(fileName.toStdString()); + else if (type == FEMCondition::INITIAL_CONDITION) + ICWrite(fileName.toStdString()); + else if (type == FEMCondition::SOURCE_TERM) + STWrite(fileName.toStdString()); + } } void MainWindow::writeGeometryToFile(QString gliName, QString fileName) { std::string schemaName(_fileFinder.getPath("OpenGeoSysGLI.xsd")); XmlGmlInterface xml(&_project, schemaName); - xml.writeFile(fileName, gliName); + xml.setNameForExport(gliName.toStdString()); + xml.writeToFile(fileName.toStdString()); } void MainWindow::writeStationListToFile(QString listName, QString fileName) { std::string schemaName(_fileFinder.getPath("OpenGeoSysSTN.xsd")); XmlStnInterface xml(&_project, schemaName); - xml.writeFile(fileName, listName); + xml.setNameForExport(listName.toStdString()); + xml.writeToFile(fileName.toStdString()); } void MainWindow::exportBoreholesToGMS(std::string listName, std::string fileName) { - const std::vector<GEOLIB::Point*>* stations(_geoModels->getStationVec( - listName)); + const std::vector<GEOLIB::Point*>* stations(_geoModels->getStationVec(listName)); GMSInterface::writeBoreholesToGMS(stations, fileName); } -void MainWindow::callGMSH(std::vector<std::string> const & selectedGeometries, +void MainWindow::callGMSH(std::vector<std::string> & selectedGeometries, size_t param1, double param2, double param3, double param4, bool delete_geo_file) { @@ -1133,21 +1241,24 @@ void MainWindow::callGMSH(std::vector<std::string> const & selectedGeometries, if (!fileName.isEmpty()) { - GMSHInterface gmsh_io(fileName.toStdString()); - - if (param4 == -1) // adaptive meshing selected - gmsh_io.writeAllDataToGMSHInputFile(*_geoModels, - selectedGeometries, - param1, - param2, - param3); - else // homogeneous meshing selected - gmsh_io.writeAllDataToGMSHInputFile(*_geoModels, - selectedGeometries, param4); + if (param4 == -1) { // adaptive meshing selected + GMSHInterface gmsh_io(*(static_cast<GEOLIB::GEOObjects*> (_geoModels)), true, + FileIO::GMSH::AdaptiveMeshDensity, param2, param3, param1, + selectedGeometries); + gmsh_io.setPrecision(20); + gmsh_io.writeToFile(fileName.toStdString()); + } else { // homogeneous meshing selected + GMSHInterface gmsh_io(*(static_cast<GEOLIB::GEOObjects*> (_geoModels)), true, + FileIO::GMSH::FixedMeshDensity, param4, param3, param1, + selectedGeometries); + gmsh_io.setPrecision(20); + gmsh_io.writeToFile(fileName.toStdString()); + } + if (system(NULL) != 0) // command processor available { - std::string gmsh_command("gmsh -2 "); + std::string gmsh_command("gmsh -2 -algo meshadapt "); std::string fname (fileName.toStdString()); gmsh_command += fname; size_t pos (fname.rfind (".")); @@ -1181,6 +1292,14 @@ void MainWindow::callGMSH(std::vector<std::string> const & selectedGeometries, } } +void MainWindow::showConditionWriterDialog() +{ + ConditionWriterDialog dlg(_geoModels); + connect(&dlg , SIGNAL(saveFEMConditionsRequested(const QString&, const FEMCondition::CondType, const QString&)), + this, SLOT(writeFEMConditionsToFile(const QString&, const FEMCondition::CondType, const QString&))); + dlg.exec(); +} + void MainWindow::showDiagramPrefsDialog(QModelIndex &index) { QString listName; @@ -1216,6 +1335,12 @@ void MainWindow::showDiagramPrefsDialog() } } +void MainWindow::showFileConverterDialog() +{ + OGSFileConverter dlg; + dlg.exec(); +} + void MainWindow::showGeoNameDialog(const std::string &geometry_name, const GEOLIB::GEOTYPE object_type, size_t id) { std::string old_name = this->_geoModels->getElementNameByID(geometry_name, object_type, id); @@ -1228,9 +1353,14 @@ void MainWindow::showGeoNameDialog(const std::string &geometry_name, const GEOLI id, this->_geoModels->getElementNameByID(geometry_name, object_type, id)); } -void MainWindow::showCondSetupDialog(const std::string &geometry_name, const GEOLIB::GEOTYPE object_type, size_t id) +void MainWindow::showCondSetupDialog(const std::string &geometry_name, const GEOLIB::GEOTYPE object_type, size_t id, bool on_points) { - std::string geo_name = this->_geoModels->getElementNameByID(geometry_name, object_type, id); + std::string geo_name(""); + if (object_type != GEOLIB::INVALID) + geo_name = this->_geoModels->getElementNameByID(geometry_name, object_type, id); + else + geo_name = geometry_name; // in this case this is actually the mesh name + if (geo_name.empty()) { this->showGeoNameDialog(geometry_name, object_type, id); @@ -1241,9 +1371,22 @@ void MainWindow::showCondSetupDialog(const std::string &geometry_name, const GEO OGSError::box("FEM Condition Setup cancelled."); else { - FEMConditionSetupDialog dlg(geometry_name, object_type, geo_name, this->_geoModels->getGEOObject(geometry_name, object_type, geo_name)); - connect(&dlg, SIGNAL(addFEMCondition(FEMCondition*)), this->_processModel, SLOT(addCondition(FEMCondition*))); - dlg.exec(); + if (on_points) + this->_geoModels->addNameForObjectPoints(geometry_name, object_type, geo_name, geometry_name); + + if (object_type != GEOLIB::INVALID) + { + FEMConditionSetupDialog dlg(geometry_name, object_type, geo_name, this->_geoModels->getGEOObject(geometry_name, object_type, geo_name), on_points); + connect(&dlg, SIGNAL(createFEMCondition(std::vector<FEMCondition*>)), this, SLOT(addFEMConditions(std::vector<FEMCondition*>))); + dlg.exec(); + } + else + { + const MeshLib::CFEMesh* mesh = _project.getMesh(geo_name); + FEMConditionSetupDialog dlg(geo_name, mesh); + connect(&dlg, SIGNAL(createFEMCondition(std::vector<FEMCondition*>)), this, SLOT(addFEMConditions(std::vector<FEMCondition*>))); + dlg.exec(); + } } } @@ -1266,8 +1409,8 @@ void MainWindow::showLineEditDialog(const std::string &geoName) void MainWindow::showGMSHPrefsDialog() { GMSHPrefsDialog dlg(_geoModels); - connect(&dlg, SIGNAL(requestMeshing(std::vector<std::string> const &, size_t, double, double, double, bool)), - this, SLOT(callGMSH(std::vector<std::string> const &, size_t, double, double, double, bool))); + connect(&dlg, SIGNAL(requestMeshing(std::vector<std::string> &, size_t, double, double, double, bool)), + this, SLOT(callGMSH(std::vector<std::string> &, size_t, double, double, double, bool))); dlg.exec(); } @@ -1286,22 +1429,28 @@ void MainWindow::showVisalizationPrefsDialog() void MainWindow::FEMTestStart() { - //FEMConditionSetupDialog* dlg = new FEMConditionSetupDialog(this->_project); - //dlg->exec(); - - // *** begin test TetGen read mesh - const std::string path ("/home/fischeth/Desktop/data/Ketzin/PSglobal/Tom/MSH/"); - std::string mesh_name ("ClosedSurface"); - std::string fname_nodes(path + mesh_name + ".1.node"); - std::string fname_elements(path + mesh_name + ".1.ele"); - - FileIO::TetGenInterface tetgen; - MeshLib::CFEMesh* mesh (tetgen.readTetGenMesh (fname_nodes, fname_elements)); - - if (mesh) - _meshModels->addMesh(mesh, mesh_name); - else - OGSError::box("Failed to load TetGen mesh file."); std::cout << "This is test functionality only..." << std::endl; +// std::map<std::string, MeshLib::CFEMesh*> const& mesh_map (_project.getMeshObjects()); +// +// std::string mesh_name(mesh_map.begin()->first); +// std::cout << "[Test] get mesh " << mesh_name << " ... " << std::flush; +// MeshLib::CFEMesh const*const mesh (_project.getMesh(mesh_name)); +// if (mesh) { +// std::cout << "done" << std::endl; +//#ifndef NDEBUG +// (mesh->getMeshGrid())->createMeshGridGeometry(_project.getGEOObjects()); +//#endif +//// std::cout << "[Test] writing mesh in TetGen file format ... " << std::flush; +//// FileIO::TetGenInterface tetgen_io; +//// tetgen_io.writeTetGenMesh(mesh_name+".node", mesh_name+".ele", mesh); +// std::cout << "done" << std::endl; +// } else { +// std::cout << "[Test] could not load mesh " << mesh_name << std::endl; +// } + + /* + CondFromRasterDialog dlg(_project.getMeshObjects()); + dlg.exec(); + */ } void MainWindow::showTrackingSettingsDialog() @@ -1526,45 +1675,3 @@ QString MainWindow::getLastUsedDir() return QDir::homePath(); } -void MainWindow::loadDIRECTSourceTerms(const std::string mshname, const std::vector<GEOLIB::Point*>* points) -{ - std::string geo_name(mshname); - - QSettings settings("UFZ", "OpenGeoSys-5"); - QString fileName = QFileDialog::getOpenFileName( this, "Select data file to open", - settings.value( - "lastOpenedFileDirectory"). - toString(), - "Geosys FEM condition files (*.st);;All files (* *.*)"); - QFileInfo fi(fileName); - QString name = fi.path() + "/"; - - if (!fileName.isEmpty()) - { - // create new geometry points vector by copying mesh nodes vector - std::vector<GEOLIB::Point*>* new_points = new std::vector<GEOLIB::Point*>; - //ignore name map because it makes things incredibly slow (and mesh-nodes cannot have names anyway, can they?) - //std::map<std::string, size_t>* name_pnt_id_map = new std::map<std::string, size_t>; - - for (size_t i = 0; i < points->size(); i++) - { - new_points->push_back(new GEOLIB::Point((*(*points)[i])[0], (*(*points)[i])[1], (*(*points)[i])[2])); - } - this->_geoModels->addPointVec(new_points, geo_name /*, name_pnt_id_map*/); - - STRead((name.append(fi.baseName())).toStdString(), *_geoModels, geo_name); - // access via st_vector (i.e. global vector from rf_st_new.h) - std::string file_path = fi.absoluteDir().absolutePath().toStdString(); - std::vector<FEMCondition*> conditions = SourceTerm::createDirectSourceTerms(st_vector, geo_name, file_path); - - // add boundary conditions to model - if (!conditions.empty()) - { - this->_processModel->addConditions(conditions); - for (size_t i = 0; i < st_vector.size(); i++) - delete st_vector[i]; - st_vector.clear(); - } - } -} - diff --git a/Gui/mainwindow.h b/Gui/mainwindow.h index 47234671200..6da7ce35f67 100644 --- a/Gui/mainwindow.h +++ b/Gui/mainwindow.h @@ -53,7 +53,7 @@ protected slots: /// Function calls for saving files. void save(); /// Function calls for generating GMSH files from the GUI - void callGMSH(std::vector<std::string> const & selectedGeometries, + void callGMSH(std::vector<std::string> & selectedGeometries, size_t param1, double param2, double param3, @@ -81,14 +81,16 @@ protected slots: void openRecentFile(); void about(); void showAddPipelineFilterItemDialog(QModelIndex parentIndex); + void showConditionWriterDialog(); /// Call dialog for creating or modifying FEM conditions. - void showCondSetupDialog(const std::string &geometry_name, const GEOLIB::GEOTYPE object_type, size_t id); + void showCondSetupDialog(const std::string &geometry_name, const GEOLIB::GEOTYPE object_type, size_t id, bool on_points = false); /// Allows setting the name for a geometric object void showGeoNameDialog(const std::string &geometry_name, const GEOLIB::GEOTYPE object_type, size_t id); /// Calls the diagram prefs dialog from the Tools menu. void showDiagramPrefsDialog(); /// Calls the diagram prefs dialog from the station list (i.e. for a specific station). void showDiagramPrefsDialog(QModelIndex &index); + void showFileConverterDialog(); void showLineEditDialog(const std::string &geoName); void showGMSHPrefsDialog(); void showMshQualitySelectionDialog(VtkMeshSource* mshSource); @@ -97,7 +99,8 @@ protected slots: void showVisalizationPrefsDialog(); void showTrackingSettingsDialog(); void updateDataViews(); - void writeFEMConditionsToFile(QString geoName, QString fileName); + void addFEMConditions(const std::vector<FEMCondition*> conditions); + void writeFEMConditionsToFile(const QString &geoName, const FEMCondition::CondType type, const QString &fileName); void writeGeometryToFile(QString listName, QString fileName); void writeStationListToFile(QString listName, QString fileName); @@ -110,7 +113,7 @@ protected slots: void startPresentationMode(); void quitPresentationMode(); - void loadDIRECTSourceTerms(const std::string name, const std::vector<GEOLIB::Point*>* points); //TODO put this in a better place + void loadDIRECTSourceTermsFromASCII(const std::string name, const std::vector<GEOLIB::Point*>* points); //TODO put this in a better place private: QMenu* createImportFilesMenu(); @@ -136,6 +139,8 @@ private: QList<QRect> _screenGeometries; QWidget* _vtkWidget; QByteArray _windowState; + QMenu* _import_files_menu; + #ifdef OGS_USE_VRPN TrackingSettingsWidget* _trackingSettingsWidget; #endif // OGS_USE_VRPN diff --git a/Gui/mainwindow.ui b/Gui/mainwindow.ui index aad1c105991..375d7f50143 100644 --- a/Gui/mainwindow.ui +++ b/Gui/mainwindow.ui @@ -127,6 +127,7 @@ <string>Tools</string> </property> <addaction name="actionMesh_Generation"/> + <addaction name="actionFile_Converter"/> <addaction name="actionDiagram_Viewer"/> <addaction name="actionFEM_Test"/> </widget> @@ -393,6 +394,11 @@ <string>About</string> </property> </action> + <action name="actionFile_Converter"> + <property name="text"> + <string>File Converter...</string> + </property> + </action> </widget> <layoutdefault spacing="6" margin="11"/> <customwidgets> @@ -611,6 +617,22 @@ </hint> </hints> </connection> + <connection> + <sender>actionFile_Converter</sender> + <signal>triggered()</signal> + <receiver>MainWindowClass</receiver> + <slot>showFileConverterDialog()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>400</x> + <y>372</y> + </hint> + </hints> + </connection> </connections> <slots> <slot>open()</slot> @@ -624,5 +646,6 @@ <slot>FEMTestStart()</slot> <slot>showDiagramPrefsDialog()</slot> <slot>about()</slot> + <slot>showFileConverterDialog()</slot> </slots> </ui> diff --git a/OpenSG/CMakeLists.txt b/OpenSG/CMakeLists.txt index 285f1faa2ec..76558c93482 100644 --- a/OpenSG/CMakeLists.txt +++ b/OpenSG/CMakeLists.txt @@ -13,7 +13,7 @@ SET( HEADERS ### Include directories ### INCLUDE_DIRECTORIES( - . + ${CMAKE_SOURCE_DIR}/Qt/OpenSG ) ### Create the library ### diff --git a/OpenSG/vtkOsgConverter.cpp b/OpenSG/vtkOsgConverter.cpp index c35c76e2217..5078fda13aa 100644 --- a/OpenSG/vtkOsgConverter.cpp +++ b/OpenSG/vtkOsgConverter.cpp @@ -25,6 +25,9 @@ #include <vtkSmartPointer.h> #include <vtkTexture.h> #include <vtkUnsignedCharArray.h> +#include <vtkCellDataToPointData.h> +#include <vtkLookupTable.h> +#include <vtkDiscretizableColorTransferFunction.h> #include <OpenSG/OSGGeoFunctions.h> #include <OpenSG/OSGGroup.h> @@ -36,19 +39,20 @@ #include <OpenSG/OSGPolygonChunk.h> #include <OpenSG/OSGSimpleGeometry.h> #include <OpenSG/OSGTwoSidedLightingChunk.h> +#include <OpenSG/OSGTextureChunk.h> +#include <OpenSG/OSGGL.h> OSG_USING_NAMESPACE vtkOsgConverter::vtkOsgConverter(vtkActor* actor) : _actor(actor), - _verbose(false), + _verbose(true), _osgRoot(NullFC), _osgTransform(NullFC) { TransformPtr tptr; _osgRoot = makeCoredNode<osg::Transform>(&tptr); _osgTransform = tptr; - _mapper = _actor->GetMapper(); } vtkOsgConverter::~vtkOsgConverter(void) @@ -58,14 +62,15 @@ vtkOsgConverter::~vtkOsgConverter(void) bool vtkOsgConverter::WriteAnActor() { + vtkMapper* actorMapper = _actor->GetMapper(); // see if the actor has a mapper. it could be an assembly - if (_actor->GetMapper() == NULL) + if (actorMapper == NULL) return false; // dont export when not visible if (_actor->GetVisibility() == 0) return false; - vtkDataObject* inputDO = _actor->GetMapper()->GetInputDataObject(0, 0); + vtkDataObject* inputDO = actorMapper->GetInputDataObject(0, 0); if (inputDO == NULL) return false; @@ -90,30 +95,63 @@ bool vtkOsgConverter::WriteAnActor() else pd = static_cast<vtkPolyData*>(inputDO); + // Get the color range from actors lookup table + double range[2]; + vtkLookupTable* actorLut = static_cast<vtkLookupTable*>(actorMapper->GetLookupTable()); + actorLut->GetTableRange(range); + // Copy mapper to a new one vtkPolyDataMapper* pm = vtkPolyDataMapper::New(); + // Convert cell data to point data + // NOTE: Comment this out to export a mesh + if (actorMapper->GetScalarMode() == VTK_SCALAR_MODE_USE_CELL_DATA || + actorMapper->GetScalarMode() == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA) + { + vtkCellDataToPointData* cellDataToPointData = vtkCellDataToPointData::New(); + cellDataToPointData->PassCellDataOff(); + cellDataToPointData->SetInput(pd); + cellDataToPointData->Update(); + pd = cellDataToPointData->GetPolyDataOutput(); + cellDataToPointData->Delete(); + + pm->SetScalarMode(VTK_SCALAR_MODE_USE_POINT_DATA); + } + else + pm->SetScalarMode(actorMapper->GetScalarMode()); + pm->SetInput(pd); - pm->SetScalarRange(_actor->GetMapper()->GetScalarRange()); - pm->SetScalarVisibility(_actor->GetMapper()->GetScalarVisibility()); - pm->SetLookupTable(_actor->GetMapper()->GetLookupTable()); - pm->SetScalarMode(_actor->GetMapper()->GetScalarMode()); + pm->SetScalarVisibility(actorMapper->GetScalarVisibility()); + + vtkLookupTable* lut = NULL; + // ParaView OpenSG Exporter + if (dynamic_cast<vtkDiscretizableColorTransferFunction*>(actorMapper->GetLookupTable())) + lut = actorLut; + // Clone the lut in OGS because otherwise the original lut gets destroyed + else + { + lut = vtkLookupTable::New(); + lut->DeepCopy(actorLut); + lut->Build(); + } + pm->SetLookupTable(lut); + pm->SetScalarRange(range); + pm->Update(); if(pm->GetScalarMode() == VTK_SCALAR_MODE_USE_POINT_FIELD_DATA || pm->GetScalarMode() == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ) { - if(_actor->GetMapper()->GetArrayAccessMode() == VTK_GET_ARRAY_BY_ID ) - pm->ColorByArrayComponent(_actor->GetMapper()->GetArrayId(), - _actor->GetMapper()->GetArrayComponent()); + if(actorMapper->GetArrayAccessMode() == VTK_GET_ARRAY_BY_ID ) + pm->ColorByArrayComponent(actorMapper->GetArrayId(), + actorMapper->GetArrayComponent()); else - pm->ColorByArrayComponent(_actor->GetMapper()->GetArrayName(), - _actor->GetMapper()->GetArrayComponent()); + pm->ColorByArrayComponent(actorMapper->GetArrayName(), + actorMapper->GetArrayComponent()); } - _mapper = pm; - // vtkPoints* points = pd->GetPoints(); + vtkPointData* pntData = pd->GetPointData(); bool hasTexCoords = false; - vtkUnsignedCharArray* vtkColors = pm->MapScalars(1.0); + vtkUnsignedCharArray* vtkColors = pm->MapScalars(1.0); // ARRAY SIZES vtkIdType m_iNumPoints = pd->GetNumberOfPoints(); @@ -138,8 +176,6 @@ bool vtkOsgConverter::WriteAnActor() std::cout << " number of primitives: " << m_iNumGLPrimitives << std::endl; } - _mapper->Update(); - // NORMALS vtkDataArray* vtkNormals = NULL; int m_iNormalType = NOT_GIVEN; @@ -271,7 +307,7 @@ bool vtkOsgConverter::WriteAnActor() _osgTransform->setMatrix(m); endEditCP(_osgTransform); - _mapper->Update(); + //pm->Update(); // Get the converted OpenSG node NodePtr osgGeomNode = Node::create(); @@ -291,12 +327,11 @@ bool vtkOsgConverter::WriteAnActor() GeoTexCoords2dPtr osgTexCoords = GeoTexCoords2d::create(); //Rendering with OpenSG simple indexed geometry - if (((m_iNormalType == PER_VERTEX) || (m_iNormalType == NOT_GIVEN)) && - ((m_iColorType == PER_VERTEX) || (m_iColorType == NOT_GIVEN))) + if (((m_iNormalType == PER_VERTEX) || (m_iNormalType == NOT_GIVEN)) && + ((m_iColorType == PER_VERTEX) || (m_iColorType == NOT_GIVEN))) { if (_verbose) - std::cout << "Start ProcessGeometryNormalsAndColorsPerVertex()" << - std::endl; + std::cout << "Start ProcessGeometryNormalsAndColorsPerVertex()" << std::endl; //getting the vertices: beginEditCP(osgPoints); @@ -318,8 +353,7 @@ bool vtkOsgConverter::WriteAnActor() for (int i = 0; i < iNumNormals; i++) { aNormal = vtkNormals->GetTuple(i); - osgNormals->addValue(Vec3f(aNormal[0], aNormal[1], - aNormal[2])); + osgNormals->addValue(Vec3f(aNormal[0], aNormal[1], aNormal[2])); } } endEditCP(osgNormals); if (iNumNormals != m_iNumPoints) @@ -327,8 +361,7 @@ bool vtkOsgConverter::WriteAnActor() std::cout << "WARNING: CVtkActorToOpenSG::ProcessGeometryNormalsAndColorsPerVertex() number of normals" << std::endl; - std::cout << "should equal the number of vertices (points)!" << - std::endl << std::endl; + std::cout << "should equal the number of vertices (points)!" << std::endl << std::endl; } } @@ -353,8 +386,7 @@ bool vtkOsgConverter::WriteAnActor() std::cout << "WARNING: CVtkActorToOpenSG::ProcessGeometryNormalsAndColorsPerVertex() number of colors" << std::endl; - std::cout << "should equal the number of vertices (points)!" << - std::endl << std::endl; + std::cout << "should equal the number of vertices (points)!" << std::endl << std::endl; } } @@ -418,8 +450,7 @@ bool vtkOsgConverter::WriteAnActor() prim = 0; pCells = pd->GetStrips(); if (pCells->GetNumberOfCells() > 0) - for (pCells->InitTraversal(); pCells->GetNextCell(npts, pts); - prim++) + for (pCells->InitTraversal(); pCells->GetNextCell(npts, pts); prim++) { osgLengths->addValue(npts); osgTypes->addValue(GL_TRIANGLE_STRIP); @@ -464,36 +495,28 @@ bool vtkOsgConverter::WriteAnActor() if(m_iNumGLPolygons > 0) { if(m_iNumGLPolygons != m_iNumGLPrimitives) - std::cout << - "WARNING: vtkActor contains different kind of primitives" << - std::endl; + std::cout << "WARNING: vtkActor contains different kind of primitives" << std::endl; gl_primitive_type = GL_POLYGON; //osgConversionSuccess = this->ProcessGeometryNonIndexedCopyAttributes(GL_POLYGON, pd, osgGeometry); } else if(m_iNumGLLineStrips > 0) { if (m_iNumGLLineStrips != m_iNumGLPrimitives) - std::cout << - "WARNING: vtkActor contains different kind of primitives" << - std::endl; + std::cout << "WARNING: vtkActor contains different kind of primitives" << std::endl; gl_primitive_type = GL_LINE_STRIP; //osgConversionSuccess = this->ProcessGeometryNonIndexedCopyAttributes(GL_LINE_STRIP, pd osgGeometry); } else if(m_iNumGLTriStrips > 0) { if (m_iNumGLTriStrips != m_iNumGLPrimitives) - std::cout << - "WARNING: vtkActor contains different kind of primitives" << - std::endl; + std::cout << "WARNING: vtkActor contains different kind of primitives" << std::endl; gl_primitive_type = GL_TRIANGLE_STRIP; //osgConversionSuccess = this->ProcessGeometryNonIndexedCopyAttributes(GL_TRIANGLE_STRIP, pd osgGeometry); } else if (m_iNumGLPoints > 0) { if (m_iNumGLPoints != m_iNumGLPrimitives) - std::cout << - "WARNING: vtkActor contains different kind of primitives" << - std::endl; + std::cout << "WARNING: vtkActor contains different kind of primitives" << std::endl; gl_primitive_type = GL_POINTS; //osgConversionSuccess = this->ProcessGeometryNonIndexedCopyAttributes(GL_POINTS, pd osgGeometry); } @@ -512,9 +535,7 @@ bool vtkOsgConverter::WriteAnActor() { std::cout << "CVtkActorToOpenSG::ProcessGeometryNonIndexedCopyAttributes(int gl_primitive_type)" - << std::endl; - std::cout << - " was called with non implemented gl_primitive_type!" << std::endl; + << std::endl << " was called with non implemented gl_primitive_type!" << std::endl; } beginEditCP(osgTypes); @@ -539,50 +560,35 @@ bool vtkOsgConverter::WriteAnActor() unsigned char aColor[4]; aVertex = pd->GetPoint(pts[i]); - osgPoints->addValue(Vec3f(aVertex[0], - aVertex[1], - aVertex[2])); + osgPoints->addValue(Vec3f(aVertex[0], aVertex[1], aVertex[2])); if (m_iNormalType == PER_VERTEX) { aNormal = vtkNormals->GetTuple(pts[i]); - osgNormals->addValue(Vec3f(aNormal[ - 0 - ], - aNormal[1], aNormal[2])); + osgNormals->addValue(Vec3f(aNormal[0], aNormal[1], aNormal[2])); } else if (m_iNormalType == PER_CELL) { aNormal = vtkNormals->GetTuple(prim); - osgNormals->addValue(Vec3f(aNormal[ - 0 - ], - aNormal[1], aNormal[2])); + osgNormals->addValue(Vec3f(aNormal[0], aNormal[1], aNormal[2])); } if (m_iColorType == PER_VERTEX) { - vtkColors->GetTupleValue(pts[i], - aColor); - float r = ((float) aColor[0]) / - 255.0f; - float g = ((float) aColor[1]) / - 255.0f; - float b = ((float) aColor[2]) / - 255.0f; + vtkColors->GetTupleValue(pts[i], aColor); + float r = ((float) aColor[0]) / 255.0f; + float g = ((float) aColor[1]) / 255.0f; + float b = ((float) aColor[2]) / 255.0f; osgColors->addValue(Color3f(r, g, b)); } else if (m_iColorType == PER_CELL) { vtkColors->GetTupleValue(prim, aColor); - float r = ((float) aColor[0]) / - 255.0f; - float g = ((float) aColor[1]) / - 255.0f; - float b = ((float) aColor[2]) / - 255.0f; + float r = ((float) aColor[0]) / 255.0f; + float g = ((float) aColor[1]) / 255.0f; + float b = ((float) aColor[2]) / 255.0f; osgColors->addValue(Color3f(r, g, b)); } } @@ -609,8 +615,7 @@ bool vtkOsgConverter::WriteAnActor() { double texCoords[3]; vtkTexCoords->GetTuple(i, texCoords); - osgTexCoords->addValue(Vec2f(texCoords[0], - texCoords[1])); + osgTexCoords->addValue(Vec2f(texCoords[0], texCoords[1])); } } endEditCP(osgTexCoords); } @@ -681,6 +686,8 @@ bool vtkOsgConverter::WriteAnActor() _osgRoot->addChild(osgGeomNode); endEditCP(_osgRoot); + pm->Delete(); + return true; } @@ -735,7 +742,7 @@ TextureChunkPtr vtkOsgConverter::CreateTexture(vtkTexture* vtkTexture) { data = imgPointData->GetScalars(); if (_verbose) - std::cout << " found texture data in point data" << std::endl; + std::cout << " Found texture data in point data" << std::endl; } if (imgCellData != NULL) @@ -743,7 +750,7 @@ TextureChunkPtr vtkOsgConverter::CreateTexture(vtkTexture* vtkTexture) { data = imgCellData->GetScalars(); if (_verbose) - std::cout << " found texture data in cell data" << std::endl; + std::cout << " Found texture data in cell data" << std::endl; } if (data == NULL) @@ -785,6 +792,8 @@ TextureChunkPtr vtkOsgConverter::CreateTexture(vtkTexture* vtkTexture) osgImage->setDataType(Image::OSG_UINT8_IMAGEDATA); if (iImgComps == 1) osgImage->setPixelFormat(Image::OSG_L_PF); + else if (iImgComps == 2) + osgImage->setPixelFormat(Image::OSG_LA_PF); else if (iImgComps == 3) osgImage->setPixelFormat(Image::OSG_RGB_PF); else if (iImgComps == 4) @@ -807,8 +816,8 @@ TextureChunkPtr vtkOsgConverter::CreateTexture(vtkTexture* vtkTexture) if (_verbose) { std::cout << " Loading image with " << iImgDims[0] << " x " << iImgDims[1] << - " x " << iImgDims[2] << "pixels." << std::endl; - std::cout << " components: " << iImgComps << std::endl; + " x " << iImgDims[2] << " pixels." << std::endl; + std::cout << " Components: " << iImgComps << std::endl; std::cout << "End CreateTexture()" << std::endl; } @@ -840,11 +849,11 @@ ChunkMaterialPtr vtkOsgConverter::CreateMaterial(bool lit, bool hasTexCoords) if (_verbose) { std::cout << " Colors:" << std::endl; - std::cout << " diffuse " << diffuse << " * " << diffuseColor[0] << " " << + std::cout << " diffuse " << diffuse << " * " << diffuseColor[0] << " " << diffuseColor[1] << " " << diffuseColor[2] << std::endl; - std::cout << " ambient " << ambient << " * " << ambientColor[0] << " " << + std::cout << " ambient " << ambient << " * " << ambientColor[0] << " " << ambientColor[1] << " " << ambientColor[2] << std::endl; - std::cout << " specular " << specular << " * " << specularColor[0] << " " << + std::cout << " specular " << specular << " * " << specularColor[0] << " " << specularColor[1] << " " << specularColor[2] << std::endl; } @@ -929,12 +938,17 @@ ChunkMaterialPtr vtkOsgConverter::CreateMaterial(bool lit, bool hasTexCoords) std::cout << " Add TextureChunk" << std::endl; osgChunkMaterial->addChunk(osgTextureChunk); } + + // Per default EnvMode is set to GL_REPLACE which does not lit the surface + beginEditCP(osgTextureChunk); + osgTextureChunk->setEnvMode(GL_MODULATE); + endEditCP(osgTextureChunk); } } } endEditCP(osgChunkMaterial); if (_verbose) - std::cout << " End CreateMaterial()" << std::endl; + std::cout << "End CreateMaterial()" << std::endl; return osgChunkMaterial; } diff --git a/OpenSG/vtkOsgConverter.h b/OpenSG/vtkOsgConverter.h index ca24f736743..a5f06c0bcbd 100644 --- a/OpenSG/vtkOsgConverter.h +++ b/OpenSG/vtkOsgConverter.h @@ -43,7 +43,6 @@ protected: private: vtkActor* _actor; - vtkMapper* _mapper; enum {NOT_GIVEN, PER_VERTEX, PER_CELL}; bool _verbose; diff --git a/Vrpn/CMakeLists.txt b/Vrpn/CMakeLists.txt index 9350c491f3d..aa5cdcf8abd 100644 --- a/Vrpn/CMakeLists.txt +++ b/Vrpn/CMakeLists.txt @@ -36,10 +36,10 @@ Qt4_WRAP_CPP( MOC_SOURCES ${MOC_HEADERS} ) ### Include directories ### INCLUDE_DIRECTORIES( - . - ${CMAKE_BINARY_DIR}/Qt/Vrpn/ + ${CMAKE_SOURCE_DIR}/Qt/Vrpn + ${CMAKE_BINARY_DIR}/Qt/Vrpn ${VRPN_INCLUDE_DIRS} - ../VtkVis + ${CMAKE_SOURCE_DIR}/Qt/VtkVis ${CMAKE_BINARY_DIR}/Qt/VtkVis ) diff --git a/VtkAct/CMakeLists.txt b/VtkAct/CMakeLists.txt index 78ee2b9fdc1..a8606e0be72 100644 --- a/VtkAct/CMakeLists.txt +++ b/VtkAct/CMakeLists.txt @@ -12,7 +12,7 @@ set( MOC_HEADERS # Header files set( HEADERS - + ) # UI files @@ -30,16 +30,16 @@ source_group("Moc Files" REGULAR_EXPRESSION "moc_.*") qt4_wrap_cpp( MOC_SOURCES ${MOC_HEADERS} ) include_directories( - . + ${CMAKE_SOURCE_DIR}/Qt/VtkAct ${CMAKE_BINARY_DIR}/Qt/VtkAct - ../../Base - ../../FEM - ../../GEO - ../../FileIO - ../../FileIO/MeshIO - ../../MSH - ../../MathLib - ../VtkVis + ${CMAKE_SOURCE_DIR}/Base + ${CMAKE_SOURCE_DIR}/FEM + ${CMAKE_SOURCE_DIR}/GEO + ${CMAKE_SOURCE_DIR}/FileIO + ${CMAKE_SOURCE_DIR}/FileIO/MeshIO + ${CMAKE_SOURCE_DIR}/MSH + ${CMAKE_SOURCE_DIR}/MathLib + ${CMAKE_SOURCE_DIR}/Qt/VtkVis ) # Create the library diff --git a/VtkVis/CMakeLists.txt b/VtkVis/CMakeLists.txt index d98326dac0b..c62e60cb943 100644 --- a/VtkVis/CMakeLists.txt +++ b/VtkVis/CMakeLists.txt @@ -8,7 +8,6 @@ SET( SOURCES VtkAlgorithmPropertyCheckbox.cpp VtkAlgorithmPropertyLineEdit.cpp VtkAlgorithmPropertyVectorEdit.cpp - VtkApplyColorTableFilter.cpp VtkBGImageSource.cpp VtkColorByHeightFilter.cpp VtkColorLookupTable.cpp @@ -31,6 +30,7 @@ SET( SOURCES VtkMeshSource.cpp VtkPolylinesSource.cpp VtkPointsSource.cpp + VtkRaster.cpp VtkSelectionFilter.cpp VtkStationSource.cpp VtkSurfacesSource.cpp @@ -43,6 +43,7 @@ SET( SOURCES VtkVisPipelineView.cpp VtkVisPointSetItem.cpp VtkVisTabWidget.cpp + VtkAlgorithmProperties.cpp ) # Moc headers @@ -64,7 +65,6 @@ SET( MOC_HEADERS # Header files SET( HEADERS - VtkApplyColorTableFilter.h VtkBGImageSource.h VtkColorByHeightFilter.h VtkColorLookupTable.h @@ -87,6 +87,7 @@ SET( HEADERS VtkMeshSource.h VtkPolylinesSource.h VtkPointsSource.h + VtkRaster.h VtkSelectionFilter.h VtkStationSource.h VtkSurfacesSource.h @@ -125,17 +126,18 @@ QT4_WRAP_UI( UI_HEADERS ${UIS} ) QT4_WRAP_CPP( MOC_SOURCES ${MOC_HEADERS} ) INCLUDE_DIRECTORIES( - . - ../VtkAct + ${CMAKE_SOURCE_DIR}/Qt/VtkVis + ${CMAKE_SOURCE_DIR}/Qt/VtkAct ${CMAKE_BINARY_DIR}/Qt/VtkVis - ../../Base - ../../FEM - ../../GEO - ../../MathLib - ../../FileIO - ../../MSH - ../Base - ../DataView + ${CMAKE_SOURCE_DIR}/Base + ${CMAKE_SOURCE_DIR}/FEM + ${CMAKE_SOURCE_DIR}/GEO + ${CMAKE_SOURCE_DIR}/MathLib + ${CMAKE_SOURCE_DIR}/FileIO + ${CMAKE_SOURCE_DIR}/MSH + ${CMAKE_SOURCE_DIR}/Qt/Base + ${CMAKE_SOURCE_DIR}/Qt/DataView + ${CMAKE_BINARY_DIR}/Qt/DataView ) # Create the library @@ -147,13 +149,20 @@ ADD_LIBRARY( VtkVis STATIC ${UIS} ) +IF (libgeotiff_FOUND) + INCLUDE_DIRECTORIES( ${libgeotiff_INCLUDE_DIR} ${libgeotiff_INCLUDE_DIR}/libxtiff ${VTK_DIR}/../Utilities/vtktiff ) + TARGET_LINK_LIBRARIES( VtkVis ${libgeotiff_LIBRARIES} ) +ENDIF () # libgeotiff_FOUND + TARGET_LINK_LIBRARIES( VtkVis ${QT_LIBRARIES} QVTK ) +ADD_DEPENDENCIES(VtkVis QtDataView) + IF(OGS_USE_VRPN) - INCLUDE_DIRECTORIES(../Vrpn) + INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/Qt/Vrpn) ENDIF() # OGS_USE_VRPN IF (OGS_USE_OPENSG) USE_OPENSG(VtkVis) - INCLUDE_DIRECTORIES( ../OpenSG ) + INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/Qt/OpenSG ) ENDIF (OGS_USE_OPENSG) diff --git a/VtkVis/VisPrefs.ui b/VtkVis/VisPrefs.ui index 10601129dcf..6641f0ffb83 100644 --- a/VtkVis/VisPrefs.ui +++ b/VtkVis/VisPrefs.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>188</width> - <height>296</height> + <height>402</height> </rect> </property> <property name="windowTitle"> @@ -110,6 +110,25 @@ </layout> </widget> </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Rendering</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="QCheckBox" name="cullBackfacesCheckBox"> + <property name="toolTip"> + <string>If enabled, all objects (such as triangles, quads) which normals are not pointing towards the view are not rendered.</string> + </property> + <property name="text"> + <string>Cull backfaces</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> <item> <widget class="QPushButton" name="closePushButton"> <property name="text"> diff --git a/VtkVis/VisPrefsDialog.cpp b/VtkVis/VisPrefsDialog.cpp index 3bfcd6210f1..cc2fb388d06 100644 --- a/VtkVis/VisPrefsDialog.cpp +++ b/VtkVis/VisPrefsDialog.cpp @@ -31,6 +31,7 @@ VisPrefsDialog::VisPrefsDialog(VtkVisPipeline* pipeline, superelevationLineEdit->setValidator(validator); QSettings settings("UFZ, OpenGeoSys-5"); superelevationLineEdit->setText(settings.value("globalSuperelevation", 1.0).toString()); + cullBackfacesCheckBox->setCheckState(Qt::CheckState(settings.value("globalCullBackfaces", 0).toInt())); } void VisPrefsDialog::on_bgColorButton_colorPicked( QColor color ) @@ -69,3 +70,12 @@ void VisPrefsDialog::on_loadShowAllCheckBox_stateChanged(int state) _visWidget->setShowAllOnLoad((bool)state); _vtkVisPipeline->resetCameraOnAddOrRemove((bool)state); } + +void VisPrefsDialog::on_cullBackfacesCheckBox_stateChanged(int state) +{ + _vtkVisPipeline->setGlobalBackfaceCulling((bool)state); + + QSettings settings("UFZ, OpenGeoSys-5"); + settings.setValue("globalCullBackfaces", state); +} + diff --git a/VtkVis/VisPrefsDialog.h b/VtkVis/VisPrefsDialog.h index a3b979d0e29..dd9fced3a2d 100644 --- a/VtkVis/VisPrefsDialog.h +++ b/VtkVis/VisPrefsDialog.h @@ -26,21 +26,24 @@ public: QDialog* parent = NULL); protected slots: - /// Sets the background colour. + /// @brief Sets the background colour. void on_bgColorButton_colorPicked(QColor color); - /// Adds a light above the scene. + /// @brief Adds a light above the scene. void on_lightAboveBox_clicked(); - /// Adds a light below the scene. + /// @brief Adds a light below the scene. void on_lightBelowBox_clicked(); - /// Sets the given superelevation on all vis pipeline source objects + /// @brief Sets the given superelevation on all vis pipeline source objects void on_superelevationPushButton_pressed(); - /// + /// @brief void on_loadShowAllCheckBox_stateChanged(int state); + /// @brief Culls backfacing rendering primitives on all actors. + void on_cullBackfacesCheckBox_stateChanged(int state); + private: VtkVisPipeline* _vtkVisPipeline; VisualizationWidget* _visWidget; diff --git a/VtkVis/VisualizationWidget.cpp b/VtkVis/VisualizationWidget.cpp index 39c95d3cac8..7c258222682 100644 --- a/VtkVis/VisualizationWidget.cpp +++ b/VtkVis/VisualizationWidget.cpp @@ -161,6 +161,8 @@ VtkPickCallback* VisualizationWidget::vtkPickCallback() const } void VisualizationWidget::updateView() { + //QDialog box(0, Qt::WindowTitleHint); + //box.show(); vtkWidget->GetRenderWindow()->Render(); } diff --git a/VtkVis/VtkAlgorithmProperties.cpp b/VtkVis/VtkAlgorithmProperties.cpp new file mode 100644 index 00000000000..7cc79c44e24 --- /dev/null +++ b/VtkVis/VtkAlgorithmProperties.cpp @@ -0,0 +1,99 @@ +/** + * \file VtkAlgorithmProperties.cpp + * 14/02/2012 LB Initial implementation + * + * Implementation of the VtkAlgorithmProperties class + */ + +// ** INCLUDES ** +#include "VtkAlgorithmProperties.h" + +#include <vtkProperty.h> +#include <vtkTexture.h> + +#include "VtkColorLookupTable.h" +#include "XmlIO/XmlLutReader.h" + +VtkAlgorithmProperties::VtkAlgorithmProperties(QObject* parent /*= NULL*/) + : QObject(parent) +{ + _property = vtkProperty::New(); + _texture = NULL; + _scalarVisibility = true; + _algorithmUserProperties = new QMap<QString, QVariant>; + _algorithmUserVectorProperties = new QMap<QString, QList<QVariant> >; + _activeAttributeName = ""; + _removable = true; +} + +VtkAlgorithmProperties::~VtkAlgorithmProperties() +{ + _property->Delete(); + if (_texture != NULL) _texture->Delete(); + + for (std::map<QString, vtkLookupTable*>::iterator it = _lut.begin(); + it != _lut.end(); ++it) + it->second->Delete(); + delete _algorithmUserProperties; + delete _algorithmUserVectorProperties; +} + +vtkLookupTable* VtkAlgorithmProperties::GetLookupTable(const QString& array_name) +{ + std::map<QString, vtkLookupTable*>::iterator it = _lut.find(array_name); + if (it != _lut.end()) + return it->second; + else + return NULL; +} + +void VtkAlgorithmProperties::SetLookUpTable(const QString &array_name, vtkLookupTable* lut) +{ + lut->Build(); + + if (array_name.length() > 0) + { + std::map<QString, vtkLookupTable*>::iterator it = _lut.find(array_name); + if (it != _lut.end()) + { + it->second->Delete(); + _lut.erase(it); + } + _lut.insert( std::pair<QString, vtkLookupTable*>(array_name, lut) ); + _activeAttributeName = array_name; + } +} + +void VtkAlgorithmProperties::SetLookUpTable(const QString &array_name, const QString &filename) +{ + VtkColorLookupTable* colorLookupTable = XmlLutReader::readFromFile(filename); + SetLookUpTable(array_name, colorLookupTable); +} + +void VtkAlgorithmProperties::SetScalarVisibility(bool on) +{ + _scalarVisibility = on; + emit ScalarVisibilityChanged(on); +} + +QVariant VtkAlgorithmProperties::GetUserProperty(QString name) const +{ + if (this->_algorithmUserProperties->contains(name)) + return this->_algorithmUserProperties->value(name); + else + { + std::cout << "Not a valid property: " << name.toStdString() << std::endl; + return QVariant(); + } +} + +QList<QVariant> VtkAlgorithmProperties::GetUserVectorProperty(QString name) const +{ + if (this->_algorithmUserVectorProperties->contains(name)) + return this->_algorithmUserVectorProperties->value(name); + else + { + std::cout << "Not a valid property: " << name.toStdString() << std::endl; + return QList<QVariant>(); + } +} diff --git a/VtkVis/VtkAlgorithmProperties.h b/VtkVis/VtkAlgorithmProperties.h index 0536f4f6c99..56e6d3e0c37 100644 --- a/VtkVis/VtkAlgorithmProperties.h +++ b/VtkVis/VtkAlgorithmProperties.h @@ -13,10 +13,11 @@ #include <QObject> #include <QString> #include <QVariant> -#include <vtkProperty.h> -#include <vtkTexture.h> -#include "VtkColorLookupTable.h" +class vtkProperty; +class vtkTexture; +class vtkLookupTable; + #define ogsUserPropertyMacro(name,type) \ virtual void Set ## name (type _arg) \ @@ -132,131 +133,76 @@ class VtkAlgorithmProperties : public QObject public: /// Constructor (sets default values) - VtkAlgorithmProperties(QObject* parent = NULL) - : QObject(parent) - { - _property = vtkProperty::New(); - _texture = NULL; - _scalarVisibility = true; - _algorithmUserProperties = new QMap<QString, QVariant>; - _algorithmUserVectorProperties = new QMap<QString, QList<QVariant> >; - _activeAttributeName = ""; - } + VtkAlgorithmProperties(QObject* parent = NULL); - virtual ~VtkAlgorithmProperties() - { - _property->Delete(); - if (_texture != NULL) _texture->Delete(); - - for (std::map<QString, vtkLookupTable*>::iterator it = _lut.begin(); it != _lut.end(); - ++it) - it->second->Delete(); - delete _algorithmUserProperties; - delete _algorithmUserVectorProperties; - } + virtual ~VtkAlgorithmProperties(); /// @brief Returns the vtk properties vtkProperty* GetProperties() const { return _property; } /// @brief Returns a texture (if one has been assigned). vtkTexture* GetTexture() { return _texture; } + /// @brief Sets a texture for the VtkVisPipelineItem. void SetTexture(vtkTexture* t) { _texture = t; } /// @brief Returns the colour lookup table (if one has been assigned). - vtkLookupTable* GetLookupTable(const QString& array_name) - { - std::map<QString, vtkLookupTable*>::iterator it = _lut.find(array_name); - if (it != _lut.end()) return it->second; - return NULL; - } + vtkLookupTable* GetLookupTable(const QString& array_name); /// @brief Sets a colour lookup table for the given scalar array of the VtkVisPipelineItem. - void SetLookUpTable(const QString array_name, vtkLookupTable* lut) - { - if (array_name.length() > 0) - { - std::map<QString, vtkLookupTable*>::iterator it = _lut.find(array_name); - if (it != _lut.end()) it->second->Delete(); - _lut.insert( std::pair<QString, vtkLookupTable*>(array_name, lut) ); - } - } + void SetLookUpTable(const QString &array_name, vtkLookupTable* lut); /// Loads a predefined color lookup table from a file for the specified scalar array. - void SetLookUpTable(const QString &array_name, const std::string &filename) - { - VtkColorLookupTable* colorLookupTable = VtkColorLookupTable::New(); - colorLookupTable->readFromFile(filename); - colorLookupTable->setInterpolationType(VtkColorLookupTable::NONE); - colorLookupTable->Build(); - SetLookUpTable(array_name, colorLookupTable); - } + void SetLookUpTable(const QString &array_name, const QString &filename); /// @brief Returns the scalar visibility. bool GetScalarVisibility() const { return _scalarVisibility; } + /// @brief Sets the scalar visibility. - void SetScalarVisibility(bool on) - { - _scalarVisibility = on; - emit ScalarVisibilityChanged(on); - } + void SetScalarVisibility(bool on); /// @brief Returns the name. This is set to the file path if it is a source algorithm. QString GetName() const { return _name; } + /// @brief Sets the name. void SetName(QString name) { _name = name; } + /// @brief Is this algorithm removable from the pipeline (view). + bool IsRemovable() const { return _removable; } + /// @brief Returns a map of user properties. - QMap<QString, QVariant>* GetAlgorithmUserProperties() const - { + QMap<QString, QVariant>* GetAlgorithmUserProperties() const { return _algorithmUserProperties; } /// @brief Returns a map of vector user properties. - QMap<QString, QList<QVariant> >* GetAlgorithmUserVectorProperties() const - { + QMap<QString, QList<QVariant> >* GetAlgorithmUserVectorProperties() const { return _algorithmUserVectorProperties; } /// @brief Sets a user property. This should be implemented by subclasses. - virtual void SetUserProperty(QString name, QVariant value) - { + virtual void SetUserProperty(QString name, QVariant value) { (*_algorithmUserProperties)[name] = value; } /// @brief Returns the value of a user property. - QVariant GetUserProperty(QString name) const - { - if (this->_algorithmUserProperties->contains(name)) - return this->_algorithmUserProperties->value(name); - else - { - std::cout << "Not a valid property: " << name.toStdString() << std::endl; - return QVariant(); - } - } + QVariant GetUserProperty(QString name) const; /// @brief Sets a vector user property. This should be implemented by subclasses. - virtual void SetUserVectorProperty(QString name, QList<QVariant> values) - { + virtual void SetUserVectorProperty(QString name, QList<QVariant> values) { (*_algorithmUserVectorProperties)[name] = values; } /// @brief Returns a list of values of a vector user property. - QList<QVariant> GetUserVectorProperty(QString name) const - { - if (this->_algorithmUserVectorProperties->contains(name)) - return this->_algorithmUserVectorProperties->value(name); - else - { - std::cout << "Not a valid property: " << name.toStdString() << std::endl; - return QList<QVariant>(); - } - } + QList<QVariant> GetUserVectorProperty(QString name) const; + + /// @brief Set the active attribute + void SetActiveAttribute(QString name) { _activeAttributeName = name; } /// @brief Returns the desired active attribute. QString GetActiveAttribute() const { return _activeAttributeName; } + protected: // Properties set on vtkActor @@ -270,6 +216,7 @@ protected: // Properties used in the GUI QString _name; QString _activeAttributeName; + bool _removable; QMap<QString, QVariant>* _algorithmUserProperties; QMap<QString, QList<QVariant> >* _algorithmUserVectorProperties; diff --git a/VtkVis/VtkApplyColorTableFilter.cpp b/VtkVis/VtkApplyColorTableFilter.cpp deleted file mode 100644 index 1f95f304671..00000000000 --- a/VtkVis/VtkApplyColorTableFilter.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/** - * \file VtkApplyColorTableFilter.cpp - * 21/10/2010 KR Initial implementation - * - */ - -// ** VTK INCLUDES ** -#include "vtkObjectFactory.h" -#include <vtkCellData.h> -#include <vtkInformation.h> -#include <vtkInformationVector.h> -#include <vtkLookupTable.h> -#include <vtkPointData.h> -#include <vtkPolyData.h> -#include <vtkSmartPointer.h> -#include <vtkStreamingDemandDrivenPipeline.h> - -#include "VtkApplyColorTableFilter.h" - -vtkStandardNewMacro(VtkApplyColorTableFilter); -vtkCxxSetObjectMacro(VtkApplyColorTableFilter, ColorLookupTable, vtkLookupTable); -vtkCxxRevisionMacro(VtkApplyColorTableFilter, "$Revision: 6575 $"); - -VtkApplyColorTableFilter::VtkApplyColorTableFilter() : ColorLookupTable(NULL) -{ - this->SetColorsOnCells(false); -} - -VtkApplyColorTableFilter::~VtkApplyColorTableFilter() -{ -} - -int VtkApplyColorTableFilter::RequestData( vtkInformation* request, - vtkInformationVector** inputVector, - vtkInformationVector* outputVector ) -{ - if (this->ColorLookupTable == NULL) - return 0; - - (void)request; - - vtkInformation* inInfo = inputVector[0]->GetInformationObject(0); - vtkPolyData* input = vtkPolyData::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT())); - - vtkSmartPointer<vtkUnsignedCharArray> colorTable = this->ColorLookupTable->GetTable(); - vtkSmartPointer<vtkUnsignedCharArray> colorArray = - vtkSmartPointer<vtkUnsignedCharArray>::New(); - colorArray->SetNumberOfComponents(4); - colorArray->SetName("Colors"); - vtkSmartPointer<vtkUnsignedCharArray> scalars = - (!ColorsOnCells) ? vtkUnsignedCharArray::SafeDownCast( - input->GetPointData()->GetScalars()) - : vtkUnsignedCharArray::SafeDownCast(input->GetCellData()->GetScalars()); - int limit = (!ColorsOnCells) ? input->GetNumberOfPoints() : input->GetNumberOfCells(); - - for (int i = 0; i < limit; i++) - { - double* value = scalars->GetTuple(i); - unsigned char* rgba = new unsigned char[4]; - colorTable->GetTupleValue(static_cast<int>(value[0]), rgba); - colorArray->InsertNextTupleValue(rgba); - } - - vtkInformation* outInfo = outputVector->GetInformationObject(0); - vtkPolyData* output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); - output->CopyStructure(input); - output->GetPointData()->PassData(input->GetPointData()); - output->GetCellData()->PassData(input->GetCellData()); - if (!ColorsOnCells) - { - output->GetPointData()->AddArray(colorArray); - output->GetPointData()->SetActiveScalars("Colors"); - } - else - { - output->GetCellData()->AddArray(colorArray); - output->GetCellData()->SetActiveScalars("Colors"); - } - - this->ColorLookupTable->Build(); - - return 1; -} - -unsigned long VtkApplyColorTableFilter::GetMTime() -{ - unsigned long t1, t2; - - t1 = this->Superclass::GetMTime(); - if (this->ColorLookupTable) - { - t2 = this->ColorLookupTable->GetMTime(); - if (t2 > t1) - t1 = t2; - } - return t1; -} - -void VtkApplyColorTableFilter::PrintSelf( ostream& os, vtkIndent indent ) -{ - this->Superclass::PrintSelf(os, indent); - os << indent << "ColorsOnCells: " << this->ColorsOnCells << "\n"; - ColorLookupTable->PrintSelf(os, indent); -} diff --git a/VtkVis/VtkApplyColorTableFilter.h b/VtkVis/VtkApplyColorTableFilter.h deleted file mode 100644 index 0306842daa3..00000000000 --- a/VtkVis/VtkApplyColorTableFilter.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * \file VtkApplyColorTableFilter.h - * 21/10/2010 KR Initial implementation - * - */ - -#ifndef VTKAPPLYCOLORTABLEFILTER_H -#define VTKAPPLYCOLORTABLEFILTER_H - -// ** INCLUDES ** -#include "VtkAlgorithmProperties.h" -#include <vtkLookupTable.h> -#include <vtkPolyDataAlgorithm.h> - -/** - * \brief Applying a color table to a vtk object. - */ -class VtkApplyColorTableFilter : public vtkPolyDataAlgorithm, public VtkAlgorithmProperties -{ -public: - /// Create new objects with New() because of VTKs object reference counting. - static VtkApplyColorTableFilter* New(); - - vtkTypeRevisionMacro(VtkApplyColorTableFilter, vtkPolyDataAlgorithm); - - /// @brief Prints information about itself. - void PrintSelf(ostream& os, vtkIndent indent); - - /// Returns the underlying colour look up table object. - vtkGetObjectMacro(ColorLookupTable,vtkLookupTable); - - /// Sets the underlying colour look up table object. - virtual void SetColorLookupTable(vtkLookupTable*); - - /// @brief Colors the whole cell instead of interpolating colors between - /// the points in a cell. - ogsUserPropertyMacro(ColorsOnCells,bool); - - //void SetColorsOnPointsOn() { _colorsOnPoints = true; }; - //void SetColorsOnCellsOn() { _colorsOnPoints = false; }; - - virtual unsigned long GetMTime(); - - virtual void SetUserProperty(QString name, QVariant value) - { - if (name.compare("ColorsOnCells") == 0) - SetColorsOnCells(value.toBool()); - } - -protected: - VtkApplyColorTableFilter(); - ~VtkApplyColorTableFilter(); - - /// Computes the unstructured grid data object. - int RequestData(vtkInformation* request, - vtkInformationVector** inputVector, - vtkInformationVector* outputVector); - -private: - vtkLookupTable* ColorLookupTable; - //bool _colorsOnPoints; -}; - -#endif // VTKAPPLYCOLORTABLEFILTER_H diff --git a/VtkVis/VtkBGImageSource.cpp b/VtkVis/VtkBGImageSource.cpp index 4f5cd20bce8..4755c9445ca 100644 --- a/VtkVis/VtkBGImageSource.cpp +++ b/VtkVis/VtkBGImageSource.cpp @@ -8,15 +8,17 @@ #include "VtkBGImageSource.h" #include "VtkVisHelper.h" -#include <QImage> - -#include "vtkObjectFactory.h" +#include <vtkImageAlgorithm.h> +#include <vtkObjectFactory.h> #include <vtkInformation.h> #include <vtkInformationVector.h> #include <vtkPlaneSource.h> #include <vtkSmartPointer.h> #include <vtkStreamingDemandDrivenPipeline.h> #include <vtkTexture.h> +#include <vtkImageData.h> +#include <vtkPointData.h> +#include <vtkImageShiftScale.h> vtkStandardNewMacro(VtkBGImageSource); vtkCxxRevisionMacro(VtkBGImageSource, "$Revision$"); @@ -29,19 +31,36 @@ VtkBGImageSource::~VtkBGImageSource() { } -void VtkBGImageSource::SetImage(vtkTexture* texture) +void VtkBGImageSource::SetRaster(vtkImageAlgorithm *img, double x0, double y0, double scalingFactor) { + double range[2]; + img->Update(); + img->GetOutput()->GetPointData()->GetScalars()->GetRange(range); + vtkSmartPointer<vtkImageShiftScale> scale = vtkSmartPointer<vtkImageShiftScale>::New(); + scale->SetInputConnection(img->GetOutputPort()); + scale->SetShift(-range[0]); + scale->SetScale(255.0/(range[1]-range[0])); + scale->SetOutputScalarTypeToUnsignedChar(); + scale->Update(); + + vtkImageData* imageData = scale->GetOutput(); + int dims[3]; + imageData->GetDimensions(dims); + vtkTexture* texture = vtkTexture::New(); + texture->InterpolateOff(); + texture->RepeatOff(); + // texture->EdgeClampOn(); // does not work + texture->SetInput(imageData); this->SetTexture(texture); -} -void VtkBGImageSource::SetRaster(QImage &img) -{ - vtkTexture* texture = VtkVisHelper::QImageToVtkTexture(img); + _origin = std::pair<float, float>(static_cast<float>(x0), static_cast<float>(y0)); + _cellsize = scalingFactor; + vtkSmartPointer<vtkPlaneSource> plane = vtkSmartPointer<vtkPlaneSource>::New(); plane->SetOrigin( _origin.first, _origin.second, -1 ); - plane->SetPoint1( _origin.first + img.width() * _cellsize, _origin.second, -1 ); - plane->SetPoint2( _origin.first,_origin.second + img.height() * _cellsize, -1 ); + plane->SetPoint1( _origin.first + dims[0] * _cellsize, _origin.second, -1 ); + plane->SetPoint2( _origin.first,_origin.second + dims[1] * _cellsize, -1 ); this->SetInputConnection(0, plane->GetOutputPort(0)); this->SetTexture(texture); diff --git a/VtkVis/VtkBGImageSource.h b/VtkVis/VtkBGImageSource.h index 8767b426008..336b55c07cc 100644 --- a/VtkVis/VtkBGImageSource.h +++ b/VtkVis/VtkBGImageSource.h @@ -12,7 +12,7 @@ #include "VtkAlgorithmProperties.h" -class QImage; +class vtkImageAlgorithm; /** * \brief Uses an image source to create a plane in the 3D with the given @@ -26,21 +26,8 @@ public: vtkTypeRevisionMacro(VtkBGImageSource, vtkTextureMapToPlane); - /// Sets the surfaces vector - void SetImage(vtkTexture* texture); - - /// Sets the cellsize (i.e. the actual dimension of a pixel) - void SetCellSize(double c) { _cellsize = c; } - /// Sets the raster/image to be used as a texture map - void SetRaster(QImage &img); - - /// Sets the geo-referenced origin of the image (i.e. the lower left corner) - virtual void SetOrigin(double x, double y, double z = 0.0) { _origin.first = x; - _origin.second = y; - (void)z; } - virtual void SetOrigin(double* pos) { _origin.first = pos[0]; - _origin.second = pos[1]; } + void SetRaster(vtkImageAlgorithm *img, double x0, double y0, double scalingFactor); virtual void SetUserProperty(QString name, QVariant value); diff --git a/VtkVis/VtkColorLookupTable.cpp b/VtkVis/VtkColorLookupTable.cpp index 42ff65f7027..6ec612ca6c9 100644 --- a/VtkVis/VtkColorLookupTable.cpp +++ b/VtkVis/VtkColorLookupTable.cpp @@ -16,7 +16,6 @@ vtkCxxRevisionMacro(VtkColorLookupTable, "$Revision$"); VtkColorLookupTable::VtkColorLookupTable() : _type(VtkColorLookupTable::LINEAR) { - this->SetNumberOfTableValues(256); } VtkColorLookupTable::~VtkColorLookupTable() @@ -43,67 +42,38 @@ unsigned char VtkColorLookupTable::expInterpolation(unsigned char a, void VtkColorLookupTable::Build() { + double range[2]; + this->GetTableRange(range); + const double interval = range[1]-range[0]; + this->SetNumberOfTableValues(ceil(interval)+1); +// const vtkIdType nColours = this->GetNumberOfTableValues(); if (!_dict.empty()) { // make sure that color map starts with the first color in the dictionary - unsigned char* startcolor = new unsigned char[4]; - startcolor[0] = _dict.begin()->second[0]; - startcolor[1] = _dict.begin()->second[1]; - startcolor[2] = _dict.begin()->second[2]; - startcolor[3] = _dict.begin()->second[3]; + unsigned char startcolor[4] = { 0, 0 , 0 , 0 }; std::pair<size_t, unsigned char*> lastValue(0, startcolor); size_t nextIndex(0); - // make sure that color map ends with the last color in the dictionary - std::map<double, unsigned char*>::iterator lastitr = _dict.end(); - --lastitr; - if (lastitr->first != 1) + for (std::map<double, unsigned char*>::const_iterator it = _dict.begin(); it != _dict.end(); ++it) { - unsigned char* lastcolor = new unsigned char[4]; - for (size_t i = 0; i < 4; i++) - lastcolor[i] = lastitr->second[i]; - _dict.insert( std::pair<double, unsigned char*>(1.0, lastcolor) ); - } - - for (std::map<double, unsigned char*>::const_iterator it = _dict.begin(); - it != _dict.end(); ++it) - { - //unsigned char rgba[4]; - //rgba[0] = (*it->second)[0]; rgba[1] = (*it->second)[1]; rgba[2] = (*it->second)[2]; rgba[3] = 255; + double val = (it->first < range[0]) ? range[0] : ((it->first > range[1]) ? range[1] : it->first); + nextIndex = static_cast<size_t>( floor(val-range[0]) ); - nextIndex = - static_cast<size_t>( floor(it->first * this->GetNumberOfTableValues()) ); - if (nextIndex >= static_cast<size_t>(this->GetNumberOfTableValues())) - nextIndex--; // this happens for the very last colour this->SetTableValue(nextIndex, it->second); - if ( nextIndex - lastValue.first > 1 ) + if ( nextIndex - lastValue.first > 0 ) for (size_t i = lastValue.first + 1; i < nextIndex; i++) { unsigned char int_rgba[4]; - int_rgba[3] = 255; - double pos = - (i - - lastValue.first) / - (static_cast<double>(nextIndex - lastValue.first)); + double pos = (i - lastValue.first) / (static_cast<double>(nextIndex - lastValue.first)); if (_type == VtkColorLookupTable::LINEAR) for (size_t j = 0; j < 3; j++) - int_rgba[j] = - linInterpolation( - (lastValue.second)[j], - (it->second)[j], - pos); + int_rgba[j] = linInterpolation( (lastValue.second)[j], (it->second)[j], pos); else if (_type == VtkColorLookupTable::EXPONENTIAL) for (size_t j = 0; j < 3; j++) - int_rgba[j] = - expInterpolation( - (lastValue.second)[j], - (it->second)[j], - 0.2, - pos); + int_rgba[j] = expInterpolation((lastValue.second)[j], (it->second)[j], 0.2, pos); else // no interpolation - for (size_t j = 0; j < 3; j++) int_rgba[j] = (lastValue.second)[j]; @@ -118,19 +88,6 @@ void VtkColorLookupTable::Build() vtkLookupTable::Build(); } -void VtkColorLookupTable::readFromFile(const std::string &filename) -{ - std::map<std::string, GEOLIB::Color*> colors; - GEOLIB::readColorLookupTable(colors, filename); - this->SetNumberOfTableValues(colors.size()); - - for (std::map<std::string, GEOLIB::Color*>::iterator it = colors.begin(); it != colors.end(); - ++it) - this->SetTableValue( static_cast<vtkIdType>(strtod( it->first.c_str(), - 0 )), (*(it->second))[0], - (*(it->second))[1], (*(it->second))[2], 255 ); -} - void VtkColorLookupTable::writeToFile(const std::string &filename) { std::cout << "Writing color table to " << filename << "...."; @@ -196,31 +153,21 @@ void VtkColorLookupTable::GetTableValue(vtkIdType indx, unsigned char rgba[4]) void VtkColorLookupTable::setColor(double pos, unsigned char rgba[4]) { - if (pos >= 0 && pos <= 1) - { - unsigned char* dict_rgba = new unsigned char[4]; - for (size_t i = 0; i < 4; i++) - dict_rgba[i] = rgba[i]; - _dict.insert( std::pair<double, unsigned char*>(pos, dict_rgba) ); - } - else - std::cout << "ColorLookupTable::setValue() - Error: pos should be in [0,1]" << - std::endl; + unsigned char* dict_rgba = new unsigned char[4]; + for (size_t i = 0; i < 4; i++) + dict_rgba[i] = rgba[i]; + _dict.insert( std::pair<double, unsigned char*>(pos, dict_rgba) ); } void VtkColorLookupTable::getColor(vtkIdType indx, unsigned char rgba[4]) const { indx = - ((indx < - this->TableRange[0]) ? static_cast<vtkIdType>(this->TableRange[0]) : (indx >= - this - -> - TableRange[1] ? static_cast<vtkIdType>(this->TableRange[1]) - 1 : indx)); + ((indx < this->TableRange[0]) + ? static_cast<vtkIdType>(this->TableRange[0]) + : (indx >=this->TableRange[1] ? static_cast<vtkIdType>(this->TableRange[1]) - 1 : indx)); indx = - static_cast<size_t>( floor( (indx - - this->TableRange[0]) * - (this->NumberOfColors / - (this->TableRange[1] - this->TableRange[0])) ) ); + static_cast<size_t>( floor( (indx - this->TableRange[0]) * + (this->NumberOfColors / (this->TableRange[1] - this->TableRange[0])) ) ); unsigned char* _rgba; _rgba = this->Table->GetPointer(indx * 4); diff --git a/VtkVis/VtkColorLookupTable.h b/VtkVis/VtkColorLookupTable.h index 15b66d3b11d..fd0d35c00a0 100644 --- a/VtkVis/VtkColorLookupTable.h +++ b/VtkVis/VtkColorLookupTable.h @@ -65,7 +65,7 @@ public: void setInterpolationType(VtkColorLookupTable::LUTType type) { _type = type; } /// Imports a color table from a file. - void readFromFile(const std::string &filename); + //void readFromFile(const std::string &filename); /// Exports a color table to a file. void writeToFile(const std::string &filename); diff --git a/VtkVis/VtkCompositeColorByHeightFilter.cpp b/VtkVis/VtkCompositeColorByHeightFilter.cpp index a4e0457f2a6..bde566997cc 100644 --- a/VtkVis/VtkCompositeColorByHeightFilter.cpp +++ b/VtkVis/VtkCompositeColorByHeightFilter.cpp @@ -44,10 +44,10 @@ void VtkCompositeColorByHeightFilter::init() unsigned char c[4] = { 255, 255, 0, 255 }; // yellow unsigned char d[4] = { 255, 0, 0, 255 }; // red //unsigned char e[4] = { 255, 255, 255, 255 }; // white - heightFilter->GetColorLookupTable()->setColor(0.0, a); - heightFilter->GetColorLookupTable()->setColor(0.2, b); // green at about 150m - heightFilter->GetColorLookupTable()->setColor(0.6, c); // yellow at about 450m and changing to red from then on - heightFilter->GetColorLookupTable()->setColor(1.0, d); + heightFilter->GetColorLookupTable()->setColor(-35, a); + heightFilter->GetColorLookupTable()->setColor(150, b); // green at about 150m + heightFilter->GetColorLookupTable()->setColor(450, c); // yellow at about 450m and changing to red from then on + heightFilter->GetColorLookupTable()->setColor(800, d); //heightFilter->GetColorLookupTable()->setColor(1.0, e); heightFilter->Update(); diff --git a/VtkVis/VtkCompositeColormapToImageFilter.cpp b/VtkVis/VtkCompositeColormapToImageFilter.cpp index 72a3c55bef7..6eace8d14c2 100644 --- a/VtkVis/VtkCompositeColormapToImageFilter.cpp +++ b/VtkVis/VtkCompositeColormapToImageFilter.cpp @@ -9,9 +9,17 @@ #include "VtkCompositeColormapToImageFilter.h" #include <vtkImageMapToColors.h> +#include <vtkImageData.h> #include <vtkLookupTable.h> +#include <vtkPointData.h> #include <vtkSmartPointer.h> +#include <QSettings> +#include <QFileDialog> + +#include "VtkColorLookupTable.h" +#include "XmlIO/XmlLutReader.h" + VtkCompositeColormapToImageFilter::VtkCompositeColormapToImageFilter( vtkAlgorithm* inputAlgorithm ) : VtkCompositeFilter(inputAlgorithm) { @@ -27,13 +35,36 @@ void VtkCompositeColormapToImageFilter::init() this->_inputDataObjectType = VTK_IMAGE_DATA; this->_outputDataObjectType = VTK_IMAGE_DATA; - vtkSmartPointer<vtkLookupTable> colormap = vtkSmartPointer<vtkLookupTable>::New(); - colormap->SetTableRange(0, 100); - colormap->SetHueRange(0.0, 0.666); + vtkSmartPointer<VtkColorLookupTable> colormap; + + QWidget* parent = 0; + QSettings settings("UFZ", "OpenGeoSys-5"); + QString fileName = QFileDialog::getOpenFileName(parent, + "Select color lookup table", + settings.value("lastOpenedLookupTableFileDirectory"). + toString(), + "Lookup table XML files (*.xml);;"); + double range[2]; + dynamic_cast<vtkImageAlgorithm*>(_inputAlgorithm)->GetOutput()->GetPointData()->GetScalars()->GetRange(range); + + if (!fileName.length()==0) + { + colormap = XmlLutReader::readFromFile(fileName); + settings.setValue("lastOpenedLookupTableFileDirectory", fileName); + } + else + { + colormap = vtkSmartPointer<VtkColorLookupTable>::New(); + colormap->SetTableRange(range[0], range[1]); + colormap->SetHueRange(0.0, 0.666); + } colormap->SetNumberOfTableValues(256); + colormap->Build(); + + colormap->GetTableRange(range); QList<QVariant> tableRangeList; - tableRangeList.push_back(0); - tableRangeList.push_back(100); + tableRangeList.push_back(range[0]); + tableRangeList.push_back(range[1]); QList<QVariant> hueRangeList; hueRangeList.push_back(0.0); hueRangeList.push_back(0.666); @@ -58,8 +89,7 @@ void VtkCompositeColormapToImageFilter::SetUserProperty( QString name, QVariant if (name.compare("PassAlphaToOutput") == 0) map->SetPassAlphaToOutput(value.toBool()); else if (name.compare("NumberOfColors") == 0) - static_cast<vtkLookupTable*>(map->GetLookupTable())->SetNumberOfTableValues( - value.toInt()); + static_cast<vtkLookupTable*>(map->GetLookupTable())->SetNumberOfTableValues(value.toInt()); } void VtkCompositeColormapToImageFilter::SetUserVectorProperty( QString name, QList<QVariant> values ) @@ -71,7 +101,6 @@ void VtkCompositeColormapToImageFilter::SetUserVectorProperty( QString name, QLi static_cast<vtkLookupTable*>(map->GetLookupTable())->SetTableRange( values[0].toInt(), values[1].toInt()); else if (name.compare("HueRange") == 0) - static_cast<vtkLookupTable*>(map->GetLookupTable())->SetHueRange(values[0].toDouble( - ), - values[1].toDouble()); + static_cast<vtkLookupTable*>(map->GetLookupTable())->SetHueRange(values[0].toDouble(), + values[1].toDouble()); } diff --git a/VtkVis/VtkCompositeContourFilter.cpp b/VtkVis/VtkCompositeContourFilter.cpp index 2aeba6dbc7b..399a227dea4 100644 --- a/VtkVis/VtkCompositeContourFilter.cpp +++ b/VtkVis/VtkCompositeContourFilter.cpp @@ -11,6 +11,8 @@ #include <vtkSmartPointer.h> #include <vtkUnstructuredGrid.h> +#include <limits> + VtkCompositeContourFilter::VtkCompositeContourFilter( vtkAlgorithm* inputAlgorithm ) : VtkCompositeFilter(inputAlgorithm) { @@ -31,14 +33,19 @@ void VtkCompositeContourFilter::init() vtkContourFilter* contour = vtkContourFilter::New(); contour->SetInputConnection(_inputAlgorithm->GetOutputPort()); + // Setting the threshold to min / max values to ensure that the whole data + // is first processed. This is needed for correct lookup table generation. + const double dMin = std::numeric_limits<double>::min(); + const double dMax = std::numeric_limits<double>::max(); + // Sets a filter vector property which will be user editable - contour->GenerateValues(10, 0, 100); + contour->GenerateValues(10, dMin, dMax); // Create a list for the ThresholdBetween (vector) property. QList<QVariant> contourRangeList; // Insert the values (same values as above) - contourRangeList.push_back(0); - contourRangeList.push_back(100); + contourRangeList.push_back(dMin); + contourRangeList.push_back(dMax); // Put that list in the property map (*_algorithmUserVectorProperties)["Range"] = contourRangeList; diff --git a/VtkVis/VtkCompositeContourFilter.h b/VtkVis/VtkCompositeContourFilter.h index e3810de045b..9ec22dacaaf 100644 --- a/VtkVis/VtkCompositeContourFilter.h +++ b/VtkVis/VtkCompositeContourFilter.h @@ -9,6 +9,8 @@ #include "VtkCompositeFilter.h" /// @brief Visualisation of contour-lines/-planes within dense scalar fields. +/// In init() the threshold is first set to double min / max values. Set the +/// threshold later on via SetUserVectorProperty() to the actual data range. class VtkCompositeContourFilter : public VtkCompositeFilter { public: diff --git a/VtkVis/VtkCompositeFilter.cpp b/VtkVis/VtkCompositeFilter.cpp index 22cdf0ef9c4..b650f8eede0 100644 --- a/VtkVis/VtkCompositeFilter.cpp +++ b/VtkVis/VtkCompositeFilter.cpp @@ -8,7 +8,7 @@ // ** INCLUDES ** #include "VtkCompositeFilter.h" -#include "VtkCompositeImageToCylindersFilter.h" +#include <vtkAlgorithm.h> #include <QMapIterator> #include <QString> diff --git a/VtkVis/VtkCompositeFilter.h b/VtkVis/VtkCompositeFilter.h index 460b81e80de..a83e098b167 100644 --- a/VtkVis/VtkCompositeFilter.h +++ b/VtkVis/VtkCompositeFilter.h @@ -8,6 +8,8 @@ #include "VtkAlgorithmProperties.h" +class vtkAlgorithm; + /// @brief Is used to combine several filter in one VtkVisPipelineItem. You can /// use vtk filter and custom filter. To subclass this you have to implement the /// init() function. There you combine the filters. Make sure to set the members diff --git a/VtkVis/VtkCompositeImageToCylindersFilter.cpp b/VtkVis/VtkCompositeImageToCylindersFilter.cpp index 5cd54c57ff2..f482ffbe622 100644 --- a/VtkVis/VtkCompositeImageToCylindersFilter.cpp +++ b/VtkVis/VtkCompositeImageToCylindersFilter.cpp @@ -8,7 +8,6 @@ // ** INCLUDES ** #include "VtkCompositeImageToCylindersFilter.h" -#include "VtkApplyColorTableFilter.h" #include "VtkImageDataToLinePolyDataFilter.h" #include <vtkLookupTable.h> @@ -35,37 +34,33 @@ void VtkCompositeImageToCylindersFilter::init() this->_outputDataObjectType = VTK_POLY_DATA; _lineFilter = VtkImageDataToLinePolyDataFilter::New(); - //lineFilter = VtkImageDataToLinePolyDataFilter::New(); _lineFilter->SetInputConnection(_inputAlgorithm->GetOutputPort()); _lineFilter->SetLengthScaleFactor(1); (*_algorithmUserProperties)["LengthScaleFactor"] = 1.0; _lineFilter->Update(); - //vtkPointData* pointData = _lineFilter->GetOutput()->GetPointData(); - //pointData->GetArray(0)->SetName("Colors"); + double range[2]; + // The data is always on points + vtkDataSet::SafeDownCast(_lineFilter->GetOutputDataObject(0))->GetPointData()->GetScalars()->GetRange(range); - vtkSmartPointer<vtkLookupTable> colormap = vtkSmartPointer<vtkLookupTable>::New(); - colormap->SetTableRange(0, 100); + vtkLookupTable* colormap = vtkLookupTable::New(); + colormap->SetTableRange(range[0], range[1]); colormap->SetHueRange(0.0, 0.666); colormap->SetNumberOfTableValues(256); colormap->ForceBuild(); QList<QVariant> tableRangeList; - tableRangeList.push_back(0); - tableRangeList.push_back(100); + tableRangeList.push_back(range[0]); + tableRangeList.push_back(range[1]); QList<QVariant> hueRangeList; hueRangeList.push_back(0.0); hueRangeList.push_back(0.666); (*_algorithmUserVectorProperties)["TableRange"] = tableRangeList; (*_algorithmUserVectorProperties)["HueRange"] = hueRangeList; - this->SetLookUpTable("Colours", colormap); - - _ctf = VtkApplyColorTableFilter::New(); - _ctf->SetInputConnection(_lineFilter->GetOutputPort()); - _ctf->SetColorLookupTable(colormap); + this->SetLookUpTable("P-Colors", colormap); vtkTubeFilter* tubeFilter = vtkTubeFilter::New(); - tubeFilter->SetInputConnection(_ctf->GetOutputPort()); + tubeFilter->SetInputConnection(_lineFilter->GetOutputPort()); tubeFilter->CappingOn(); tubeFilter->SetNumberOfSides(6); tubeFilter->SetRadius(_lineFilter->GetImageSpacing() * 0.25); @@ -86,8 +81,11 @@ void VtkCompositeImageToCylindersFilter::SetUserProperty( QString name, QVariant // VtkImageDataToLinePolyDataFilter is equal to _firstAlgorithm // vtkTubeFilter is equal _outputAlgorithm if (name.compare("NumberOfColors") == 0) - static_cast<vtkLookupTable*>(_ctf->GetColorLookupTable())->SetNumberOfTableValues( - value.toInt()); + { + vtkLookupTable* lut = this->GetLookupTable("P-Colors"); + if(lut) + lut->SetNumberOfTableValues(value.toInt()); + } else if (name.compare("NumberOfSides") == 0) static_cast<vtkTubeFilter*>(_outputAlgorithm)->SetNumberOfSides(value.toInt()); else if (name.compare("Capping") == 0) @@ -105,17 +103,20 @@ void VtkCompositeImageToCylindersFilter::SetUserVectorProperty( QString name, _lineFilter->SetUserVectorProperty(name, values); if (name.compare("TableRange") == 0) - static_cast<vtkLookupTable*>(_ctf->GetColorLookupTable())->SetTableRange( - values[0].toInt(), - values[1].toInt()); + { + vtkLookupTable* lut = this->GetLookupTable("P-Colors"); + if(lut) + lut->SetTableRange(values[0].toDouble(), values[1].toDouble()); + } else if (name.compare("HueRange") == 0) - static_cast<vtkLookupTable*>(_ctf->GetColorLookupTable())->SetHueRange( - values[0].toDouble(), - values[1].toDouble()); + { + vtkLookupTable* lut = this->GetLookupTable("P-Colors"); + if(lut) + lut->SetHueRange(values[0].toDouble(), values[1].toDouble()); + } } VtkCompositeImageToCylindersFilter::~VtkCompositeImageToCylindersFilter() { _lineFilter->Delete(); - _ctf->Delete(); } diff --git a/VtkVis/VtkCompositeImageToCylindersFilter.h b/VtkVis/VtkCompositeImageToCylindersFilter.h index 0bb4e65b50a..b696fee158d 100644 --- a/VtkVis/VtkCompositeImageToCylindersFilter.h +++ b/VtkVis/VtkCompositeImageToCylindersFilter.h @@ -9,7 +9,6 @@ #include "VtkCompositeFilter.h" class VtkImageDataToLinePolyDataFilter; -class VtkApplyColorTableFilter; /// @brief Creates cylinders that stand on top of the image with the length /// of the corresponding first sub-pixel value (the red value). Useful to @@ -28,7 +27,6 @@ public: private: VtkImageDataToLinePolyDataFilter* _lineFilter; - VtkApplyColorTableFilter* _ctf; }; #endif // VTKCOMPOSITEIMAGETOCYLINDERSFILTER_H diff --git a/VtkVis/VtkCompositeLineToTubeFilter.cpp b/VtkVis/VtkCompositeLineToTubeFilter.cpp index 971d4ab38b1..8eb9efa1d98 100644 --- a/VtkVis/VtkCompositeLineToTubeFilter.cpp +++ b/VtkVis/VtkCompositeLineToTubeFilter.cpp @@ -37,11 +37,14 @@ void VtkCompositeLineToTubeFilter::init() int default_number_of_sides(8); vtkTubeFilter* tubes = vtkTubeFilter::New(); tubes->SetInputConnection(0, mergePoints->GetOutputPort(0)); + + //tubes->SetInputArrayToProcess(1,0,0,vtkDataObject::FIELD_ASSOCIATION_CELLS,"StationValue"); + //tubes->SetVaryRadiusToVaryRadiusByScalar(); // KR radius changes with scalar + tubes->SetInputArrayToProcess(1,0,0,vtkDataObject::FIELD_ASSOCIATION_CELLS,"Stratigraphies"); tubes->SetRadius(default_radius); tubes->SetNumberOfSides(default_number_of_sides); tubes->SetCapping(1); - //tubes->SetVaryRadiusToVaryRadiusByScalar(); // KR radius changes with scalar (*_algorithmUserProperties)["Radius"] = default_radius; (*_algorithmUserProperties)["NumberOfSides"] = default_number_of_sides; diff --git a/VtkVis/VtkCompositePointToGlyphFilter.cpp b/VtkVis/VtkCompositePointToGlyphFilter.cpp index 10f9e3bf83e..7a520ab5177 100644 --- a/VtkVis/VtkCompositePointToGlyphFilter.cpp +++ b/VtkVis/VtkCompositePointToGlyphFilter.cpp @@ -57,7 +57,7 @@ void VtkCompositePointToGlyphFilter::init() glyphFilter->SetSource(_glyphSource->GetOutput()); glyphFilter->SetInputConnection(_inputAlgorithm->GetOutputPort()); //(*_algorithmUserProperties)["ScaleMode"] = 0; - (*_algorithmUserProperties)["ScaleFactor"] = 1.0; + //(*_algorithmUserProperties)["ScaleFactor"] = 1.0; //(*_algorithmUserProperties)["ColorMode"] = glyphFilter->GetColorMode(); //(*_algorithmUserProperties)["VectorMode"] = glyphFilter->GetVectorMode(); //(*_algorithmUserProperties)["Orient"] = glyphFilter->GetOrient(); diff --git a/VtkVis/VtkCompositeSelectionFilter.cpp b/VtkVis/VtkCompositeSelectionFilter.cpp index 21d20f3e6b6..9d902bc8262 100644 --- a/VtkVis/VtkCompositeSelectionFilter.cpp +++ b/VtkVis/VtkCompositeSelectionFilter.cpp @@ -8,6 +8,7 @@ // ** INCLUDES ** #include "VtkCompositeSelectionFilter.h" #include "VtkSelectionFilter.h" +#include "VtkColorLookupTable.h" #include <vtkDataSetSurfaceFilter.h> #include <vtkSmartPointer.h> diff --git a/VtkVis/VtkCompositeSelectionFilter.h b/VtkVis/VtkCompositeSelectionFilter.h index 45a33409e43..ff76d6df863 100644 --- a/VtkVis/VtkCompositeSelectionFilter.h +++ b/VtkVis/VtkCompositeSelectionFilter.h @@ -8,6 +8,10 @@ #include "VtkCompositeFilter.h" +#include <vector> + +class VtkColorLookupTable; + /// @brief This filter colors the input by the points z-value. class VtkCompositeSelectionFilter : public VtkCompositeFilter { diff --git a/VtkVis/VtkCompositeTextureOnSurfaceFilter.cpp b/VtkVis/VtkCompositeTextureOnSurfaceFilter.cpp index 44d27b7537d..30b79d59b94 100644 --- a/VtkVis/VtkCompositeTextureOnSurfaceFilter.cpp +++ b/VtkVis/VtkCompositeTextureOnSurfaceFilter.cpp @@ -11,13 +11,17 @@ #include <vtkDataSetSurfaceFilter.h> #include <vtkSmartPointer.h> #include <vtkUnstructuredGrid.h> - -#include "OGSRaster.h" +#include "VtkGeoImageSource.h" +#include "VtkRaster.h" +#include "NetCdfConfigureDialog.h" #include <QFileDialog> #include <QFileInfo> #include <QSettings> +//#include "VtkCompositeColormapToImageFilter.h" + + VtkCompositeTextureOnSurfaceFilter::VtkCompositeTextureOnSurfaceFilter( vtkAlgorithm* inputAlgorithm ) : VtkCompositeFilter(inputAlgorithm) @@ -52,25 +56,41 @@ void VtkCompositeTextureOnSurfaceFilter::init() "Select raster file to apply as texture", settings.value("lastOpenedTextureFileDirectory"). toString(), - "Raster files (*.asc *.bmp *.jpg *.png *.tif);;"); + "Raster files (*.asc *.grd *.bmp *.jpg *.png *.tif);;NetCDF files (*.nc);;"); QFileInfo fi(fileName); if ((fi.suffix().toLower() == "asc") || (fi.suffix().toLower() == "tif") || - (fi.suffix().toLower() == "png") || + (fi.suffix().toLower() == "png") || (fi.suffix().toLower() == "grd") || (fi.suffix().toLower() == "jpg") || (fi.suffix().toLower() == "bmp")) { - QImage img; - QPointF origin; - double scalingFactor = 0; - - OGSRaster::loadImage(fileName, img, origin, scalingFactor); - std::pair<float, float> org(origin.x(), origin.y()); - surface->SetRaster(img, org, scalingFactor); + double x0(0), y0(0), scalingFactor(1); + std::string name = fileName.toStdString(); + vtkImageAlgorithm* image = VtkRaster::loadImage(name, x0, y0, scalingFactor); + surface->SetRaster(image, x0, y0, scalingFactor); surface->Update(); QDir dir = QDir(fileName); settings.setValue("lastOpenedTextureFileDirectory", dir.absolutePath()); } + else if (fi.suffix().toLower() == "nc") + { + NetCdfConfigureDialog dlg(fileName.toStdString().c_str()); + dlg.exec(); + if (dlg.getRaster() != NULL) + { + VtkGeoImageSource* image = dlg.getRaster(); + double origin[3]; + image->GetOutput()->GetOrigin(origin); + double spacing[3]; + image->GetOutput()->GetSpacing(spacing); +/* + VtkCompositeColormapToImageFilter* cm = new VtkCompositeColormapToImageFilter(image); + vtkImageAlgorithm* img = dynamic_cast<vtkImageAlgorithm*>(cm->GetOutputAlgorithm()); +*/ + surface->SetRaster(image, origin[0], origin[1], spacing[0]); + surface->Update(); + } + } else std::cout << "VtkCompositeTextureOnSurfaceFilter.init() - Error reading texture file..." << diff --git a/VtkVis/VtkCompositeThresholdFilter.cpp b/VtkVis/VtkCompositeThresholdFilter.cpp index ebe174ac33d..d3448d6dfc6 100644 --- a/VtkVis/VtkCompositeThresholdFilter.cpp +++ b/VtkVis/VtkCompositeThresholdFilter.cpp @@ -11,10 +11,11 @@ #include <vtkCellData.h> #include <vtkThreshold.h> #include <vtkUnstructuredGrid.h> - #include <vtkIntArray.h> #include <vtkSmartPointer.h> +#include <limits> + VtkCompositeThresholdFilter::VtkCompositeThresholdFilter( vtkAlgorithm* inputAlgorithm ) : VtkCompositeFilter(inputAlgorithm) { @@ -35,25 +36,23 @@ void VtkCompositeThresholdFilter::init() vtkThreshold* threshold = vtkThreshold::New(); threshold->SetInputConnection(_inputAlgorithm->GetOutputPort()); - // TODO: Initalisation - //vtkDataArray* activeScalar = vtkDataSet::SafeDownCast(threshold->GetInput())->GetCellData()->GetArray(0); - //threshold->SetInputArrayToProcess(0,0,0,vtkDataObject::FIELD_ASSOCIATION_CELLS, activeScalar->GetName()); - //threshold->SetComponentModeToUseSelected(); - -//double* range = threshold->GetOutput()->GetScalarRange(); -//std::cout << range[0] << ", " << range[1] << std::endl; + // Note: There is no need to select the input array because it is + // automatically selected. // Sets a filter property which will be user editable threshold->SetSelectedComponent(0); - // Sets a filter vector property which will be user editable - threshold->ThresholdBetween(0, 100); + // Setting the threshold to min / max values to ensure that the whole data + // is first processed. This is needed for correct lookup table generation. + const double dMin = std::numeric_limits<double>::min(); + const double dMax = std::numeric_limits<double>::max(); + threshold->ThresholdBetween(dMin, dMax); // Create a list for the ThresholdBetween (vector) property. QList<QVariant> thresholdRangeList; // Insert the values (same values as above) - thresholdRangeList.push_back(0); - thresholdRangeList.push_back(100); + thresholdRangeList.push_back(dMin); + thresholdRangeList.push_back(dMax); // Put that list in the property map (*_algorithmUserVectorProperties)["Threshold Between"] = thresholdRangeList; @@ -80,17 +79,7 @@ void VtkCompositeThresholdFilter::SetUserVectorProperty( QString name, QList<QVa // Use the same name as in init() if (name.compare("Threshold Between") == 0) - //double* range = dynamic_cast<vtkUnstructuredGridAlgorithm*>(_outputAlgorithm)->GetOutput()->GetScalarRange(); - //std::cout << range[0] << ", " << range[1] << std::endl; // Set the vector property on the algorithm static_cast<vtkThreshold*>(_outputAlgorithm)->ThresholdBetween( - values[0].toInt(), values[1].toInt()); + values[0].toDouble(), values[1].toDouble()); } -/* - void VtkCompositeThresholdFilter::SetScalarRangeOnItem( double min, double max ) - { - _item->SetScalarRange(min, max); - emit requestViewUpdate(); - } - - */ diff --git a/VtkVis/VtkCompositeThresholdFilter.h b/VtkVis/VtkCompositeThresholdFilter.h index 54bbc963a1f..acdfe7c460c 100644 --- a/VtkVis/VtkCompositeThresholdFilter.h +++ b/VtkVis/VtkCompositeThresholdFilter.h @@ -9,6 +9,8 @@ #include "VtkCompositeFilter.h" /// @brief Visualises only parts of meshes that are above/below/within given thresholds. +/// In init() the threshold is first set to double min / max values. Set the +/// threshold later on via SetUserVectorProperty() to the actual data range. class VtkCompositeThresholdFilter : public VtkCompositeFilter { public: diff --git a/VtkVis/VtkConditionSource.cpp b/VtkVis/VtkConditionSource.cpp index ed36f7df52c..1d26f5f595d 100644 --- a/VtkVis/VtkConditionSource.cpp +++ b/VtkVis/VtkConditionSource.cpp @@ -19,6 +19,7 @@ #include <vtkPolygon.h> #include <vtkSmartPointer.h> #include <vtkStreamingDemandDrivenPipeline.h> +#include <vtkProperty.h> #include <vtkLookupTable.h> @@ -41,6 +42,7 @@ VtkConditionSource::~VtkConditionSource() void VtkConditionSource::setData(const std::vector<GEOLIB::Point*>* points, const std::vector<FEMCondition*>* conds) { + _removable = false; // From VtkAlgorithmProperties _points = points; _cond_vec = conds; } @@ -62,17 +64,7 @@ int VtkConditionSource::RequestData( vtkInformation* request, (void)request; (void)inputVector; - if ( _points ) - { - if (_points->empty()) - { - std::cout << - "ERROR in VtkConditionSource::RequestData : Size of point vector is 0" << - std::endl; - return 0; - } - } - else + if (this->_points->empty() || this->_cond_vec->empty()) return 0; vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New(); @@ -95,7 +87,7 @@ int VtkConditionSource::RequestData( vtkInformation* request, if (outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0) return 1; - + /* size_t n_pnts = _points->size(); double value(-9999); if (!_cond_vec->empty()) @@ -111,12 +103,14 @@ int VtkConditionSource::RequestData( vtkInformation* request, distypes->InsertNextValue(0); scalars->InsertNextValue(value); } - + */ + vtkIdType pnt_id = 0; size_t nCond = _cond_vec->size(); for (size_t n = 0; n < nCond; n++) { FiniteElement::DistributionType type = (*_cond_vec)[n]->getProcessDistributionType(); - const std::vector<double> dis_values = (*_cond_vec)[n]->getDisValue(); + const std::vector<size_t> dis_nodes = (*_cond_vec)[n]->getDisNodes(); + const std::vector<double> dis_values = (*_cond_vec)[n]->getDisValues(); vtkIdType dis_type_value(0); std::map<FiniteElement::DistributionType, vtkIdType>::const_iterator it(_dis_type_map.find(type)); @@ -129,6 +123,7 @@ int VtkConditionSource::RequestData( vtkInformation* request, if ((*_cond_vec)[n]->getGeoType() == GEOLIB::POINT) { + /* size_t nPoints = _points->size(); const GEOLIB::Point* pnt = static_cast<const GEOLIB::Point*>((*_cond_vec)[n]->getGeoObj()); @@ -138,45 +133,59 @@ int VtkConditionSource::RequestData( vtkInformation* request, { id = static_cast<int>(i); //(this->getIndex(i, newPoints, scalars, idx_map)); vtkIdType vtk_id = static_cast<vtkIdType>(id); - newVerts->InsertNextCell(1, &vtk_id); - if (type == FiniteElement::CONSTANT) - scalars->SetValue(id, dis_values[0]); - distypes->SetValue(id, dis_type_value); + */ + const GEOLIB::Point* pnt = static_cast<const GEOLIB::Point*>((*_cond_vec)[n]->getGeoObj()); + newPoints->InsertNextPoint(pnt->getData()); + + newVerts->InsertNextCell(1, &pnt_id); + if (type == FiniteElement::CONSTANT || type == FiniteElement::CONSTANT_NEUMANN) + scalars->InsertNextValue(dis_values[0]); + else scalars->InsertNextValue(0); + distypes->InsertNextValue(dis_type_value); + pnt_id++; + /* break; } if (id == -1) std::cout << "Error in VtkConditionSource::RequestData() - Point object not found ..." << std::endl; + */ } else if ((*_cond_vec)[n]->getGeoType() == GEOLIB::POLYLINE) { - const GEOLIB::Polyline* ply = - static_cast<const GEOLIB::Polyline*>((*_cond_vec)[n]->getGeoObj()); + const GEOLIB::Polyline* ply = static_cast<const GEOLIB::Polyline*>((*_cond_vec)[n]->getGeoObj()); const int nPoints = ply->getNumberOfPoints(); newLines->InsertNextCell(nPoints); + double value (0); for (int i = 0; i < nPoints; i++) { - size_t pnt_id = ply->getPointID(i); //this->getIndex(ply->getPointID(i), newPoints, scalars, idx_map); + size_t point_index = ply->getPointID(i); + + newPoints->InsertNextPoint((*_points)[point_index]->getData()); newLines->InsertCellPoint(pnt_id); - distypes->SetValue(pnt_id, dis_type_value); + distypes->InsertNextValue(dis_type_value); - if (type == FiniteElement::CONSTANT) - scalars->SetValue(pnt_id, dis_values[0]); - else if (type == FiniteElement::LINEAR) + if (type == FiniteElement::CONSTANT || type == FiniteElement::CONSTANT_NEUMANN) + scalars->InsertNextValue(dis_values[0]); + else if (type == FiniteElement::LINEAR || type == FiniteElement::LINEAR_NEUMANN) { - for (size_t j = 0; j < dis_values.size(); j += 2) - if (static_cast<size_t>(dis_values[j]) == pnt_id) - //if (this->getIndex(static_cast<size_t>(dis_values[j]), newPoints, scalars, idx_map) == pnt_id) - { - scalars->SetValue(pnt_id, dis_values[j + 1]); - break; - } + for (size_t j = 0; j < dis_values.size(); j ++) + { + if (static_cast<int>(dis_nodes[j]) == i) + value = dis_values[j]; + } + scalars->InsertNextValue(value); } + else + scalars->InsertNextValue(0); + pnt_id++; } } else if ((*_cond_vec)[n]->getGeoType() == GEOLIB::SURFACE) { + std::vector<int> point_idx_map(_points->size(), -1); + const GEOLIB::Surface* sfc = static_cast<const GEOLIB::Surface*>((*_cond_vec)[n]->getGeoObj()); @@ -190,23 +199,31 @@ int VtkConditionSource::RequestData( vtkInformation* request, const GEOLIB::Triangle* triangle = (*sfc)[i]; for (size_t j = 0; j < 3; j++) { - size_t pnt_id = (*triangle)[j]; //this->getIndex((*triangle)[j], newPoints, scalars, idx_map); - aPolygon->GetPointIds()->SetId(j, pnt_id); - distypes->SetValue(pnt_id, dis_type_value); + size_t point_index ((*triangle)[j]); - if (type == FiniteElement::CONSTANT) - scalars->SetValue(pnt_id, dis_values[0]); - else if (type == FiniteElement::LINEAR) + if (point_idx_map[point_index] == -1) { - for (size_t k = 0; k < dis_values.size(); k += 2) - if (static_cast<size_t>(dis_values[j]) == - pnt_id) - //if (this->getIndex(static_cast<size_t>(dis_values[j]), newPoints, scalars, idx_map) == pnt_id) - { - scalars->SetValue(pnt_id,dis_values[j + 1]); - break; - } + point_idx_map[point_index] = pnt_id; + newPoints->InsertNextPoint((*_points)[point_index]->getData()); + aPolygon->GetPointIds()->SetId(j, pnt_id); + distypes->InsertNextValue(dis_type_value); + + if (type == FiniteElement::CONSTANT || type == FiniteElement::CONSTANT_NEUMANN) + scalars->InsertNextValue(dis_values[0]); + else if (type == FiniteElement::LINEAR || type == FiniteElement::LINEAR_NEUMANN) + { + for (size_t k = 0; k < dis_values.size(); k++) + if (static_cast<size_t>(dis_nodes[j]) == point_index) + { + scalars->InsertNextValue(dis_values[j]); + break; + } + } + else scalars->InsertNextValue(0); + pnt_id++; } + else + aPolygon->GetPointIds()->SetId(j, static_cast<vtkIdType>(point_idx_map[point_index])); } newPolys->InsertNextCell(aPolygon); @@ -217,12 +234,14 @@ int VtkConditionSource::RequestData( vtkInformation* request, else if ((*_cond_vec)[n]->getGeoType() == GEOLIB::INVALID) { size_t nValues = dis_values.size(); - for (size_t i=0; i<nValues; i+=2) + for (size_t i=0; i<nValues; i++) { - vtkIdType vtk_id = static_cast<vtkIdType>(dis_values[i]); - newVerts->InsertNextCell(1, &vtk_id); - scalars->SetValue(vtk_id, dis_values[i+1]); - distypes->SetValue(vtk_id, dis_type_value); + //vtkIdType pid = newPoints->InsertNextPoint((*_points)[dis_nodes[i]]->getData()); + vtkIdType pid = newPoints->InsertNextPoint((*_points)[i]->getData()); + newVerts->InsertNextCell(1, &pid); + scalars->InsertNextValue(dis_values[i]); + distypes->InsertNextValue(dis_type_value); + pnt_id++; } } // draw a bounding box in case of of the conditions is "domain" diff --git a/VtkVis/VtkGeoImageSource.cpp b/VtkVis/VtkGeoImageSource.cpp index a2481baecab..1ee5e8dd0d4 100644 --- a/VtkVis/VtkGeoImageSource.cpp +++ b/VtkVis/VtkGeoImageSource.cpp @@ -8,19 +8,17 @@ // ** INCLUDES ** #include "VtkGeoImageSource.h" -#include "OGSRaster.h" +//#include "OGSRaster.h" +#include "VtkRaster.h" #include <vtkFloatArray.h> #include <vtkImageChangeInformation.h> #include <vtkImageData.h> +#include <vtkImageImport.h> #include <vtkImageShiftScale.h> #include <vtkObjectFactory.h> #include <vtkPointData.h> -#include <vtkQImageToImageSource.h> - -#include <QImage> -#include <QPointF> -#include <QString> +#include <vtkIntArray.h> vtkStandardNewMacro(VtkGeoImageSource); @@ -51,22 +49,13 @@ void vtkSimpleImageFilterExampleExecute(vtkImageData* input, } VtkGeoImageSource::VtkGeoImageSource() +: _imageSource(NULL), _x0(0), _y0(0), _z0(0), _spacing(1) { - _imageSource = vtkQImageToImageSource::New(); - _imageInfo = vtkImageChangeInformation::New(); - _imageShift = vtkImageShiftScale::New(); - - _imageInfo->SetInputConnection(_imageSource->GetOutputPort()); - _imageShift->SetInputConnection(_imageInfo->GetOutputPort()); - _imageShift->SetOutputScalarTypeToUnsignedChar(); - this->SetInputConnection(_imageShift->GetOutputPort()); } VtkGeoImageSource::~VtkGeoImageSource() { - _imageSource->Delete(); - _imageInfo->Delete(); - _imageShift->Delete(); + if(_imageSource) _imageSource->Delete(); } void VtkGeoImageSource::PrintSelf(ostream& os, vtkIndent indent) @@ -74,52 +63,43 @@ void VtkGeoImageSource::PrintSelf(ostream& os, vtkIndent indent) this->Superclass::PrintSelf(os, indent); } -void VtkGeoImageSource::setImageFilename(QString filename) +void VtkGeoImageSource::readImage(const QString &filename) { - QImage* raster = new QImage; - QPointF origin; - double spacing; - OGSRaster::loadImage(filename, *raster, origin, spacing); - this->setImage(*raster); - delete raster; - // correct raster position by half a pixel for correct visualisation - this->setOrigin(origin.x()+(spacing/2.0), origin.y()+(spacing/2.0), -10.0); - this->setSpacing(spacing); - this->SetName(filename); + this->setImage(VtkRaster::loadImage(filename.toStdString(), _x0, _y0, _spacing), filename, _x0, _y0, _spacing); } -vtkImageData* VtkGeoImageSource::getImageData() +void VtkGeoImageSource::setImage(vtkImageAlgorithm* image, const QString &name, double x0, double y0, double spacing) { - return this->_imageSource->GetImageDataInput(0); -} + this->_imageSource = image; + this->SetInputConnection(_imageSource->GetOutputPort()); + this->SetName(name); + _x0 = x0; _y0 = y0; _z0 = -10; _spacing = spacing; -std::pair<double, double> VtkGeoImageSource::getOrigin() -{ - double* origin = this->_imageInfo->GetOutputOrigin(); - std::pair<double, double> p(origin[0], origin[1]); - return p; + this->GetOutput()->SetOrigin(_x0, _y0, _z0); + this->GetOutput()->SetSpacing(_spacing, _spacing, _spacing); } -double VtkGeoImageSource::getSpacing() +vtkImageData* VtkGeoImageSource::getImageData() { - double* spacing = this->_imageInfo->GetOutputSpacing(); - return spacing[0]; + return this->_imageSource->GetImageDataInput(0); } -void VtkGeoImageSource::setImage(QImage& image) +void VtkGeoImageSource::getOrigin(double origin[3]) const { - _imageSource->SetQImage(&image); - _imageSource->Update(); // crashes otherwise + origin[0] = this->_x0; + origin[1] = this->_y0; + origin[2] = this->_z0; } -void VtkGeoImageSource::setOrigin(double x, double y, double z) +double VtkGeoImageSource::getSpacing() const { - _imageInfo->SetOutputOrigin(x, y, z); + return this->_spacing; } -void VtkGeoImageSource::setSpacing(double spacing) +void VtkGeoImageSource::getRange(double range[2]) { - _imageInfo->SetOutputSpacing(spacing, spacing, spacing); + this->_imageSource->Update(); + _imageSource->GetOutput()->GetPointData()->GetArray(0)->GetRange(range); } void VtkGeoImageSource::SimpleExecute(vtkImageData* input, vtkImageData* output) @@ -137,41 +117,6 @@ void VtkGeoImageSource::SimpleExecute(vtkImageData* input, vtkImageData* output) vtkGenericWarningMacro("Execute: Unknown input ScalarType"); return; } - -/* - // Create normals - vtkFloatArray* normals = vtkFloatArray::New(); - int numPoints = input->GetNumberOfPoints(); - normals->SetNumberOfComponents(3); - normals->Allocate(3*numPoints); - float normal[3] = {0.f, 0.f, 1.f}; - - // vector data - std::cout << input->GetScalarTypeAsString() << std::endl; - vtkFloatArray* vectors = vtkFloatArray::New(); - vectors->SetNumberOfComponents(3); - vectors->Allocate(3*numPoints); - int numScalarComponents = input->GetNumberOfScalarComponents(); - - for (int i = 0; i < numPoints; i++) - { - normals->InsertTuple(i, normal); - float vector[3]; - vector[0] = 1; - vector[1] = 1; - vector[2] = ((unsigned char*)inPtr)[i * numScalarComponents] * 0.1; - //std::cout << vector[2] << " "; - vectors->InsertTuple(i, vector); - } - - normals->SetName("Normals"); - output->GetPointData()->SetNormals(normals); - normals->Delete(); - - vectors->SetName("Vectors"); - output->GetPointData()->SetVectors(vectors); - vectors->Delete(); - */ } void VtkGeoImageSource::SetUserProperty( QString name, QVariant value ) diff --git a/VtkVis/VtkGeoImageSource.h b/VtkVis/VtkGeoImageSource.h index c21e175c6c7..3e12f7ab926 100644 --- a/VtkVis/VtkGeoImageSource.h +++ b/VtkVis/VtkGeoImageSource.h @@ -13,10 +13,10 @@ class QString; class QPointF; class QImage; class vtkQImageToImageSource; -class vtkImageChangeInformation; class vtkImageShiftScale; class vtkImageData; + class VtkGeoImageSource : public vtkSimpleImageToImageFilter, public VtkAlgorithmProperties { public: @@ -28,19 +28,23 @@ public: /// @brief Prints information about itself. void PrintSelf(ostream& os, vtkIndent indent); + /// @brief Returns the ImageData object. vtkImageData* getImageData(); - std::pair<double, double> getOrigin(); - - double getSpacing(); + /// @brief Reads an image from file. + void readImage(const QString &filename); - void setImageFilename(QString filename); + /// @brief Imports an existing image object. + void setImage(vtkImageAlgorithm* img, const QString &name, double x0, double y0, double spacing); - void setImage(QImage& image); + /// @brief Returns the origin in world coordinates. + void getOrigin(double origin[3]) const; - void setOrigin(double x, double y, double z); + /// @brief Returns the scalar data range. + void getRange(double range[2]); - void setSpacing(double spacing); + /// @brief Returns the spacing betweeen two pixels. + double getSpacing() const; virtual void SetUserProperty(QString name, QVariant value); @@ -58,9 +62,9 @@ private: VtkGeoImageSource(const VtkGeoImageSource&); // Not implemented. void operator=(const VtkGeoImageSource&); // Not implemented - vtkQImageToImageSource* _imageSource; - vtkImageChangeInformation* _imageInfo; - vtkImageShiftScale* _imageShift; + vtkImageAlgorithm* _imageSource; + + double _x0, _y0, _z0, _spacing; }; #endif // VTKGEOIMAGESOURCE_H diff --git a/VtkVis/VtkImageDataToLinePolyDataFilter.cpp b/VtkVis/VtkImageDataToLinePolyDataFilter.cpp index 5a2b79485f6..a83e0bd5d2e 100644 --- a/VtkVis/VtkImageDataToLinePolyDataFilter.cpp +++ b/VtkVis/VtkImageDataToLinePolyDataFilter.cpp @@ -54,10 +54,14 @@ int VtkImageDataToLinePolyDataFilter::RequestData(vtkInformation*, void* inScalarPtr = input->GetScalarPointer(); int numScalarComponents = input->GetNumberOfScalarComponents(); + double spacing[3]; input->GetSpacing(spacing); this->ImageSpacing = spacing[0]; + int dimensions[3]; + input->GetDimensions(dimensions); + // Skip execution if there are no points vtkIdType numPts = input->GetNumberOfPoints(); if (numPts < 1) @@ -84,14 +88,25 @@ int VtkImageDataToLinePolyDataFilter::RequestData(vtkInformation*, vtkPointData* outPD = output->GetPointData(); outPD->CopyAllocate(inPD, numPts * 16, numPts); + // Compute scaling factor that max height is 0.1 * longest image dimension + double range[2]; + inPD->GetArray(0)->GetRange(range); + float scalingFactor = (std::max(dimensions[0], dimensions[1]) * spacing[0] * 0.1) + / std::max(range[0], range[1]); + double dir[3] = {0, 0, 1}; // Traverse all points creating another point with scalar distance in Z direction for (vtkIdType ptId = 0; ptId < numPts; ++ptId) { + // Skip translucent pixels + float opacity = ((float*)inScalarPtr)[ptId * numScalarComponents + 1]; + if (opacity < 0.00000001f) + continue; + // Compute length of the new line (scalar * LengthScaleFactor) - float length = ((unsigned char*)inScalarPtr)[ptId * numScalarComponents] - * this->LengthScaleFactor; + float length = ((float*)inScalarPtr)[ptId * numScalarComponents] + * scalingFactor * this->LengthScaleFactor; //float length = (((unsigned char*)inScalarPtr)[ptId * numScalarComponents]* this->LengthScaleFactor > 50000) ? 50000 : ((unsigned char*)inScalarPtr)[ptId * numScalarComponents]* this->LengthScaleFactor; // Skip this line if length is zero @@ -126,7 +141,7 @@ int VtkImageDataToLinePolyDataFilter::RequestData(vtkInformation*, // Store the new set of points in the output output->SetPoints(newPts); - output->GetPointData()->GetArray(0)->SetName("Colours"); + output->GetPointData()->GetArray(0)->SetName("Colors"); // Avoid keeping extra memory around output->Squeeze(); diff --git a/VtkVis/VtkImageDataToLinePolyDataFilter.h b/VtkVis/VtkImageDataToLinePolyDataFilter.h index 18792b5d199..cddf808d5c3 100644 --- a/VtkVis/VtkImageDataToLinePolyDataFilter.h +++ b/VtkVis/VtkImageDataToLinePolyDataFilter.h @@ -13,8 +13,9 @@ class vtkInformation; class vtkInformationVector; /// @brief Creates lines that stand on top of the image with the length -/// of the corresponding first sub-pixel value (the red value). Used by -/// VtkCompositeImageDataToCylindersFilter. +/// of the corresponding first sub-pixel value (the grey or red value). +/// The maximum height is 0.1 * longest image dimension. +/// Used by VtkCompositeImageDataToCylindersFilter. class VtkImageDataToLinePolyDataFilter : public vtkPolyDataAlgorithm, public VtkAlgorithmProperties { public: diff --git a/VtkVis/VtkMeshConverter.cpp b/VtkVis/VtkMeshConverter.cpp index 413125ddade..143a244a053 100644 --- a/VtkVis/VtkMeshConverter.cpp +++ b/VtkVis/VtkMeshConverter.cpp @@ -18,11 +18,12 @@ #include <vtkCell.h> #include <vtkCellData.h> #include <vtkUnstructuredGrid.h> +#include <vtkFloatArray.h> -MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(vtkImageData* img, - const std::pair<double,double> &origin, - const double &scalingFactor, +GridAdapter* VtkMeshConverter::convertImgToMesh(vtkImageData* img, + const double origin[3], + const double scalingFactor, MshElemType::type elem_type, UseIntensityAs::type intensity_type) { @@ -32,8 +33,8 @@ MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(vtkImageData* img, return NULL; } - vtkSmartPointer<vtkUnsignedCharArray> pixelData = vtkSmartPointer<vtkUnsignedCharArray>( - vtkUnsignedCharArray::SafeDownCast(img->GetPointData()->GetScalars())); + vtkSmartPointer<vtkFloatArray> pixelData = vtkSmartPointer<vtkFloatArray>( + vtkFloatArray::SafeDownCast(img->GetPointData()->GetScalars())); int* dims = img->GetDimensions(); const size_t imgHeight = dims[0]; @@ -44,7 +45,7 @@ MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(vtkImageData* img, bool* visNodes(new bool[incWidth * incHeight]); int* node_idx_map(new int[incWidth * incHeight]); - for (size_t j = 0; j < incWidth; j++) + for (size_t j = 0; j < incHeight; j++) { pixVal[j]=0; visNodes[j]=false; @@ -56,9 +57,26 @@ MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(vtkImageData* img, { const size_t img_idx = i * imgHeight + j; const size_t index = (i+1) * incHeight + j; - const double* colour = pixelData->GetTuple4(img_idx); - pixVal[index] = 0.3 * colour[0] + 0.6 * colour[1] + 0.1 * colour[2]; - visNodes[index] = (colour[3] > 0); + int nTuple = pixelData->GetNumberOfComponents(); + double* colour; + if (nTuple == 2) //Grey+Alpha + { + colour = pixelData->GetTuple2(img_idx); + pixVal[index] = colour[0]; + + } + else if (nTuple == 4) //RGBA + { + colour = pixelData->GetTuple4(img_idx); + pixVal[index] = 0.3 * colour[0] + 0.6 * colour[1] + 0.1 * colour[2]; + } + else + { + std::cout << "Unsupported pixel composition!" << std::endl; + return NULL; + } + + visNodes[index] = (colour[nTuple-1] > 0); node_idx_map[index]=-1; } pixVal[(i+2)*incHeight-1]=0; @@ -66,7 +84,7 @@ MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(vtkImageData* img, node_idx_map[(i+2)*incHeight-1]=-1; } - MeshLib::CFEMesh* mesh = constructMesh(pixVal, node_idx_map, visNodes, origin, imgHeight, imgWidth, scalingFactor, elem_type, intensity_type); + GridAdapter* mesh = constructMesh(pixVal, node_idx_map, visNodes, origin, imgHeight, imgWidth, scalingFactor, elem_type, intensity_type); delete [] pixVal; delete [] visNodes; @@ -75,8 +93,8 @@ MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(vtkImageData* img, return mesh; } -MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(const double* img, - const std::pair<double,double> &origin, +GridAdapter* VtkMeshConverter::convertImgToMesh(const double* img, + const double origin[3], const size_t imgHeight, const size_t imgWidth, const double &scalingFactor, @@ -89,7 +107,9 @@ MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(const double* img, bool* visNodes(new bool[incWidth * incHeight]); int* node_idx_map(new int[incWidth * incHeight]); - for (size_t j = 0; j < incWidth; j++) + double noDataValue = getExistingValue(img, imgWidth*imgHeight); + + for (size_t j = 0; j < imgHeight; j++) { pixVal[j]=0; visNodes[j]=false; @@ -101,8 +121,17 @@ MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(const double* img, { const size_t img_idx = i * imgHeight + j; const size_t index = (i+1) * incHeight + j; - pixVal[index] = img[img_idx]; - visNodes[index] = 1; + if (img[img_idx] == -9999) + { + visNodes[index] = false; + pixVal[index] = noDataValue; + } + else + { + pixVal[index] = img[img_idx]; + visNodes[index] = true; + } + node_idx_map[index]=-1; } pixVal[(i+2)*incHeight-1]=0; @@ -110,7 +139,7 @@ MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(const double* img, node_idx_map[(i+2)*incHeight-1]=-1; } - MeshLib::CFEMesh* mesh = constructMesh(pixVal, node_idx_map, visNodes, origin, imgHeight, imgWidth, scalingFactor, elem_type, intensity_type); + GridAdapter* mesh = constructMesh(pixVal, node_idx_map, visNodes, origin, imgHeight, imgWidth, scalingFactor, elem_type, intensity_type); delete [] pixVal; delete [] visNodes; @@ -119,10 +148,10 @@ MeshLib::CFEMesh* VtkMeshConverter::convertImgToMesh(const double* img, return mesh; } -MeshLib::CFEMesh* VtkMeshConverter::constructMesh(const double* pixVal, +GridAdapter* VtkMeshConverter::constructMesh(const double* pixVal, int* node_idx_map, const bool* visNodes, - const std::pair<double,double> &origin, + const double origin[3], const size_t &imgHeight, const size_t &imgWidth, const double &scalingFactor, @@ -131,10 +160,10 @@ MeshLib::CFEMesh* VtkMeshConverter::constructMesh(const double* pixVal, { const size_t incHeight = imgHeight+1; const size_t incWidth = imgWidth+1; - MeshLib::CFEMesh* mesh(new MeshLib::CFEMesh()); + GridAdapter* grid = new GridAdapter(); size_t node_idx_count(0); - const double x_offset(origin.first - scalingFactor/2.0); - const double y_offset(origin.second - scalingFactor/2.0); + const double x_offset(origin[0] - scalingFactor/2.0); + const double y_offset(origin[1] - scalingFactor/2.0); for (size_t i = 0; i < incWidth; i++) for (size_t j = 0; j < incHeight; j++) @@ -150,13 +179,9 @@ MeshLib::CFEMesh* VtkMeshConverter::constructMesh(const double* pixVal, if (set_node) { double zValue = (intensity_type == UseIntensityAs::ELEVATION) ? pixVal[index] : 0.0; - const double coords[3] = { x_offset + (scalingFactor * j), - y_offset + (scalingFactor * i), - zValue }; - - MeshLib::CNode* node(new MeshLib::CNode(node_idx_count)); - node->SetCoordinates(coords); - mesh->nod_vector.push_back(node); + grid->addNode(new GEOLIB::Point(x_offset + (scalingFactor * j), + y_offset + (scalingFactor * i), + zValue)); node_idx_map[index] = node_idx_count; node_idx_count++; } @@ -172,45 +197,45 @@ MeshLib::CFEMesh* VtkMeshConverter::constructMesh(const double* pixVal, const int mat = (intensity_type != UseIntensityAs::MATERIAL) ? 0 : static_cast<int>(pixVal[index+incHeight]); if (elem_type == MshElemType::TRIANGLE) { - mesh->ele_vector.push_back(createElement(elem_type, mat, node_idx_map[index], node_idx_map[index + 1], - node_idx_map[index + incHeight])); // upper left triangle - mesh->ele_vector.push_back(createElement(elem_type, mat, node_idx_map[index + 1], - node_idx_map[index + incHeight + 1], - node_idx_map[index + incHeight])); // lower right triangle + grid->addElement(createElement(elem_type, mat, node_idx_map[index], node_idx_map[index + 1], + node_idx_map[index + incHeight])); // upper left triangle + grid->addElement(createElement(elem_type, mat, node_idx_map[index + 1], + node_idx_map[index + incHeight + 1], + node_idx_map[index + incHeight])); // lower right triangle } if (elem_type == MshElemType::QUAD) { - mesh->ele_vector.push_back(createElement(elem_type, mat, node_idx_map[index], node_idx_map[index + 1], - node_idx_map[index + incHeight + 1], - node_idx_map[index + incHeight])); + grid->addElement(createElement(elem_type, mat, node_idx_map[index], node_idx_map[index + 1], + node_idx_map[index + incHeight + 1], + node_idx_map[index + incHeight])); } } } - mesh->ConstructGrid(); - return mesh; + return grid; } -MeshLib::CElem* VtkMeshConverter::createElement(MshElemType::type t, int mat, size_t node1, size_t node2, size_t node3, size_t node4) +GridAdapter::Element* VtkMeshConverter::createElement(MshElemType::type t, int mat, size_t node1, size_t node2, size_t node3, size_t node4) { - MeshLib::CElem* elem(new MeshLib::CElem); - elem->setElementProperties(t); - elem->SetNodeIndex(0, node1); - elem->SetNodeIndex(1, node2); - elem->SetNodeIndex(2, node3); + GridAdapter::Element* elem = new GridAdapter::Element(); + elem->material = mat; + elem->type = t; + std::vector<size_t> nodes; + nodes.push_back(node1); + nodes.push_back(node2); + nodes.push_back(node3); if (t == MshElemType::QUAD) - elem->SetNodeIndex(3, node4); - elem->SetPatchIndex(mat); - elem->InitializeMembers(); + nodes.push_back(node4); + elem->nodes = nodes; return elem; } -MeshLib::CFEMesh* VtkMeshConverter::convertUnstructuredGrid(vtkUnstructuredGrid* grid) +GridAdapter* VtkMeshConverter::convertUnstructuredGrid(vtkUnstructuredGrid* grid) { if (!grid) return NULL; - MeshLib::CFEMesh* mesh(new MeshLib::CFEMesh()); + GridAdapter* mesh = new GridAdapter(); const size_t nNodes = grid->GetPoints()->GetNumberOfPoints(); const size_t nElems = grid->GetNumberOfCells(); @@ -220,8 +245,7 @@ MeshLib::CFEMesh* VtkMeshConverter::convertUnstructuredGrid(vtkUnstructuredGrid* for (size_t i = 0; i < nNodes; i++) { coords = grid->GetPoints()->GetPoint(i); - MeshLib::CNode* node(new MeshLib::CNode(i, coords[0], coords[1], coords[2])); - mesh->nod_vector.push_back(node); + mesh->addNode(new GEOLIB::Point(coords[0], coords[1], coords[2])); } // set mesh elements @@ -229,7 +253,7 @@ MeshLib::CFEMesh* VtkMeshConverter::convertUnstructuredGrid(vtkUnstructuredGrid* vtkDataArray* scalars = grid->GetCellData()->GetScalars("MaterialIDs"); for (size_t i = 0; i < nElems; i++) { - MeshLib::CElem* elem(new MeshLib::CElem()); + GridAdapter::Element* elem = new GridAdapter::Element(); MshElemType::type elem_type = MshElemType::INVALID; int cell_type = grid->GetCellType(i); @@ -250,29 +274,34 @@ MeshLib::CFEMesh* VtkMeshConverter::convertUnstructuredGrid(vtkUnstructuredGrid* if (elem_type != MshElemType::INVALID) { - //elem->SetElementType(elem_type); - elem->setElementProperties(elem_type); + elem->type = elem_type; if (scalars) - elem->SetPatchIndex(static_cast<int>(scalars->GetComponent(i,0))); // HACK the name of the correct scalar array of the vtk file should probably be passed as an argument?! + elem->material = static_cast<int>(scalars->GetComponent(i,0)); } else { - std::cout << - "Error in GridAdapter::convertUnstructuredGrid() - Unknown mesh element type ..." - << std::endl; + std::cout << "Error in GridAdapter::convertUnstructuredGrid() - Unknown mesh element type ..." << std::endl; return NULL; } cell = grid->GetCell(i); size_t nElemNodes = cell->GetNumberOfPoints(); - elem->SetNodesNumber(nElemNodes); - elem->getNodeIndices().resize(nElemNodes); - + std::vector<size_t> nodes; for (size_t j = 0; j < nElemNodes; j++) - elem->SetNodeIndex(j, cell->GetPointId(j)); + nodes.push_back(cell->GetPointId(j)); - mesh->ele_vector.push_back(elem); + elem->nodes = nodes; + mesh->addElement(elem); } - mesh->ConstructGrid(); return mesh; } + +double VtkMeshConverter::getExistingValue(const double* img, size_t length) +{ + for (size_t i=0; i<length; i++) + { + if (img[i] != -9999) + return img[i]; + } + return -9999; +} diff --git a/VtkVis/VtkMeshConverter.h b/VtkVis/VtkMeshConverter.h index 30f82d3defc..ee748168c85 100644 --- a/VtkVis/VtkMeshConverter.h +++ b/VtkVis/VtkMeshConverter.h @@ -7,18 +7,13 @@ #ifndef VTKMESHCONVERTER_H #define VTKMESHCONVERTER_H -// ** INCLUDES ** -#include "msh_mesh.h" +//#include <utility> +//#include "MSHEnums.h" +#include "GridAdapter.h" class vtkImageData; // For conversion from Image to QuadMesh class vtkUnstructuredGrid; // For conversion vom vtk to ogs mesh -namespace MeshLib -{ -class CFEMesh; -class CNode; -} - /// Selection of possible interpretations for intensities struct UseIntensityAs { @@ -37,47 +32,49 @@ class VtkMeshConverter public: /** * Converts greyscale image to a mesh - * \parelem_type defines if elements of the new mesh should be triangles or quads (or hexes for 3D) + * \param elem_type defines if elements of the new mesh should be triangles or quads (or hexes for 3D) * \param intensity_type defines how image intensities are interpreted */ - static MeshLib::CFEMesh* convertImgToMesh(vtkImageData* img, - const std::pair<double,double> &origin, - const double &scalingFactor, - MshElemType::type elem_type, - UseIntensityAs::type intensity_type); + static GridAdapter* convertImgToMesh(vtkImageData* img, + const double origin[3], + const double scalingFactor, + MshElemType::type elem_type, + UseIntensityAs::type intensity_type); /** * Converts double array with raster values to a mesh - * \parelem_type defines if elements of the new mesh should be triangles or quads (or hexes for 3D) + * \param elem_type defines if elements of the new mesh should be triangles or quads (or hexes for 3D) * \param intensity_type defines how image intensities are interpreted */ - static MeshLib::CFEMesh* convertImgToMesh(const double* img, - const std::pair<double,double> &origin, - const size_t imgHeight, - const size_t imgWidth, - const double &scalingFactor, - MshElemType::type elem_type, - UseIntensityAs::type intensity_type); + static GridAdapter* convertImgToMesh(const double* img, + const double origin[3], + const size_t imgHeight, + const size_t imgWidth, + const double &scalingFactor, + MshElemType::type elem_type, + UseIntensityAs::type intensity_type); /// Converts a vtkUnstructuredGrid object to a CFEMesh - static MeshLib::CFEMesh* convertUnstructuredGrid(vtkUnstructuredGrid* grid); + static GridAdapter* convertUnstructuredGrid(vtkUnstructuredGrid* grid); private: /// Does the actual mesh generation based on the data given to the public methods. - static MeshLib::CFEMesh* constructMesh(const double* pixVal, - int* node_idx_map, - const bool* visNodes, - const std::pair<double,double> &origin, - const size_t &imgHeight, - const size_t &imgWidth, - const double &scalingFactor, - MshElemType::type elem_type, - UseIntensityAs::type intensity_type); + static GridAdapter* constructMesh(const double* pixVal, + int* node_idx_map, + const bool* visNodes, + const double origin[3], + const size_t &imgHeight, + const size_t &imgWidth, + const double &scalingFactor, + MshElemType::type elem_type, + UseIntensityAs::type intensity_type); /// Creates a mesh element based on the given data. - static MeshLib::CElem* createElement(MshElemType::type t, int mat, + static GridAdapter::Element* createElement(MshElemType::type t, int mat, size_t node1, size_t node2, size_t node3, size_t node4 = 0); + + static double getExistingValue(const double* img, size_t length); }; #endif // VTKMESHCONVERTER_H diff --git a/VtkVis/VtkMeshSource.cpp b/VtkVis/VtkMeshSource.cpp index c561268cba6..e98c1e9ef72 100644 --- a/VtkVis/VtkMeshSource.cpp +++ b/VtkVis/VtkMeshSource.cpp @@ -18,6 +18,7 @@ #include <vtkStreamingDemandDrivenPipeline.h> #include <vtkUnsignedCharArray.h> #include <vtkUnstructuredGrid.h> +#include <vtkProperty.h> // OGS Cell Types #include <vtkHexahedron.h> @@ -32,10 +33,9 @@ vtkCxxRevisionMacro(VtkMeshSource, "$Revision$"); VtkMeshSource::VtkMeshSource() : _matName("MaterialIDs") { + _removable = false; // From VtkAlgorithmProperties this->SetNumberOfInputPorts(0); - //this->SetColorByMaterial(true); - const GEOLIB::Color* c = GEOLIB::getRandomColor(); vtkProperty* vtkProps = GetProperties(); vtkProps->SetColor((*c)[0] / 255.0,(*c)[1] / 255.0,(*c)[2] / 255.0); @@ -93,9 +93,9 @@ int VtkMeshSource::RequestData( vtkInformation* request, const std::vector<GEOLIB::Point*>* nodes = _grid->getNodes(); const std::vector<GridAdapter::Element*>* elems = _grid->getElements(); - size_t nPoints = nodes->size(); - size_t nElems = elems->size(); - size_t nElemNodes = 0; + const size_t nPoints = nodes->size(); + const size_t nElems = elems->size(); + //size_t nElemNodes = 0; if (nPoints == 0 || nElems == 0) return 0; @@ -118,14 +118,15 @@ int VtkMeshSource::RequestData( vtkInformation* request, vtkSmartPointer<vtkIntArray> materialIDs = vtkSmartPointer<vtkIntArray>::New(); materialIDs->SetName(_matName); materialIDs->SetNumberOfComponents(1); - //materialIDs->SetNumberOfTuples(nElems); + materialIDs->SetNumberOfTuples(nElems); // Generate mesh elements for (size_t i = 0; i < nElems; i++) { vtkCell* newCell; + const GridAdapter::Element* elem = (*elems)[i]; - switch ((*elems)[i]->type) + switch (elem->type) { case MshElemType::TRIANGLE: newCell = vtkTriangle::New(); @@ -149,11 +150,11 @@ int VtkMeshSource::RequestData( vtkInformation* request, return 0; } - materialIDs->InsertNextValue((*elems)[i]->material); + materialIDs->InsertValue(i,(elem->material)); - nElemNodes = (*elems)[i]->nodes.size(); + const size_t nElemNodes (elem->nodes.size()); for (size_t j = 0; j < nElemNodes; j++) - newCell->GetPointIds()->SetId(j, (*elems)[i]->nodes[nElemNodes - 1 - j]); + newCell->GetPointIds()->SetId(j, elem->nodes[nElemNodes - 1 - j]); output->InsertNextCell(newCell->GetCellType(), newCell->GetPointIds()); newCell->Delete(); diff --git a/VtkVis/VtkPointsSource.cpp b/VtkVis/VtkPointsSource.cpp index 7f108aa8d21..1850908209c 100644 --- a/VtkVis/VtkPointsSource.cpp +++ b/VtkVis/VtkPointsSource.cpp @@ -18,6 +18,7 @@ #include <vtkSmartPointer.h> #include <vtkStreamingDemandDrivenPipeline.h> #include <vtkCellData.h> +#include <vtkProperty.h> vtkStandardNewMacro(VtkPointsSource); vtkCxxRevisionMacro(VtkPointsSource, "$Revision$"); @@ -25,6 +26,7 @@ vtkCxxRevisionMacro(VtkPointsSource, "$Revision$"); VtkPointsSource::VtkPointsSource() : _points(NULL) { + _removable = false; // From VtkAlgorithmProperties this->SetNumberOfInputPorts(0); const GEOLIB::Color* c = GEOLIB::getRandomColor(); diff --git a/VtkVis/VtkPolylinesSource.cpp b/VtkVis/VtkPolylinesSource.cpp index b8d880c9dcb..cc3aa88873d 100644 --- a/VtkVis/VtkPolylinesSource.cpp +++ b/VtkVis/VtkPolylinesSource.cpp @@ -18,6 +18,7 @@ #include <vtkPolyData.h> #include <vtkSmartPointer.h> #include <vtkStreamingDemandDrivenPipeline.h> +#include <vtkProperty.h> vtkStandardNewMacro(VtkPolylinesSource); vtkCxxRevisionMacro(VtkPolylinesSource, "$Revision$"); @@ -25,6 +26,7 @@ vtkCxxRevisionMacro(VtkPolylinesSource, "$Revision$"); VtkPolylinesSource::VtkPolylinesSource() : _polylines(NULL) { + _removable = false; // From VtkAlgorithmProperties this->SetNumberOfInputPorts(0); const GEOLIB::Color* c = GEOLIB::getRandomColor(); diff --git a/VtkVis/VtkRaster.cpp b/VtkVis/VtkRaster.cpp new file mode 100644 index 00000000000..529d64ca3cd --- /dev/null +++ b/VtkVis/VtkRaster.cpp @@ -0,0 +1,516 @@ +/** + * \file VtkRaster.cpp + * 2012/02/01 KR Initial implementation + */ + +#include "VtkRaster.h" + +#include <cmath> +#include <iomanip> +#include <iostream> +#include <sstream> + +#include <QFileInfo> + +#include "StringTools.h" + +#include <vtkFloatArray.h> +#include <vtkPointData.h> + +#include <vtkImageAlgorithm.h> +#include <vtkImageData.h> +#include <vtkImageImport.h> +#include <vtkImageReader2.h> +#include <vtkPNGReader.h> +#include <vtkJPEGReader.h> +#include <vtkBMPReader.h> + +#ifdef libgeotiff_FOUND +#include "geo_tiffp.h" +#include "xtiffio.h" +#endif + +vtkImageAlgorithm* VtkRaster::loadImage(const std::string &fileName, + double& x0, double& y0, double& delta) +{ + QFileInfo fileInfo(QString::fromStdString(fileName)); + + if (fileInfo.suffix().toLower() == "asc" || fileInfo.suffix().toLower() == "grd") + return loadImageFromASC(fileName, x0, y0, delta); +#ifdef libgeotiff_FOUND + else if ((fileInfo.suffix().toLower() == "tif") || (fileInfo.suffix().toLower() == "tiff")) + return loadImageFromTIFF(fileName, x0, y0, delta); +#endif + else + return loadImageFromFile(fileName); +} + +vtkImageImport* VtkRaster::loadImageFromASC(const std::string &fileName, + double& x0, double& y0, double& delta) +{ + size_t width(0), height(0); + float* data; + + if (fileName.substr(fileName.length()-3, 3).compare("asc") == 0) + data = loadDataFromASC(fileName, x0, y0, width, height, delta); + else + data = loadDataFromSurfer(fileName, x0, y0, width, height, delta); + + vtkImageImport* image = vtkImageImport::New(); + image->SetDataSpacing(delta, delta,delta); + image->SetDataOrigin(x0+(delta/2.0), y0+(delta/2.0), 0); // translate whole mesh by half a pixel in x and y + image->SetWholeExtent(0, width-1, 0, height-1, 0, 0); + image->SetDataExtent(0, width-1, 0, height-1, 0, 0); + image->SetDataExtentToWholeExtent(); + image->SetDataScalarTypeToFloat(); + image->SetNumberOfScalarComponents(2); + image->SetImportVoidPointer(data, 0); + image->Update(); + + return image; +} + +vtkImageImport* VtkRaster::loadImageFromArray(double* data_array, double &x0, double &y0, size_t &width, size_t &height, double &delta, double noData) +{ + const size_t length = height*width; + float* data = new float[length*2]; + float max_val=noData; + for (size_t j=0; j<length; j++) + { + data[j*2] = static_cast<float>(data_array[j]); + max_val = (data[j*2]>max_val) ? data[j*2] : max_val; + } + for (size_t j=0; j<length; j++) + { + if (data[j*2]==noData) + { + data[j*2] = max_val; + data[j*2+1] = 0; + } + else + { + //data[j*2] = max_val-data[j*2];//delete; + data[j*2+1] = max_val; + } + } + + vtkImageImport* image = vtkImageImport::New(); + image->SetDataSpacing(delta, delta, delta); + image->SetDataOrigin(x0+(delta/2.0), y0+(delta/2.0), 0); // translate whole mesh by half a pixel in x and y + image->SetWholeExtent(0, width-1, 0, height-1, 0, 0); + image->SetDataExtent(0, width-1, 0, height-1-1, 0, 0); + image->SetDataExtentToWholeExtent(); + image->SetDataScalarTypeToFloat(); + image->SetNumberOfScalarComponents(2); + image->SetImportVoidPointer(data, 0); + image->Update(); + + return image; +} + + +bool VtkRaster::readASCHeader(ascHeader &header, std::ifstream &in) +{ + std::string line, tag, value; + + in >> tag; + if (tag.compare("ncols") == 0) + { + in >> value; + header.ncols = atoi(value.c_str()); + } + else + return false; + in >> tag; + if (tag.compare("nrows") == 0) + { + in >> value; + header.nrows = atoi(value.c_str()); + } + else + return false; + in >> tag; + if (tag.compare("xllcorner") == 0) + { + in >> value; + header.x = strtod(replaceString(",", ".", value).c_str(),0); + } + else + return false; + in >> tag; + if (tag.compare("yllcorner") == 0) + { + in >> value; + header.y = strtod(replaceString(",", ".", value).c_str(),0); + } + else + return false; + in >> tag; + if (tag.compare("cellsize") == 0) + { + in >> value; + header.cellsize = strtod(replaceString(",", ".", value).c_str(),0); + } + else + return false; + in >> tag; + if (tag.compare("NODATA_value") == 0) + { + in >> value; + header.noData = value.c_str(); + } + else + return false; + + // correct raster position by half a pixel for correct visualisation + // argh! wrong! correction has to happen in visualisation object, otherwise the actual data is wrong + //header.x = header.x + (header.cellsize / 2); + //header.y = header.y + (header.cellsize / 2); + + return true; +} + +float* VtkRaster::loadDataFromASC(const std::string &fileName, + double &x0, + double &y0, + size_t &width, + size_t &height, + double &delta) +{ + std::ifstream in( fileName.c_str() ); + + if (!in.is_open()) + { + std::cout << "VtkRaster::loadImageFromASC() - Could not open file..." << std::endl; + return NULL; + } + + ascHeader header; + + if (readASCHeader(header, in)) + { + x0 = header.x; + y0 = header.y; + width = header.ncols; + height = header.nrows; + delta = header.cellsize; + + float* values = new float[header.ncols * header.nrows * 2]; + + int col_index(0); + int noData = atoi(header.noData.c_str()); + float max_val = noData; + std::string s(""); + // read the file into a double-array + for (int j = 0; j < header.nrows; j++) + { + col_index = (header.nrows - j - 1) * header.ncols; + for (int i = 0; i < header.ncols; i++) + { + in >> s; + size_t index = 2*(col_index+i); + values[index] = static_cast<float>(strtod(replaceString(",", ".", s).c_str(),0)); + if (values[index] > max_val) + max_val = values[index]; + } + } + + // shift noData values into normal pixel-range and set transparancy values for all pixels + size_t nPixels = header.ncols * header.nrows; + for (size_t j = 0; j < nPixels; j++) + { + if (values[j*2] == noData) + { + values[j*2] = max_val; + values[j*2+1] = 0; + } + else + values[j*2+1] = max_val; + } + + in.close(); + return values; + } + return NULL; +} + +bool VtkRaster::readSurferHeader(ascHeader &header, std::ifstream &in) +{ + std::string line, tag, value; + double min, max; + + in >> tag; + + if (tag.compare("DSAA") != 0) + { + std::cout << "Error in readSurferHeader() - No Surfer file..." << std::endl; + return false; + } + else + { + in >> header.ncols >> header.nrows; + in >> min >> max; + header.x = min; + header.cellsize = (max-min)/(double)header.ncols; + + in >> min >> max; + header.y = min; + + if (ceil((max-min)/(double)header.nrows) == ceil(header.cellsize)) + header.cellsize = ceil(header.cellsize); + else + { + std::cout << "Error in readSurferHeader() - Anisotropic cellsize detected..." << std::endl; + return 0; + } + in >> min >> max; // ignore min- and max-values + + header.noData = "1.70141E+038"; + } + + return true; +} + +float* VtkRaster::loadDataFromSurfer(const std::string &fileName, + double &x0, + double &y0, + size_t &width, + size_t &height, + double &delta) +{ + std::ifstream in( fileName.c_str() ); + + if (!in.is_open()) + { + std::cout << "VtkRaster::loadImageFromSurfer() - Could not open file..." << std::endl; + return NULL; + } + + ascHeader header; + + if (readSurferHeader(header, in)) + { + x0 = header.x; + y0 = header.y; + width = header.ncols; + height = header.nrows; + delta = header.cellsize; + + float* values = new float[header.ncols * header.nrows * 2]; + + int col_index(0); + int noData = -9999; + float max_val = noData; + std::string s(""); + // read the file into a double-array + for (int j = 0; j < header.nrows; j++) + { + col_index = j * header.ncols; + for (int i = 0; i < header.ncols; i++) + { + in >> s; + if (s.compare(header.noData) == 0) + s = "-9999"; + size_t index = 2*(col_index+i); + values[index] = static_cast<float>(strtod(replaceString(",", ".", s).c_str(),0)); + if (values[index] > max_val) + max_val = values[index]; + } + } + + // shift noData values into normal pixel-range and set transparancy values for all pixels + size_t nPixels = header.ncols * header.nrows; + for (size_t j = 0; j < nPixels; j++) + { + if (values[j*2] == noData) + { + values[j*2] = max_val; + values[j*2+1] = 0; + } + else + values[j*2+1] = max_val; + } + + in.close(); + return values; + } + return NULL; +} + +#ifdef libgeotiff_FOUND +vtkImageImport* VtkRaster::loadImageFromTIFF(const std::string &fileName, + double &x0, double &y0, + double &cellsize) +{ + TIFF* tiff = XTIFFOpen(fileName.c_str(), "r"); + + if (tiff) + { + GTIF* geoTiff = GTIFNew(tiff); + + if (geoTiff) + { + int imgWidth = 0, imgHeight = 0, nImages = 0, pntCount = 0; + double* pnts = 0; + + // get actual number of images in the tiff file + do { + nImages++; + } while (TIFFReadDirectory(tiff)); + if (nImages > 1) + std::cout << "VtkRaster::loadImageFromTIFF() - File contains " << + nImages << " images. This method is not tested for this case." << + std::endl; + + // get image size + TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &imgWidth); + TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &imgHeight); + + // get cellsize + // Note: GeoTiff allows anisotropic pixels. This is not supported here and equilateral pixels are assumed. + if (TIFFGetField(tiff, GTIFF_PIXELSCALE, &pntCount, &pnts)) + { + if (pnts[0] != pnts[1]) + std::cout << + "VtkRaster::loadImageFromTIFF() - Warning: Original raster data has anisotrop pixel size!" + << std::endl; + cellsize = pnts[0]; + } + + // get upper left point / origin + if (TIFFGetField(tiff, GTIFF_TIEPOINTS, &pntCount, &pnts)) + { + x0 = pnts[3]; + y0 = pnts[4] - (imgHeight * cellsize); // the origin should be the lower left corner of the img + } + + // read pixel values + uint32* pixVal = + (uint32*) _TIFFmalloc(imgWidth * imgHeight * sizeof (uint32)); + if ((imgWidth > 0) && (imgHeight > 0)) + if (!TIFFReadRGBAImage(tiff, imgWidth, imgHeight, pixVal, 0)) + { + std::cout << + "VtkRaster::loadImageFromTIFF() - Error reading GeoTIFF file." + << std::endl; + _TIFFfree(pixVal); + GTIFFree(geoTiff); + XTIFFClose(tiff); + return false; + } + + // check for colormap + uint16 photometric; + TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); + // read colormap + uint16* cmap_red = NULL, * cmap_green = NULL, * cmap_blue = NULL; + int colormap_used = TIFFGetField(tiff, + TIFFTAG_COLORMAP, + &cmap_red, + &cmap_green, + &cmap_blue); + + float* data = new float[imgWidth * imgHeight * 4]; + int* pxl (new int[4]); + for (int j = 0; j < imgHeight; j++) + { + int lineindex = j * imgWidth; + for (int i = 0; i < imgWidth; i++) + { // scale intensities and set nodata values to white (i.e. the background colour) + size_t pxl_idx(lineindex+i); + size_t pos = 4 * (pxl_idx); + if (photometric==1) + { + int idx = TIFFGetR(pixVal[pxl_idx]); + data[pos] = cmap_red[idx] >> 8; + data[pos+1] = cmap_green[idx] >> 8; + data[pos+2] = cmap_blue[idx] >> 8; + data[pos+3] = 1; + } + else + { + data[pos] = TIFFGetR(pixVal[pxl_idx]); + data[pos+1] = TIFFGetG(pixVal[pxl_idx]); + data[pos+2] = TIFFGetB(pixVal[pxl_idx]); + data[pos+3] = TIFFGetA(pixVal[pxl_idx]); + } + } + } + delete [] pxl; + + // set transparency values according to maximum pixel value + if (photometric==1) + { + float max_val(0); + size_t nPixels = 4*imgWidth*imgHeight; + for (size_t j = 0; j < nPixels; j++) + if (data[j]>max_val) + max_val = data[j]; + + for (size_t j = 0; j < nPixels; j+=4) + data[j+3] = max_val; + } + + vtkImageImport* image = vtkImageImport::New(); + image->SetDataOrigin(x0, y0, 0); + image->SetDataSpacing(cellsize, cellsize, cellsize); + image->SetWholeExtent(0, imgWidth-1, 0, imgHeight-1, 0, 0); + image->SetDataExtent(0, imgWidth-1, 0, imgHeight-1, 0, 0); + image->SetDataExtentToWholeExtent(); + image->SetDataScalarTypeToFloat(); + image->SetNumberOfScalarComponents(4); + image->SetImportVoidPointer(data, 0); + image->Update(); + + _TIFFfree(pixVal); + GTIFFree(geoTiff); + XTIFFClose(tiff); + return image; + } + + XTIFFClose(tiff); + std::cout << + "VtkRaster::loadImageFromTIFF() - File not recognised as GeoTIFF-Image." << + std::endl; + return NULL; + } + + std::cout << "VtkRaster::loadImageFromTIFF() - File not recognised as TIFF-Image." << + std::endl; + return NULL; +} +#endif + +vtkImageReader2* VtkRaster::loadImageFromFile(const std::string &fileName) +{ + QString file_name (QString::fromStdString(fileName)); + QFileInfo fi(file_name); + vtkImageReader2* image(NULL); + + if (fi.suffix().toLower() == "png") + image = vtkPNGReader::New(); + else if ((fi.suffix().toLower() == "jpg") || (fi.suffix().toLower() == "jpeg")) + image = vtkJPEGReader::New(); + else if (fi.suffix().toLower() == "bmp") + image = vtkBMPReader::New(); + else + { + std::cout << "VtkRaster::readImageFromFile() - File format not support, please convert to BMP, JPG, PNG or TIFF..." << std::endl; + return NULL; + } + + image->SetFileName(fileName.c_str()); + image->GetOutput()->SetScalarTypeToFloat(); + image->Update(); + return image; +} + +void VtkRaster::uint32toRGBA(const unsigned int s, int* p) +{ + p[3] = s / (256 * 256 * 256); + int r = s % (256 * 256 * 256); + p[2] = r / (256 * 256); + r %= (256 * 256); + p[1] = r / 256; + p[0] = r % 256; +} diff --git a/VtkVis/VtkRaster.h b/VtkVis/VtkRaster.h new file mode 100644 index 00000000000..f74797b352c --- /dev/null +++ b/VtkVis/VtkRaster.h @@ -0,0 +1,145 @@ +/** + * \file VtkRaster.h + * 2012/02/01 KR Initial implementation + * + */ +#ifndef VTKRASTER_H +#define VTKRASTER_H + +#include <fstream> + +class vtkImageAlgorithm; +class vtkImageImport; +class vtkImageReader2; + +/** + * \brief Loading raster data such as images or ArcGIS-data into VTK image data structures. + * + * The VtkRaster class enables loading of raster data such as images or ArcGIS-data. Supported image formats are ..... + * Georeferenced data can be imported via the GeoTIFF- or asc-format. + */ +class VtkRaster +{ + /// Data structure for the asc-file header. + struct ascHeader + { + int ncols; + int nrows; + double x; + double y; + double cellsize; + std::string noData; + }; + +public: + /** + * \brief Loads an image- or raster-file into an vtkImageAlgorithm-Object. + * + * Public method for loading all data formats. Internally the method automatically differentiates between + * images and georeferenced files and then calls the appropriate method for reading the file. + * \param fileName Filename of the file that should be loaded. + * \param x0 X-coordinate of the upper left corner of the data set, the default value is 0. + * \param y0 Y-coordinate of the upper left corner of the data set, the default value is 0. + * \param delta The size of each pixel in the image which is needed for correctly displaying the data, the default value is 1. + * \return The ImageAlgorithm-object. + */ + static vtkImageAlgorithm* loadImage(const std::string &fileName, + double& x0, + double& y0, + double& delta); + + /** + * \brief Loads an ASC file into a double array. + * The array alternates between pixel values and their respective alpha-values, i.e. + * result = { pixel0-value; pixel0-alpha, pixel1-value; pixel1-alpha; ... } + * + * \param fileName Filename of the file that should be loaded. + * \param x0 The x-coordinate of the origin. + * \param y0 The y-coordinate of the origin. + * \param width The width of the image. + * \param height The height of the image + * \param delta The size of each pixel in the image which is needed for correctly displaying the data. + * \return A float-array of pixel values incl. opacity (noData values are transparent) + */ + static float* loadDataFromASC(const std::string &fileName, + double &x0, + double &y0, + size_t &width, + size_t &height, + double &delta); + + /** + * \brief Loads an ASC file into a double array. + * Works exactly like loadDataFromASC(). + */ + static float* loadDataFromSurfer(const std::string &fileName, + double &x0, + double &y0, + size_t &width, + size_t &height, + double &delta); + + /** + * \brief Returns a VtkImageAlgorithm from an array of pixel values and some image meta data. + */ + static vtkImageImport* loadImageFromArray(double* data_array, + double &x0, + double &y0, + size_t &width, + size_t &height, + double &delta, + double noData); + +private: + /** + * Loads ArcGIS asc-files to a vtkImageImport object. + * \param fileName Filename of the file that should be loaded. + * \param x0 The x-coordinate of the origin. + * \param y0 The y-coordinate of the origin. + * \param delta The size of each pixel in the image which is needed for correctly displaying the data. + * \return A vtkImageImport-object (derived from vtkImageAlgorithm). + */ + static vtkImageImport* loadImageFromASC(const std::string &fileName, + double& x0, double& y0, double& delta); + + /** + * Loads ArcGIS asc-files to a QPixmap object and automatically does a contrast stretching to adjust values to 8 bit greyscale images. + * \param fileName Filename of the file that should be loaded. + * \param raster The QPixmap into which the raster data will be written. + * \param origin The upper left corner of the data set + * \param delta The size of each pixel in the image which is needed for correctly displaying the data. + * \return A vtkImageImport-object (derived from vtkImageAlgorithm). + */ +#ifdef libgeotiff_FOUND + static vtkImageImport* loadImageFromTIFF(const std::string &fileName, + double& x0, double& y0, double& delta); +#endif + + /** + * Loads image files into a QPixmap object. Since images are not geo-referenced no origin point will be returned. + * \param fileName Filename of the file that should be loaded. + * \return vtkImageReader2-object containing the image data. + */ + static vtkImageReader2* loadImageFromFile(const std::string &fileName); + + /** + * Reads the header of an ArcGIS asc-file. + * \param header The ascHeader-object into which all the information will be written. + * \param in FileInputStream used for reading the data. + * \return True if the header could be read correctly, false otherwise. + */ + static bool readASCHeader(ascHeader &header, std::ifstream &in); + + /** + * Reads the header of a Surfer grd-file. + * \param header The ascHeader-object into which all the information will be written. + * \param in FileInputStream used for reading the data. + * \return True if the header could be read correctly, false otherwise. + */ + static bool readSurferHeader(ascHeader &header, std::ifstream &in); + + /// Converts an uint32-number into a quadruple representing RGBA-colours for a pixel. + static void uint32toRGBA(const unsigned int s, int* p); +}; + +#endif //VTKRASTER_H diff --git a/VtkVis/VtkSelectionFilter.h b/VtkVis/VtkSelectionFilter.h index 41df9e5bea3..c58e6f6ee65 100644 --- a/VtkVis/VtkSelectionFilter.h +++ b/VtkVis/VtkSelectionFilter.h @@ -9,8 +9,11 @@ // ** INCLUDES ** #include "VtkAlgorithmProperties.h" + #include <vtkUnstructuredGridAlgorithm.h> +#include <vector> + class VtkSelectionFilter : public vtkUnstructuredGridAlgorithm, public VtkAlgorithmProperties { public: diff --git a/VtkVis/VtkStationSource.cpp b/VtkVis/VtkStationSource.cpp index 3af0866f47c..ccf6bea5a92 100644 --- a/VtkVis/VtkStationSource.cpp +++ b/VtkVis/VtkStationSource.cpp @@ -11,6 +11,7 @@ #include "VtkStationSource.h" #include "vtkObjectFactory.h" +#include <vtkDoubleArray.h> #include <vtkCellArray.h> #include <vtkCellData.h> #include <vtkInformation.h> @@ -21,6 +22,7 @@ #include <vtkPolyData.h> #include <vtkSmartPointer.h> #include <vtkStreamingDemandDrivenPipeline.h> +#include <vtkProperty.h> vtkStandardNewMacro(VtkStationSource); vtkCxxRevisionMacro(VtkStationSource, "$Revision$"); @@ -28,6 +30,7 @@ vtkCxxRevisionMacro(VtkStationSource, "$Revision$"); VtkStationSource::VtkStationSource() : _stations(NULL) { + _removable = false; // From VtkAlgorithmProperties this->SetNumberOfInputPorts(0); const GEOLIB::Color* c = GEOLIB::getRandomColor(); @@ -76,6 +79,15 @@ int VtkStationSource::RequestData( vtkInformation* request, if (nStations == 0) return 0; + bool useStationValues(false); + double sValue=static_cast<GEOLIB::Station*>((*_stations)[0])->getStationValue(); + for (size_t i = 1; i < nStations; i++) + if (static_cast<GEOLIB::Station*>((*_stations)[i])->getStationValue() != sValue) + { + useStationValues = true; + break; + } + bool isBorehole = (static_cast<GEOLIB::Station*>((*_stations)[0])->type() == GEOLIB::Station::BOREHOLE) ? true : false; @@ -100,6 +112,10 @@ int VtkStationSource::RequestData( vtkInformation* request, station_ids->SetNumberOfComponents(1); station_ids->SetName("SiteIDs"); + vtkSmartPointer<vtkDoubleArray> station_values = vtkSmartPointer<vtkDoubleArray>::New(); + station_values->SetNumberOfComponents(1); + station_values->SetName("StationValue"); + vtkSmartPointer<vtkIntArray> strat_ids = vtkSmartPointer<vtkIntArray>::New(); strat_ids->SetNumberOfComponents(1); strat_ids->SetName("Stratigraphies"); @@ -114,6 +130,8 @@ int VtkStationSource::RequestData( vtkInformation* request, double coords[3] = { (*(*it))[0], (*(*it))[1], (*(*it))[2] }; vtkIdType sid = newStations->InsertNextPoint(coords); station_ids->InsertNextValue(site_count); + if (useStationValues) + station_values->InsertNextValue(static_cast<GEOLIB::Station*>(*it)->getStationValue()); if (!isBorehole) newVerts->InsertNextCell(1, &sid); @@ -137,6 +155,8 @@ int VtkStationSource::RequestData( vtkInformation* request, newLines->InsertCellPoint(lastMaxIndex + 1); //end of boreholelayer lastMaxIndex++; strat_ids->InsertNextValue(this->GetIndexByName(soilNames[i])); + if (useStationValues) + station_values->InsertNextValue(static_cast<GEOLIB::Station*>(*it)->getStationValue()); } lastMaxIndex++; } @@ -157,7 +177,9 @@ int VtkStationSource::RequestData( vtkInformation* request, output->GetCellData()->SetActiveAttribute("Stratigraphies", vtkDataSetAttributes::SCALARS); } - + if (useStationValues) + output->GetPointData()->AddArray(station_values); + return 1; } @@ -191,8 +213,9 @@ size_t VtkStationSource::GetIndexByName( std::string name ) if (it->second > max_key) max_key = it->second; } - vtkIdType new_index(max_key + 1); - std::cout << "Key \"" << name << "\" not found in color lookup table..." << std::endl; + + vtkIdType new_index = (_id_map.empty()) ? 0 : (max_key+1); + std::cout << "Key \"" << name << "\" (Index " << new_index << ") not found in color lookup table..." << std::endl; _id_map.insert(std::pair<std::string, vtkIdType>(name, new_index)); return new_index; } diff --git a/VtkVis/VtkSurfacesSource.cpp b/VtkVis/VtkSurfacesSource.cpp index 3e0a9216508..fc7c47b42b0 100644 --- a/VtkVis/VtkSurfacesSource.cpp +++ b/VtkVis/VtkSurfacesSource.cpp @@ -20,6 +20,7 @@ #include <vtkPolygon.h> #include <vtkSmartPointer.h> #include <vtkStreamingDemandDrivenPipeline.h> +#include <vtkProperty.h> vtkStandardNewMacro(VtkSurfacesSource); vtkCxxRevisionMacro(VtkSurfacesSource, "$Revision$"); @@ -27,6 +28,7 @@ vtkCxxRevisionMacro(VtkSurfacesSource, "$Revision$"); VtkSurfacesSource::VtkSurfacesSource() : _surfaces(NULL) { + _removable = false; // From VtkAlgorithmProperties this->SetNumberOfInputPorts(0); //this->SetColorBySurface(true); diff --git a/VtkVis/VtkTextureOnSurfaceFilter.cpp b/VtkVis/VtkTextureOnSurfaceFilter.cpp index a7fe3d3086c..e2721911148 100644 --- a/VtkVis/VtkTextureOnSurfaceFilter.cpp +++ b/VtkVis/VtkTextureOnSurfaceFilter.cpp @@ -15,13 +15,15 @@ #include <vtkPointData.h> #include <vtkSmartPointer.h> #include <vtkStreamingDemandDrivenPipeline.h> +#include <vtkImageShiftScale.h> +#include <vtkImageAlgorithm.h> +#include <vtkProperty.h> +#include <vtkTexture.h> #include "MathTools.h" #include "VtkTextureOnSurfaceFilter.h" #include "VtkVisHelper.h" -#include <QImage> - vtkStandardNewMacro(VtkTextureOnSurfaceFilter); vtkCxxRevisionMacro(VtkTextureOnSurfaceFilter, "$Revision$"); @@ -67,18 +69,42 @@ int VtkTextureOnSurfaceFilter::RequestData( vtkInformation* request, //calculate texture coordinates vtkPoints* points = input->GetPoints(); vtkSmartPointer<vtkFloatArray> textureCoordinates = vtkSmartPointer<vtkFloatArray>::New(); - textureCoordinates->SetNumberOfComponents(3); + textureCoordinates->SetNumberOfComponents(2); textureCoordinates->SetName("TextureCoordinates"); size_t nPoints = points->GetNumberOfPoints(); +/* // adaptation for netcdf-curtain for TERENO Demo + double dist(0.0); + for (size_t i = 0; i < nPoints; i++) + { + double coords[3]; + if ((i==0) || (i==173)) + { + if (i==0) dist=0; + } + else + { + points->GetPoint(i-1, coords); + GEOLIB::Point* pnt = new GEOLIB::Point(coords); + points->GetPoint(i, coords); + GEOLIB::Point* pnt2 = new GEOLIB::Point(coords); + if (i<173) + dist += sqrt(MathLib::sqrDist(pnt, pnt2)); + else + dist -= sqrt(MathLib::sqrDist(pnt, pnt2)); + } + points->GetPoint(i, coords); + double x = MathLib::normalize(0, 8404, dist); + double z = MathLib::normalize(-79.5, 1.5, coords[2]); + float newcoords[2] = {x, z}; + textureCoordinates->InsertNextTuple(newcoords); + } +*/ for (size_t i = 0; i < nPoints; i++) { double coords[3]; points->GetPoint(i, coords); - float newcoords[3] = - {MathLib::normalize(min.first, max.first, coords[0]), MathLib::normalize(min.second, - max.second, - coords[1]), - 0 /*coords[2]*/ }; + float newcoords[2] = { MathLib::normalize(min.first, max.first, coords[0]), + MathLib::normalize(min.second,max.second, coords[1])}; textureCoordinates->InsertNextTuple(newcoords); } @@ -93,14 +119,29 @@ int VtkTextureOnSurfaceFilter::RequestData( vtkInformation* request, return 1; } -void VtkTextureOnSurfaceFilter::SetRaster(QImage &img, - std::pair<float, float> origin, +void VtkTextureOnSurfaceFilter::SetRaster(vtkImageAlgorithm* img, + double x0, double y0, double scalingFactor) { - _origin = origin; + double range[2]; + img->Update(); + img->GetOutput()->GetPointData()->GetScalars()->GetRange(range); + vtkSmartPointer<vtkImageShiftScale> scale = vtkSmartPointer<vtkImageShiftScale>::New(); + scale->SetInputConnection(img->GetOutputPort()); + scale->SetShift(-range[0]); + scale->SetScale(255.0/(range[1]-range[0])); + scale->SetOutputScalarTypeToUnsignedChar(); // Comment this out to get colored grayscale textures + scale->Update(); + + vtkTexture* texture = vtkTexture::New(); + texture->InterpolateOff(); + texture->RepeatOff(); + // texture->EdgeClampOn(); // does not work + texture->SetInput(scale->GetOutput()); + this->SetTexture(texture); + + _origin = std::pair<float, float>(static_cast<float>(x0), static_cast<float>(y0)); _scalingFactor = scalingFactor; - QImage raster = img.transformed(QTransform(1, 0, 0, -1, 0, 0), Qt::FastTransformation); - this->SetTexture(VtkVisHelper::QImageToVtkTexture(raster)); } void VtkTextureOnSurfaceFilter::SetUserProperty( QString name, QVariant value ) diff --git a/VtkVis/VtkTextureOnSurfaceFilter.h b/VtkVis/VtkTextureOnSurfaceFilter.h index ad47c1b55f6..2db29b931b9 100644 --- a/VtkVis/VtkTextureOnSurfaceFilter.h +++ b/VtkVis/VtkTextureOnSurfaceFilter.h @@ -13,6 +13,7 @@ #include <vtkPolyDataAlgorithm.h> class QImage; +class vtkImageAlgorithm; /** * \brief Filter class for assigning a texture to a surface. @@ -38,7 +39,7 @@ public: void PrintSelf(ostream& os, vtkIndent indent); /// Sets the raster/image to be used as a texture map - void SetRaster(QImage &img, std::pair<float, float> origin, double scalingFactor); + void SetRaster(vtkImageAlgorithm* img, double x0, double y0, double scalingFactor); virtual void SetUserProperty(QString name, QVariant value); diff --git a/VtkVis/VtkVisImageItem.cpp b/VtkVis/VtkVisImageItem.cpp index 11e784c0741..b523a0116e9 100644 --- a/VtkVis/VtkVisImageItem.cpp +++ b/VtkVis/VtkVisImageItem.cpp @@ -6,13 +6,17 @@ // ** INCLUDES ** #include "VtkAlgorithmProperties.h" #include "VtkVisImageItem.h" +#include "VtkGeoImageSource.h" #include <vtkActor.h> #include <vtkDataSetMapper.h> #include <vtkImageAlgorithm.h> #include <vtkImageChangeInformation.h> +#include <vtkImageData.h> +#include <vtkPointData.h> #include <vtkRenderer.h> #include <vtkSmartPointer.h> +#include <vtkImageShiftScale.h> // export #include <vtkImageActor.h> @@ -39,8 +43,30 @@ VtkVisImageItem::~VtkVisImageItem() void VtkVisImageItem::Initialize(vtkRenderer* renderer) { + vtkImageAlgorithm* img = dynamic_cast<vtkImageAlgorithm*>(_algorithm); + img->Update(); + //VtkGeoImageSource* img = dynamic_cast<VtkGeoImageSource*>(_algorithm); + + double origin[3]; + double spacing[3]; + double range[2]; + img->GetOutput()->GetOrigin(origin); + img->GetOutput()->GetSpacing(spacing); + //img->getRange(range); + img->GetOutput()->GetPointData()->GetScalars()->GetRange(range); + vtkImageShiftScale* scale = vtkImageShiftScale::New(); + scale->SetOutputScalarTypeToUnsignedChar(); + scale->SetInputConnection(img->GetOutputPort()); + scale->SetShift(-range[0]); + scale->SetScale(255.0/(range[1]-range[0])); + _transformFilter = vtkImageChangeInformation::New(); - _transformFilter->SetInputConnection(_algorithm->GetOutputPort()); + _transformFilter->SetInputConnection(scale->GetOutputPort()); + //double origin[3]; + //img->getOrigin(origin); + //double spacing = img->getSpacing(); + //_transformFilter->SetOutputOrigin(origin2); + //_transformFilter->SetOutputSpacing(spacing2); _transformFilter->Update(); _renderer = renderer; diff --git a/VtkVis/VtkVisPipeline.cpp b/VtkVis/VtkVisPipeline.cpp index 6ed962d5d94..c44f094baef 100644 --- a/VtkVis/VtkVisPipeline.cpp +++ b/VtkVis/VtkVisPipeline.cpp @@ -240,6 +240,21 @@ void VtkVisPipeline::setGlobalSuperelevation(double factor) const emit vtkVisPipelineChanged(); } +void VtkVisPipeline::setGlobalBackfaceCulling(bool enable) const +{ + // iterate over all source items + for (int i = 0; i < _rootItem->childCount(); ++i) + { + VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(_rootItem->child(i)); + item->setBackfaceCulling(enable); + + // recursively set on all child items + item->setBackfaceCullingOnChildren(enable); + } + + emit vtkVisPipelineChanged(); +} + void VtkVisPipeline::addPipelineItem(GeoTreeModel* model, const std::string &name, GEOLIB::GEOTYPE type) @@ -283,10 +298,8 @@ QModelIndex VtkVisPipeline::addPipelineItem(VtkVisPipelineItem* item, const QMod _actorMap.insert(item->actor(), newIndex); // Do not interpolate images -#ifndef OGS_USE_OPENSG if (dynamic_cast<vtkImageAlgorithm*>(item->algorithm())) static_cast<vtkImageActor*>(item->actor())->InterpolateOff(); -#endif // OGS_USE_OPENSG reset(); emit vtkVisPipelineChanged(); @@ -299,10 +312,6 @@ QModelIndex VtkVisPipeline::addPipelineItem( vtkAlgorithm* source, { TreeItem* parentItem = getItem(parent); - // If the parent is not the root TreeItem - //if (parent.isValid()) - // VtkVisPipelineItem* visParentItem = static_cast<VtkVisPipelineItem*>(parentItem); - QList<QVariant> itemData; QString itemName; if (!parent.isValid()) // if source object diff --git a/VtkVis/VtkVisPipeline.h b/VtkVis/VtkVisPipeline.h index 8fbefb0d561..1594232a928 100644 --- a/VtkVis/VtkVisPipeline.h +++ b/VtkVis/VtkVisPipeline.h @@ -82,6 +82,9 @@ public: /// the factor on other items to 1. void setGlobalSuperelevation(double factor) const; + /// \brief Enables / disables backface culling on all actors. + void setGlobalBackfaceCulling(bool enable) const; + public slots: /// \brief Adds the given Model to the pipeline. void addPipelineItem(MshModel* model, const QModelIndex &idx); diff --git a/VtkVis/VtkVisPipelineItem.cpp b/VtkVis/VtkVisPipelineItem.cpp index cc2fe2cb975..fd79579b341 100644 --- a/VtkVis/VtkVisPipelineItem.cpp +++ b/VtkVis/VtkVisPipelineItem.cpp @@ -8,6 +8,7 @@ // ** INCLUDES ** #include "VtkAlgorithmProperties.h" #include "VtkVisPipelineItem.h" +#include "VtkCompositeFilter.h" #include "QVtkDataSetMapper.h" #include <vtkActor.h> @@ -18,15 +19,12 @@ #include <vtkRenderer.h> #include <vtkSmartPointer.h> #include <vtkTextureMapToPlane.h> - #include <vtkGenericDataObjectWriter.h> - -#include <QMessageBox> - -#include "VtkCompositeFilter.h" - #include <vtkCellData.h> #include <vtkPointData.h> +#include <vtkImageActor.h> + +#include <QMessageBox> #ifdef OGS_USE_OPENSG #include "vtkOsgConverter.h" @@ -37,7 +35,7 @@ VtkVisPipelineItem::VtkVisPipelineItem( vtkAlgorithm* algorithm, TreeItem* parentItem, const QList<QVariant> data /*= QList<QVariant>()*/) : TreeItem(data, parentItem), _actor(NULL), _algorithm(algorithm), - _renderer(NULL),_compositeFilter(NULL) + _renderer(NULL), _compositeFilter(NULL), _vtkProps(NULL) { VtkVisPipelineItem* visParentItem = dynamic_cast<VtkVisPipelineItem*>(parentItem); if (parentItem->parentItem()) @@ -47,7 +45,8 @@ VtkVisPipelineItem::VtkVisPipelineItem( VtkVisPipelineItem::VtkVisPipelineItem( VtkCompositeFilter* compositeFilter, TreeItem* parentItem, const QList<QVariant> data /*= QList<QVariant>()*/) - : TreeItem(data, parentItem), _actor(NULL), _renderer(NULL), _compositeFilter(compositeFilter) + : TreeItem(data, parentItem), _actor(NULL), _renderer(NULL), _compositeFilter(compositeFilter), + _vtkProps(NULL) { _algorithm = _compositeFilter->GetOutputAlgorithm(); } @@ -105,15 +104,21 @@ int VtkVisPipelineItem::writeToFile(const std::string &filename) const if (filename.substr(filename.size() - 4).find("os") != std::string::npos) { #ifdef OGS_USE_OPENSG - vtkOsgConverter osgConverter(static_cast<vtkActor*>(_actor)); - if(osgConverter.WriteAnActor()) - OSG::SceneFileHandler::the().write( - osgConverter.GetOsgNode(), filename.c_str()); -#else + if(!dynamic_cast<vtkImageActor*>(_actor)) + { + vtkOsgConverter osgConverter(static_cast<vtkActor*>(_actor)); + if(osgConverter.WriteAnActor()) + OSG::SceneFileHandler::the().write( + osgConverter.GetOsgNode(), filename.c_str()); + } + else + QMessageBox::warning(NULL, "Conversion to OpenSG not possible", + "It is not possible to convert an vtkImageData based object\nto OpenSG. If you want to convert raster data import it via \" File / Import / Raster Files as PolyData\"!"); +#else QMessageBox::warning( - NULL, - "Functionality not implemented", - "Sorry but this program was not compiled with OpenSG support."); + NULL, + "Functionality not implemented", + "Sorry but this program was not compiled with OpenSG support."); #endif return 0; } @@ -156,3 +161,40 @@ void VtkVisPipelineItem::setScaleOnChildren(double x, double y, double z) const child->setScale(x, y, z); } } + +void VtkVisPipelineItem::setBackfaceCulling(bool enable) const +{ + // Reimplemented in subclass + (void)enable; +} + +void VtkVisPipelineItem::setBackfaceCullingOnChildren(bool enable) const +{ + for (int i = 0; i < this->childCount(); ++i) + { + VtkVisPipelineItem* child = this->child(i); + child->setBackfaceCulling((int)enable); + child->setBackfaceCullingOnChildren((int)enable); + } +} + +QStringList VtkVisPipelineItem::getScalarArrayNames() const +{ + vtkDataSet* dataSet = vtkDataSet::SafeDownCast(this->algorithm()->GetOutputDataObject(0)); + QStringList dataSetAttributesList; + if (dataSet) + { + vtkPointData* pointData = dataSet->GetPointData(); + //std::cout << " #point data arrays: " << pointData->GetNumberOfArrays() << std::endl; + for (int i = 0; i < pointData->GetNumberOfArrays(); i++) + //std::cout << " Name: " << pointData->GetArrayName(i) << std::endl; + dataSetAttributesList.push_back(QString("P-") + pointData->GetArrayName(i)); + + vtkCellData* cellData = dataSet->GetCellData(); + //std::cout << " #cell data arrays: " << cellData->GetNumberOfArrays() << std::endl; + for (int i = 0; i < cellData->GetNumberOfArrays(); i++) + //std::cout << " Name: " << cellData->GetArrayName(i) << std::endl; + dataSetAttributesList.push_back(QString("C-") + cellData->GetArrayName(i)); + } + return dataSetAttributesList; +} \ No newline at end of file diff --git a/VtkVis/VtkVisPipelineItem.h b/VtkVis/VtkVisPipelineItem.h index 9c07af2e58b..dc35c1ff980 100644 --- a/VtkVis/VtkVisPipelineItem.h +++ b/VtkVis/VtkVisPipelineItem.h @@ -17,6 +17,7 @@ #include <QString> #include <QVariant> +class QStringList; class vtkAlgorithm; class vtkDataSetAttributes; class vtkPointSet; @@ -83,7 +84,8 @@ public: /// @brief Sets the visibility of the VTK object in the visualization. void setVisible(bool visible); - /// @brief Writes this algorithm's vtkDataSet (i.e. vtkPolyData or vtkUnstructuredGrid) to a vtk-file. + /// @brief Writes this algorithm's vtkDataSet (i.e. vtkPolyData or vtkUnstructuredGrid) + /// to a vtk-file. int writeToFile(const std::string &filename) const; /** @@ -92,6 +94,10 @@ public: */ virtual void setScale(double x, double y, double z) const; + /// @brief Sets the geometry and date scaling recursively on all children of + /// this item. + void setScaleOnChildren(double x, double y, double z) const; + /** * @brief Translates the item in visualisation-space. * This function is empty and needs to be implemented by derived classes. @@ -104,9 +110,18 @@ public: */ virtual vtkAlgorithm* transformFilter() const = 0; - /// @brief Sets the geometry and date scaling recursively on all children of - /// this item. - void setScaleOnChildren(double x, double y, double z) const; + /// @brief Enables / disables backface culling. + virtual void setBackfaceCulling(bool enable) const; + + /// @brief Enables / disables backface culling on all children. + void setBackfaceCullingOnChildren(bool enable) const; + + /// @brief Returns a list of array names prefixed with P- or C- + /// for point and cell data. + QStringList getScalarArrayNames() const; + + /// @brief Returns the VtkAlgorithmProperties. + VtkAlgorithmProperties* getVtkProperties() const { return _vtkProps; }; protected: vtkProp3D* _actor; @@ -114,6 +129,10 @@ protected: vtkRenderer* _renderer; VtkCompositeFilter* _compositeFilter; + /// @brief The active VtkAlgorithmProperties. + /// From algorithm, compositeFilter, or copied from parent + VtkAlgorithmProperties* _vtkProps; + /** * Selects the appropriate VTK-Writer object and writes the object to a file with the given name. * This function is empty and needs to be implemented by derived classes. diff --git a/VtkVis/VtkVisPipelineView.cpp b/VtkVis/VtkVisPipelineView.cpp index 32aae875e09..edbf601c73b 100644 --- a/VtkVis/VtkVisPipelineView.cpp +++ b/VtkVis/VtkVisPipelineView.cpp @@ -11,6 +11,7 @@ #include "CheckboxDelegate.h" #include "VtkVisPipeline.h" #include "VtkVisPipelineItem.h" +#include "VtkVisPointSetItem.h" #include <vtkDataSetMapper.h> #include <vtkProp3D.h> @@ -21,21 +22,23 @@ #include <QHeaderView> #include <QMenu> #include <QSettings> +#include <QMessageBox> //image to mesh conversion +#include "msh_mesh.h" +#include "GridAdapter.h" #include "VtkGeoImageSource.h" +#include <vtkImageData.h> #include "MeshFromRasterDialog.h" #include <vtkDataObject.h> -#include <vtkImageData.h> #include <vtkSmartPointer.h> - -#include "msh_mesh.h" #include <vtkGenericDataObjectReader.h> #include <vtkTransformFilter.h> #include <vtkUnstructuredGrid.h> #include <vtkUnstructuredGridAlgorithm.h> #include <vtkXMLUnstructuredGridReader.h> + VtkVisPipelineView::VtkVisPipelineView( QWidget* parent /*= 0*/ ) : QTreeView(parent) { @@ -62,13 +65,10 @@ void VtkVisPipelineView::contextMenuEvent( QContextMenuEvent* event ) if (index.isValid()) { // check object type - vtkAlgorithm* algorithm = - static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>(this->model()) - -> - getItem(this->selectionModel()-> - currentIndex()))->algorithm(); - int objectType = algorithm->GetOutputDataObject(0)->GetDataObjectType(); - VtkAlgorithmProperties* vtkProps = dynamic_cast<VtkAlgorithmProperties*>(algorithm); + VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>( + this->model())->getItem(this->selectionModel()->currentIndex())); + int objectType = item->algorithm()->GetOutputDataObject(0)->GetDataObjectType(); + VtkAlgorithmProperties* vtkProps = item->getVtkProperties(); bool isSourceItem = (this->selectionModel()->currentIndex().parent().isValid()) ? 0 : 1; @@ -79,7 +79,8 @@ void VtkVisPipelineView::contextMenuEvent( QContextMenuEvent* event ) QAction* addMeshingAction(NULL); if (objectType == VTK_IMAGE_DATA) { - isSourceItem = false; // this exception is needed as image object are only displayed in the vis-pipeline + // this exception is needed as image object are only displayed in the vis-pipeline + isSourceItem = false; addMeshingAction = menu.addAction("Convert Image to Mesh..."); connect(addMeshingAction, SIGNAL(triggered()), this, SLOT(showImageToMeshConversionDialog())); @@ -101,7 +102,7 @@ void VtkVisPipelineView::contextMenuEvent( QContextMenuEvent* event ) QAction* exportVtkAction = menu.addAction("Export as VTK"); QAction* exportOsgAction = menu.addAction("Export as OpenSG"); QAction* removeAction = NULL; - if (!isSourceItem || vtkProps == NULL) + if (!isSourceItem || vtkProps->IsRemovable()) { removeAction = menu.addAction("Remove"); connect(removeAction, SIGNAL(triggered()), this, @@ -175,20 +176,22 @@ void VtkVisPipelineView::constructMeshFromImage(QString msh_name, MshElemType::t getItem(this->selectionModel()->currentIndex()))->algorithm(); vtkSmartPointer<VtkGeoImageSource> imageSource = VtkGeoImageSource::SafeDownCast(algorithm); - vtkSmartPointer<vtkImageData> image = imageSource->GetOutput(); + double origin[3]; + imageSource->GetOutput()->GetOrigin(origin); + double spacing[3]; + imageSource->GetOutput()->GetSpacing(spacing); - MeshLib::CFEMesh* mesh = VtkMeshConverter::convertImgToMesh(image, imageSource->getOrigin(), - imageSource->getSpacing(), - element_type, intensity_type); - std::string new_mesh_name(msh_name.toStdString()); - emit meshAdded(mesh, new_mesh_name); + GridAdapter* mesh = VtkMeshConverter::convertImgToMesh(imageSource->GetOutput(), origin, spacing[0], element_type, intensity_type); + mesh->setName(msh_name.toStdString()); + emit meshAdded(mesh); } void VtkVisPipelineView::convertVTKToOGSMesh() { - vtkSmartPointer<vtkAlgorithm> algorithm = - static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>(this->model())->getItem( - this->selectionModel()->currentIndex()))->algorithm(); + VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>(this->model())->getItem( + this->selectionModel()->currentIndex())); + vtkSmartPointer<vtkAlgorithm> algorithm = item->algorithm(); + vtkUnstructuredGrid* grid(NULL); vtkUnstructuredGridAlgorithm* ugAlg = vtkUnstructuredGridAlgorithm::SafeDownCast(algorithm); @@ -207,9 +210,9 @@ void VtkVisPipelineView::convertVTKToOGSMesh() grid = vtkUnstructuredGrid::SafeDownCast(xmlReader->GetOutput()); } } - MeshLib::CFEMesh* mesh = VtkMeshConverter::convertUnstructuredGrid(grid); - std::string msh_name("NewMesh"); - emit meshAdded(mesh, msh_name); + GridAdapter* mesh = VtkMeshConverter::convertUnstructuredGrid(grid); + mesh->setName(item->data(0).toString().toStdString()); + emit meshAdded(mesh); } void VtkVisPipelineView::selectionChanged( const QItemSelection &selected, @@ -258,23 +261,28 @@ void VtkVisPipelineView::addColorTable() const QString array_name = item->GetActiveAttribute(); QSettings settings("UFZ", "OpenGeoSys-5"); - QString fileName = QFileDialog::getOpenFileName(this, "Select color table", - settings.value( - "lastOpenedTextureFileDirectory"). - toString(), - "Color table files (*.lut);;"); - QFileInfo fi(fileName); + QString filename = QFileDialog::getOpenFileName(this, "Select color table", + settings.value("lastOpenedLutFileDirectory"). toString(), + "Color table files (*.xml);;"); + QFileInfo fi(filename); - if (fi.suffix().toLower() == "lut") + if (fi.suffix().toLower() == "xml") { - VtkAlgorithmProperties* props = - dynamic_cast<VtkAlgorithmProperties*>(item->algorithm()); - if (props) + VtkVisPointSetItem* pointSetItem = dynamic_cast<VtkVisPointSetItem*>(item); + if (pointSetItem) { - const std::string file (fileName.toStdString()); - props->SetLookUpTable(array_name, file); - item->SetActiveAttribute(array_name); - emit requestViewUpdate(); + VtkAlgorithmProperties* props = pointSetItem->getVtkProperties(); + if (props) + { + props->SetLookUpTable(array_name, filename); + item->SetActiveAttribute(array_name); + emit requestViewUpdate(); + } } + else + QMessageBox::warning(NULL, "Color lookup table could not be applied.", + "Color lookup tables can only be applied to VtkVisPointSetItem."); + QDir dir = QDir(filename); + settings.setValue("lastOpenedLutFileDirectory", dir.absolutePath()); } } diff --git a/VtkVis/VtkVisPipelineView.h b/VtkVis/VtkVisPipelineView.h index e2d28ae33ab..652f121398c 100644 --- a/VtkVis/VtkVisPipelineView.h +++ b/VtkVis/VtkVisPipelineView.h @@ -78,7 +78,7 @@ signals: void itemSelected(VtkVisPipelineItem*); void actorSelected(vtkProp3D*); void dataObjectSelected(vtkDataObject*); - void meshAdded(MeshLib::CFEMesh*, std::string&); + void meshAdded(GridAdapter*); }; #endif // VTKVISPIPELINEVIEW_H diff --git a/VtkVis/VtkVisPointSetItem.cpp b/VtkVis/VtkVisPointSetItem.cpp index 39f6ec6af2e..70283bcb10e 100644 --- a/VtkVis/VtkVisPointSetItem.cpp +++ b/VtkVis/VtkVisPointSetItem.cpp @@ -6,6 +6,8 @@ // ** INCLUDES ** #include "VtkAlgorithmProperties.h" #include "VtkVisPointSetItem.h" +#include "VtkCompositeFilter.h" +#include "VtkCompositeThresholdFilter.h" #include <limits> @@ -19,9 +21,13 @@ #include <vtkSmartPointer.h> #include <vtkTransform.h> #include <vtkTransformFilter.h> +#include <vtkProperty.h> +#include <vtkLookupTable.h> #include <QObject> #include <QRegExp> +#include <QSettings> +#include <QStringList> // export test #include <vtkPolyDataAlgorithm.h> @@ -37,7 +43,7 @@ VtkVisPointSetItem::VtkVisPointSetItem( vtkAlgorithm* algorithm, TreeItem* parentItem, const QList<QVariant> data /*= QList<QVariant>()*/) : VtkVisPipelineItem(algorithm, parentItem, data), _mapper(NULL), - _transformFilter(NULL), _activeAttribute("") + _transformFilter(NULL), _onPointData(true), _activeArrayName("") { VtkVisPipelineItem* visParentItem = dynamic_cast<VtkVisPipelineItem*>(parentItem); if (parentItem->parentItem()) @@ -60,7 +66,7 @@ VtkVisPointSetItem::VtkVisPointSetItem( VtkCompositeFilter* compositeFilter, TreeItem* parentItem, const QList<QVariant> data /*= QList<QVariant>()*/) : VtkVisPipelineItem(compositeFilter, parentItem, data), _mapper(NULL), - _transformFilter(NULL), _activeAttribute("") + _transformFilter(NULL), _onPointData(true), _activeArrayName("") { } @@ -69,10 +75,13 @@ VtkVisPointSetItem::~VtkVisPointSetItem() _transformFilter->Delete(); _mapper->Delete(); } +const QString VtkVisPointSetItem::GetActiveAttribute() const +{ + return _vtkProps->GetActiveAttribute(); +} void VtkVisPointSetItem::Initialize(vtkRenderer* renderer) { - _activeAttribute = ""; _transformFilter = vtkTransformFilter::New(); vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New(); transform->Identity(); @@ -90,48 +99,69 @@ void VtkVisPointSetItem::Initialize(vtkRenderer* renderer) static_cast<vtkActor*>(_actor)->SetMapper(_mapper); _renderer->AddActor(_actor); - // Set pre-set properties + // Determine the right pre-set properties + // Order is: _algorithm, _compositeFilter, create a new one with props copied from parent VtkAlgorithmProperties* vtkProps = dynamic_cast<VtkAlgorithmProperties*>(_algorithm); - if (vtkProps) - setVtkProperties(vtkProps); - - // Copy properties from parent - else + if (!vtkProps) { - VtkVisPipelineItem* parentItem = dynamic_cast<VtkVisPipelineItem*>(this->parentItem()); - while (parentItem) + vtkProps = dynamic_cast<VtkAlgorithmProperties*>(_compositeFilter); + + // Copy properties from parent or create a new VtkAlgorithmProperties + if (!vtkProps) { - VtkAlgorithmProperties* parentProps = - dynamic_cast<VtkAlgorithmProperties*>(parentItem->algorithm()); - if (parentProps) + VtkVisPipelineItem* parentItem = dynamic_cast<VtkVisPipelineItem*>(this->parentItem()); + while (parentItem) { - VtkAlgorithmProperties* newProps = new VtkAlgorithmProperties(); - newProps->SetScalarVisibility(parentProps->GetScalarVisibility()); - newProps->SetTexture(parentProps->GetTexture()); - setVtkProperties(newProps); - vtkProps = newProps; - parentItem = NULL; + VtkAlgorithmProperties* parentProps = NULL; + if(dynamic_cast<VtkVisPointSetItem*>(parentItem)) + parentProps = dynamic_cast<VtkVisPointSetItem*>(parentItem)->getVtkProperties(); + if (parentProps) + { + vtkProps = new VtkAlgorithmProperties(); // TODO memory leak? + vtkProps->SetScalarVisibility(parentProps->GetScalarVisibility()); + vtkProps->SetTexture(parentProps->GetTexture()); + vtkProps->SetActiveAttribute(parentProps->GetActiveAttribute()); + parentItem = NULL; + } + else + parentItem = dynamic_cast<VtkVisPipelineItem*>(parentItem->parentItem()); } - else - parentItem = dynamic_cast<VtkVisPipelineItem*>(parentItem->parentItem()); + + // Has no parents + if (!vtkProps) + vtkProps = new VtkAlgorithmProperties(); // TODO memory leak? } } - - // Set active scalar to the desired one from VtkAlgorithmProperties - // or to match those of the parent. - if (vtkProps) + _vtkProps = vtkProps; + + if (vtkProps->GetActiveAttribute().length() == 0) { - if (vtkProps->GetActiveAttribute().length() > 0) - this->SetActiveAttribute(vtkProps->GetActiveAttribute()); + // Get first scalar and set it to active + QStringList arrayNames = this->getScalarArrayNames(); + if (arrayNames.length() > 0) + vtkProps->SetActiveAttribute(arrayNames[0]); else - { - VtkVisPointSetItem* visParentItem = - dynamic_cast<VtkVisPointSetItem*>(this->parentItem()); - if (visParentItem) - this->SetActiveAttribute(visParentItem->GetActiveAttribute()); - if (vtkProps->GetTexture() != NULL) - this->SetActiveAttribute("Solid Color"); - } + vtkProps->SetActiveAttribute("Solid Color"); + } + this->setVtkProperties(vtkProps); + this->SetActiveAttribute(vtkProps->GetActiveAttribute()); + + + // Set global backface culling + QSettings settings("UFZ, OpenGeoSys-5"); + bool backfaceCulling = settings.value("globalCullBackfaces", 0).toBool(); + this->setBackfaceCulling(backfaceCulling); + + // Set the correct threshold range + if (dynamic_cast<VtkCompositeThresholdFilter*>(this->_compositeFilter)) + { + double range[2]; + this->GetRangeForActiveAttribute(range); + QList<QVariant> thresholdRangeList; + thresholdRangeList.push_back(range[0]); + thresholdRangeList.push_back(range[1]); + dynamic_cast<VtkCompositeFilter*>(this->_compositeFilter) + ->SetUserVectorProperty("Threshold Between", thresholdRangeList); } } @@ -145,8 +175,6 @@ void VtkVisPointSetItem::setVtkProperties(VtkAlgorithmProperties* vtkProps) QObject::connect(vtkProps, SIGNAL(ScalarVisibilityChanged(bool)), _mapper, SLOT(SetScalarVisibility(bool))); - this->setLookupTableForActiveScalar(); - vtkActor* actor = dynamic_cast<vtkActor*>(_actor); if (actor) { @@ -203,14 +231,13 @@ int VtkVisPointSetItem::callVTKWriter(vtkAlgorithm* algorithm, const std::string void VtkVisPointSetItem::SetActiveAttribute( const QString& name ) { // Get type by identifier - bool onPointData = true; if (name.contains(QRegExp("^P-"))) - onPointData = true; + _onPointData = true; else if (name.contains(QRegExp("^C-"))) - onPointData = false; + _onPointData = false; else if (name.contains("Solid Color")) { - _activeAttribute = "Solid Color"; + _vtkProps->SetActiveAttribute("Solid Color"); _mapper->ScalarVisibilityOff(); return; } @@ -218,25 +245,28 @@ void VtkVisPointSetItem::SetActiveAttribute( const QString& name ) return; // Remove type identifier - std::string strippedName = QString(name).remove(0, 2).toStdString(); - const char* charName = strippedName.c_str(); + _activeArrayName = QString(name).remove(0, 2).toStdString(); + const char* charName = _activeArrayName.c_str(); + double range[2]; vtkDataSet* dataSet = vtkDataSet::SafeDownCast(this->_algorithm->GetOutputDataObject(0)); if (dataSet) { - if (onPointData) + if (_onPointData) { vtkPointData* pointData = dataSet->GetPointData(); if(pointData) { - if(activeAttributeExists(pointData, strippedName)) + if(activeAttributeExists(pointData, _activeArrayName)) { _algorithm->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, charName); _mapper->SetScalarModeToUsePointData(); + pointData->GetArray(_activeArrayName.c_str())->GetRange(range); } else { - _activeAttribute = "Solid Color"; + _activeArrayName = ""; + _vtkProps->SetActiveAttribute("Solid Color"); _mapper->ScalarVisibilityOff(); return; } @@ -247,26 +277,45 @@ void VtkVisPointSetItem::SetActiveAttribute( const QString& name ) vtkCellData* cellData = dataSet->GetCellData(); if(cellData) { - if(activeAttributeExists(cellData, strippedName)) + if(activeAttributeExists(cellData, _activeArrayName)) { _algorithm->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS, charName); _mapper->SetScalarModeToUseCellData(); + cellData->GetArray(_activeArrayName.c_str())->GetRange(range); } else { - _activeAttribute = "Solid Color"; + _activeArrayName = ""; + _vtkProps->SetActiveAttribute("Solid Color"); _mapper->ScalarVisibilityOff(); return; } } } - _activeAttribute = name; - _mapper->SetScalarRange(dataSet->GetScalarRange()); - this->setLookupTableForActiveScalar(); - _mapper->ScalarVisibilityOn(); + //std::cout << "Range for " << name.toStdString() << " :" << range[0] << " " << range[1] << std::endl; + _vtkProps->SetActiveAttribute(name); + + QVtkDataSetMapper* mapper = dynamic_cast<QVtkDataSetMapper*>(_mapper); + if (mapper) + { + // Create a default color table when there is no lookup table for this attribute + vtkLookupTable* lut = _vtkProps->GetLookupTable(name); + if (lut == NULL) + { + //std::cout << "Creating new lookup table for: " << name.toStdString() << std::endl; + lut = vtkLookupTable::New(); // is not a memory leak, gets deleted in VtkAlgorithmProperties + lut->SetTableRange(range); + _vtkProps->SetLookUpTable(name, lut); + } - //_mapper->Update(); // KR: TODO - this is incredibly slow ... WHY??? + _mapper->SetLookupTable(lut); + _mapper->UseLookupTableScalarRangeOn(); + //_mapper->SetScalarRange(range); // not necessary when UseLookupTableScalarRange is on + } + + _mapper->ScalarVisibilityOn(); + _mapper->Update(); } } @@ -288,41 +337,12 @@ bool VtkVisPointSetItem::activeAttributeExists(vtkDataSetAttributes* data, std:: return false; } -void VtkVisPointSetItem::setLookupTableForActiveScalar() -{ - VtkAlgorithmProperties* vtkProps = dynamic_cast<VtkAlgorithmProperties*>(_algorithm); - if (vtkProps) - { - QVtkDataSetMapper* mapper = dynamic_cast<QVtkDataSetMapper*>(_mapper); - if (mapper) - { - if (vtkProps->GetLookupTable(this->GetActiveAttribute()) == NULL) // default color table - { - vtkLookupTable* lut = vtkLookupTable::New(); - vtkProps->SetLookUpTable(GetActiveAttribute(), lut); - } - else // specific color table - _mapper->SetLookupTable(vtkProps->GetLookupTable(this->GetActiveAttribute())); - - //_mapper->SetScalarRange(this->_transformFilter->GetOutput()->GetScalarRange()); - _mapper->SetScalarRange(vtkDataSet::SafeDownCast(this->_algorithm->GetOutputDataObject(0))->GetScalarRange()); - //_mapper->Update(); //KR: not necessary?! - } - } -} - -void VtkVisPointSetItem::SetScalarRange(double min, double max) -{ - _mapper->SetScalarRange(min, max); - _mapper->Update(); -} - void VtkVisPointSetItem::setScale(double x, double y, double z) const { if (this->transformFilter()) { vtkTransform* transform = - static_cast<vtkTransform*>(this->_transformFilter->GetTransform()); + static_cast<vtkTransform*>(this->_transformFilter->GetTransform()); double* trans = transform->GetPosition(); transform->Identity(); transform->Scale(x, y, z); @@ -336,7 +356,7 @@ void VtkVisPointSetItem::setTranslation(double x, double y, double z) const if (this->transformFilter()) { vtkTransform* transform = - static_cast<vtkTransform*>(this->_transformFilter->GetTransform()); + static_cast<vtkTransform*>(this->_transformFilter->GetTransform()); double* scale = transform->GetScale(); transform->Identity(); transform->Scale(scale); @@ -349,3 +369,27 @@ vtkAlgorithm* VtkVisPointSetItem::transformFilter() const { return _transformFilter; } + +void VtkVisPointSetItem::setBackfaceCulling(bool enable) const +{ + static_cast<vtkActor*>(this->_actor)->GetProperty()->SetBackfaceCulling((int)enable); +} + +void VtkVisPointSetItem::GetRangeForActiveAttribute(double range[2]) const +{ + vtkDataSet* dataSet = vtkDataSet::SafeDownCast(this->_algorithm->GetOutputDataObject(0)); + if (dataSet && _activeArrayName.length() > 0) + { + if (_onPointData) + { + vtkPointData* pointData = dataSet->GetPointData(); + if(pointData) + pointData->GetArray(_activeArrayName.c_str())->GetRange(range); + } + else + { + vtkCellData* cellData = dataSet->GetCellData(); + cellData->GetArray(_activeArrayName.c_str())->GetRange(range); + } + } +} diff --git a/VtkVis/VtkVisPointSetItem.h b/VtkVis/VtkVisPointSetItem.h index 90298eca855..ad106761807 100644 --- a/VtkVis/VtkVisPointSetItem.h +++ b/VtkVis/VtkVisPointSetItem.h @@ -47,7 +47,10 @@ public: ~VtkVisPointSetItem(); /// @brief Gets the last selected attribute. - const QString GetActiveAttribute() const {return _activeAttribute; } + const QString GetActiveAttribute() const; + + /// @brief Get the scalar range for the active attribute + void GetRangeForActiveAttribute(double range[2]) const; /// @brief Initializes vtkMapper and vtkActor necessary for visualization of /// the item and sets the item's properties. @@ -58,26 +61,24 @@ public: /// @brief Sets the selected attribute array for the visualisation of the data set. void SetActiveAttribute(const QString& name); - /// @brief Sets the scalar range for the selected data array - void SetScalarRange(double min, double max); - /// @brief Scales the data in visualisation-space. void setScale(double x, double y, double z) const; /// @brief Translates the item in visualisation-space. void setTranslation(double x, double y, double z) const; + /// @brief Enables / disables backface culling. + void setBackfaceCulling(bool enable) const; + protected: QVtkDataSetMapper* _mapper; vtkTransformFilter* _transformFilter; - QString _activeAttribute; + bool _onPointData; + std::string _activeArrayName; /// Selects the appropriate VTK-Writer object and writes the object to a file with the given name. virtual int callVTKWriter(vtkAlgorithm* algorithm, const std::string &filename) const; - /// Sets a color lookup table for the current scalar array. - void setLookupTableForActiveScalar(); - void SetScalarVisibility(bool on); /// @brief Sets pre-set properties on vtkActor and on vtkMapper @@ -86,6 +87,7 @@ protected: private: /// Checks if the selected attribute actually exists for the data set bool activeAttributeExists(vtkDataSetAttributes* data, std::string& name); + }; #endif // VTKVISPOINTSETITEM_H diff --git a/VtkVis/VtkVisTabWidget.cpp b/VtkVis/VtkVisTabWidget.cpp index 880fca04054..2901f6de52f 100644 --- a/VtkVis/VtkVisTabWidget.cpp +++ b/VtkVis/VtkVisTabWidget.cpp @@ -198,7 +198,8 @@ void VtkVisTabWidget::on_scaleZ_textChanged(const QString &text) bool ok = true; double scale = text.toDouble(&ok); - if (ok) + // If z scale becomes zero, the object becomes invisible + if (ok && scale != 0.0) { _item->setScale(1.0, 1.0, scale); @@ -344,24 +345,8 @@ void VtkVisTabWidget::buildProportiesDialog(VtkVisPipelineItem* item) void VtkVisTabWidget::buildScalarArrayComboBox(VtkVisPipelineItem* item) { - vtkDataSet* dataSet = vtkDataSet::SafeDownCast(item->algorithm()->GetOutputDataObject(0)); - QStringList dataSetAttributesList; - if (dataSet) - { - vtkPointData* pointData = dataSet->GetPointData(); - //std::cout << " #point data arrays: " << pointData->GetNumberOfArrays() << std::endl; - for (int i = 0; i < pointData->GetNumberOfArrays(); i++) - //std::cout << " Name: " << pointData->GetArrayName(i) << std::endl; - dataSetAttributesList.push_back(QString("P-") + pointData->GetArrayName(i)); - - vtkCellData* cellData = dataSet->GetCellData(); - //std::cout << " #cell data arrays: " << cellData->GetNumberOfArrays() << std::endl; - for (int i = 0; i < cellData->GetNumberOfArrays(); i++) - //std::cout << " Name: " << cellData->GetArrayName(i) << std::endl; - dataSetAttributesList.push_back(QString("C-") + cellData->GetArrayName(i)); - - dataSetAttributesList.push_back("Solid Color"); // all scalars switched off - } + QStringList dataSetAttributesList = item->getScalarArrayNames(); + dataSetAttributesList.push_back("Solid Color"); // all scalars switched off this->activeScalarComboBox->blockSignals(true); this->activeScalarComboBox->clear(); this->activeScalarComboBox->insertItems(0, dataSetAttributesList); -- GitLab