resqpy 4.14.2__tar.gz → 4.14.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {resqpy-4.14.2 → resqpy-4.14.4}/PKG-INFO +1 -1
- {resqpy-4.14.2 → resqpy-4.14.4}/pyproject.toml +1 -1
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/__init__.py +1 -1
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/surface/_surface.py +142 -54
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/time_series/_any_time_series.py +3 -1
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/time_series/_geologic_time_series.py +1 -1
- {resqpy-4.14.2 → resqpy-4.14.4}/LICENSE +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/README.md +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/crs.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_add_edges_per_column_property_array.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_add_faults.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_add_one_blocked_well_property.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_add_one_grid_property_array.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_add_single_cell_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_add_wells_from_ascii_file.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_add_zone_by_layer_property.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_coarsened_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_common.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_copy_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_drape_to_surface.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_extract_box.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_extract_box_for_well.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_fault_throw_scaling.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_gather_ensemble.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_interpolated_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_local_depth_adjustment.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_refined_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_tilted_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_unsplit_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_zonal_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_zone_layer_ranges_from_array.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/fault/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/fault/_gcs_functions.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/fault/_grid_connection_set.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_cell_properties.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_connection_sets.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_create_grid_xml.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_defined_geometry.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_extract_functions.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_face_functions.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_faults.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_grid_types.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_intervals_info.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_moved_functions.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_pillars.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_pixel_maps.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_points_functions.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_regular_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_transmissibility.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_write_hdf5_from_caches.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_write_nexus_corp.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid/_xyz.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid_surface/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid_surface/_blocked_well_populate.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid_surface/_find_faces.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid_surface/_grid_skin.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid_surface/_grid_surface.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid_surface/_trajectory_intersects.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/grid_surface/grid_surface_cuda.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/lines/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/lines/_common.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/lines/_polyline.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/lines/_polyline_set.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/model/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/model/_catalogue.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/model/_context.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/model/_forestry.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/model/_grids.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/model/_hdf5.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/model/_model.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/model/_xml.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/multi_processing/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/multi_processing/_multiprocessing.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/multi_processing/wrappers/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/multi_processing/wrappers/blocked_well_mp.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/multi_processing/wrappers/grid_surface_mp.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/multi_processing/wrappers/mesh_mp.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/ab_toolbox.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/base.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/box_utilities.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/class_dict.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/consolidation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/data/build.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/data/properties.json +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/dataframe.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/exceptions.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/factors.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/fine_coarse.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/grid_functions.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/intersection.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/keyword_files.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/load_data.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/point_inclusion.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/random_seed.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/read_nexus_fault.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/relperm.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/simple_lines.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/time.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/trademark.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/transmission.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/triangulation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/uuid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/vdb.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/vector_utilities.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/volume.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/wellspec_keywords.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/write_data.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/write_hdf5.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/xml_et.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/xml_namespaces.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/olio/zmap_reader.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/_utils.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/boundary_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/boundary_feature_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/earth_model_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/fault_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/fluid_boundary_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/frontier_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/generic_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/genetic_boundary_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/geobody_boundary_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/geobody_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/geobody_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/geologic_unit_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/horizon_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/organization_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/rock_fluid_unit_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/structural_organization_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/tectonic_boundary_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/wellbore_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/organize/wellbore_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/_collection_add_part.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/_collection_create_xml.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/_collection_get_attributes.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/_collection_support.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/_property.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/grid_property_collection.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/property_collection.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/property_common.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/property_kind.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/string_lookup.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/well_interval_property.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/well_interval_property_collection.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/well_log.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/property/well_log_collection.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/rq_import/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/rq_import/_add_ab_properties.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/rq_import/_add_surfaces.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/rq_import/_grid_from_cp.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/rq_import/_import_nexus.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/rq_import/_import_vdb_all_grids.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/rq_import/_import_vdb_ensemble.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/strata/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/strata/_binary_contact_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/strata/_geologic_unit_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/strata/_strata_common.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/strata/_stratigraphic_column.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/strata/_stratigraphic_column_rank.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/strata/_stratigraphic_unit_feature.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/strata/_stratigraphic_unit_interpretation.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/surface/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/surface/_base_surface.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/surface/_combined_surface.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/surface/_mesh.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/surface/_pointset.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/surface/_tri_mesh.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/surface/_tri_mesh_stencil.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/surface/_triangulated_patch.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/time_series/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/time_series/_from_nexus_summary.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/time_series/_functions.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/time_series/_time_duration.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/time_series/_time_series.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/unstructured/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/unstructured/_hexa_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/unstructured/_prism_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/unstructured/_pyramid_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/unstructured/_tetra_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/unstructured/_unstructured_grid.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/weights_and_measures/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/weights_and_measures/nexus_units.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/weights_and_measures/weights_and_measures.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/__init__.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/_blocked_well.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/_deviation_survey.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/_md_datum.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/_trajectory.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/_wellbore_frame.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/_wellbore_marker.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/_wellbore_marker_frame.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/blocked_well_frame.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/well_object_funcs.py +0 -0
- {resqpy-4.14.2 → resqpy-4.14.4}/resqpy/well/well_utils.py +0 -0
@@ -272,48 +272,86 @@ class Surface(rqsb.BaseSurface):
|
|
272
272
|
|
273
273
|
self.model = parent_model
|
274
274
|
|
275
|
-
def
|
276
|
-
"""Returns
|
275
|
+
def number_of_patches(self):
|
276
|
+
"""Returns the number of patches present in the surface."""
|
277
|
+
|
278
|
+
self.extract_patches(self.root)
|
279
|
+
return len(self.patch_list)
|
280
|
+
|
281
|
+
def triangles_and_points(self, patch = None):
|
282
|
+
"""Returns arrays representing one patch or a combination of all the patches in the surface.
|
283
|
+
|
284
|
+
arguments:
|
285
|
+
patch (int, optional): patch index; if None, combined arrays for all patches are returned
|
277
286
|
|
278
287
|
returns:
|
279
288
|
tuple (triangles, points):
|
280
289
|
triangles (int array of shape[:, 3]): integer indices into points array,
|
281
|
-
|
290
|
+
being the nodes of the corners of the triangles;
|
282
291
|
points (float array of shape[:, 3]): flat array of xyz points, indexed by triangles
|
283
292
|
|
284
293
|
:meta common:
|
285
294
|
"""
|
286
295
|
|
287
|
-
if self.triangles is not None:
|
288
|
-
return (self.triangles, self.points)
|
289
296
|
self.extract_patches(self.root)
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
297
|
+
if patch is None:
|
298
|
+
if self.triangles is None:
|
299
|
+
points_offset = 0
|
300
|
+
for triangulated_patch in self.patch_list:
|
301
|
+
(t, p) = triangulated_patch.triangles_and_points()
|
302
|
+
if points_offset == 0:
|
303
|
+
self.triangles = t.copy()
|
304
|
+
self.points = p.copy()
|
305
|
+
else:
|
306
|
+
self.triangles = np.concatenate((self.triangles, t.copy() + points_offset))
|
307
|
+
self.points = np.concatenate((self.points, p.copy()))
|
308
|
+
points_offset += p.shape[0]
|
309
|
+
return (self.triangles, self.points)
|
310
|
+
assert 0 <= patch < len(self.patch_list), \
|
311
|
+
ValueError(f'patch index {patch} out of range for surface with {len(self.patch_list)} patches')
|
312
|
+
return self.patch_list[patch].triangles_and_points()
|
313
|
+
|
314
|
+
def triangle_count(self, patch = None):
|
315
|
+
"""Return the numner of triangles in this surface, or in one patch.
|
301
316
|
|
302
|
-
|
303
|
-
|
317
|
+
arguments:
|
318
|
+
patch (int, optional): patch index; if None, a combined triangle count for all patches is returned
|
319
|
+
|
320
|
+
returns:
|
321
|
+
int being the number of trianges in the patch (if specified) or in all the patches
|
322
|
+
"""
|
304
323
|
|
305
324
|
self.extract_patches(self.root)
|
306
|
-
if
|
307
|
-
|
308
|
-
|
325
|
+
if patch is None:
|
326
|
+
if not self.patch_list:
|
327
|
+
return 0
|
328
|
+
return np.sum([tp.triangle_count for tp in self.patch_list])
|
329
|
+
assert 0 <= patch < len(self.patch_list), \
|
330
|
+
ValueError(f'patch index {patch} out of range for surface with {len(self.patch_list)} patches in triangle_count')
|
331
|
+
return self.patch_list[patch].triangle_count
|
332
|
+
|
333
|
+
def node_count(self, patch = None):
|
334
|
+
"""Return the number of nodes (points) used in this surface, or in one patch.
|
335
|
+
|
336
|
+
arguments:
|
337
|
+
patch (int, optional): patch index; if None, a combined node count for all patches is returned
|
309
338
|
|
310
|
-
|
311
|
-
|
339
|
+
returns:
|
340
|
+
int being the number of nodes in the patch (if specified) or in all the patches
|
341
|
+
|
342
|
+
note:
|
343
|
+
a multi patch surface might have more than one node colocated; this method will treat such coincident nodes
|
344
|
+
as separate nodes
|
345
|
+
"""
|
312
346
|
|
313
347
|
self.extract_patches(self.root)
|
314
|
-
if
|
315
|
-
|
316
|
-
|
348
|
+
if patch is None:
|
349
|
+
if not self.patch_list:
|
350
|
+
return 0
|
351
|
+
return np.sum([tp.node_count for tp in self.patch_list])
|
352
|
+
assert 0 <= patch < len(self.patch_list), \
|
353
|
+
ValueError(f'patch index {patch} out of range for surface with {len(self.patch_list)} patches in node_count')
|
354
|
+
return self.patch_list[patch].node_count
|
317
355
|
|
318
356
|
def change_crs(self, required_crs):
|
319
357
|
"""Changes the crs of the surface, also sets a new uuid if crs changed.
|
@@ -381,7 +419,7 @@ class Surface(rqsb.BaseSurface):
|
|
381
419
|
self.uuid = bu.new_uuid()
|
382
420
|
|
383
421
|
def set_to_split_surface(self, large_surface, line, delta_xyz):
|
384
|
-
"""Populate this (empty) surface with a version of a larger surface split by
|
422
|
+
"""Populate this (empty) surface with a version of a larger surface split by a straight xy line.
|
385
423
|
|
386
424
|
arguments:
|
387
425
|
large_surface (Surface): the larger surface, a copy of which is to be split
|
@@ -404,8 +442,8 @@ class Surface(rqsb.BaseSurface):
|
|
404
442
|
tp[:, 1] = len(p) + 1
|
405
443
|
tp[:, 2] = np.arange(len(p), dtype = int)
|
406
444
|
cw = vec.clockwise_triangles(pp, tp)
|
407
|
-
pai =
|
408
|
-
pbi =
|
445
|
+
pai = (cw >= 0.0) # bool mask over p
|
446
|
+
pbi = (cw <= 0.0) # bool mask over p
|
409
447
|
tap = pai[t]
|
410
448
|
tbp = pbi[t]
|
411
449
|
ta = np.any(tap, axis = 1) # bool array over t
|
@@ -435,17 +473,24 @@ class Surface(rqsb.BaseSurface):
|
|
435
473
|
|
436
474
|
self.set_from_triangles_and_points(t_combo, p_combo)
|
437
475
|
|
438
|
-
def distinct_edges(self):
|
439
|
-
"""Returns a numpy int array of shape (N, 2) being the ordered node pairs of distinct edges of triangles.
|
476
|
+
def distinct_edges(self, patch = None):
|
477
|
+
"""Returns a numpy int array of shape (N, 2) being the ordered node pairs of distinct edges of triangles.
|
440
478
|
|
441
|
-
|
479
|
+
arguments:
|
480
|
+
patch (int, optional): patch index; if None, a combination of edges for all patches is returned
|
481
|
+
"""
|
482
|
+
|
483
|
+
triangles, _ = self.triangles_and_points(patch = patch)
|
442
484
|
assert triangles is not None
|
443
485
|
unique_edges, _ = triangulate.edges(triangles)
|
444
486
|
return unique_edges
|
445
487
|
|
446
|
-
def distinct_edges_and_counts(self):
|
488
|
+
def distinct_edges_and_counts(self, patch = None):
|
447
489
|
"""Returns unique edges as pairs of point indices, and a count of uses of each edge.
|
448
490
|
|
491
|
+
arguments:
|
492
|
+
patch (int, optional): patch index; if None, combined results for all patches are returned
|
493
|
+
|
449
494
|
returns:
|
450
495
|
numpy int array of shape (N, 2), numpy int array of shape (N,)
|
451
496
|
where 2D array is list-like sorted points index pairs for unique edges
|
@@ -453,14 +498,39 @@ class Surface(rqsb.BaseSurface):
|
|
453
498
|
|
454
499
|
notes:
|
455
500
|
first entry in each pair is always the lower of the two point indices;
|
456
|
-
for well formed surfaces, the count should everywhere be
|
501
|
+
for well formed surfaces, the count should everywhere be one or two;
|
457
502
|
the function does not attempt to detect coincident points
|
458
503
|
"""
|
459
504
|
|
460
|
-
triangles, _ = self.triangles_and_points()
|
505
|
+
triangles, _ = self.triangles_and_points(patch = patch)
|
461
506
|
assert triangles is not None
|
462
507
|
return triangulate.edges(triangles)
|
463
508
|
|
509
|
+
def edge_lengths(self, required_uom = None, patch = None):
|
510
|
+
"""Returns float array of shape (N, 3) being triangle edge lengths.
|
511
|
+
|
512
|
+
arguments:
|
513
|
+
required_uom (str, optional): the required length uom for the resulting edge lengths; default is crs xy units
|
514
|
+
patch (int, optional): patch index; if None, edge lengths for all patches are returned
|
515
|
+
|
516
|
+
returns:
|
517
|
+
numpy float array of shape (N, 3) where N is the number of triangles
|
518
|
+
"""
|
519
|
+
|
520
|
+
t, p = self.triangles_and_points(patch = patch)
|
521
|
+
crs = rqc.Crs(self.model, uuid = self.crs_uuid)
|
522
|
+
if required_uom is None:
|
523
|
+
required_uom = crs.xy_units
|
524
|
+
if crs.xy_units != required_uom or crs.z_units != required_uom:
|
525
|
+
p = p.copy()
|
526
|
+
wam.convert_lengths(p[:, :2], crs.xy_units, required_uom)
|
527
|
+
wam.convert_lengths(p[:, 2], crs.z_units, required_uom)
|
528
|
+
t_end = np.empty_like(t)
|
529
|
+
t_end[:, :2] = t[:, 1:]
|
530
|
+
t_end[:, 2] = t[:, 0]
|
531
|
+
edge_v = p[t_end, :] - p[t, :]
|
532
|
+
return vec.naive_lengths(edge_v)
|
533
|
+
|
464
534
|
def set_from_triangles_and_points(self, triangles, points):
|
465
535
|
"""Populate this (empty) Surface object from an array of triangle corner indices and an array of points."""
|
466
536
|
|
@@ -468,6 +538,22 @@ class Surface(rqsb.BaseSurface):
|
|
468
538
|
tri_patch.set_from_triangles_and_points(triangles, points)
|
469
539
|
self.patch_list = [tri_patch]
|
470
540
|
self.uuid = bu.new_uuid()
|
541
|
+
self.triangles = triangles.copy()
|
542
|
+
self.points = points.copy()
|
543
|
+
|
544
|
+
def set_multi_patch_from_triangles_and_points(self, triangles_and_points_list):
|
545
|
+
"""Populate this (empty) Surface object from a list of paits: array of triangle corner indices, array of points."""
|
546
|
+
|
547
|
+
self.patch_list = []
|
548
|
+
self.trianges = None
|
549
|
+
self.points = None
|
550
|
+
for patch, entry in enumerate(triangles_and_points_list):
|
551
|
+
assert len(entry) == 2, 'expecting pair of arrays (triangles, points) for each patch'
|
552
|
+
triangles, points = entry
|
553
|
+
tri_patch = rqstp.TriangulatedPatch(self.model, patch_index = patch, crs_uuid = self.crs_uuid)
|
554
|
+
tri_patch.set_from_triangles_and_points(triangles, points)
|
555
|
+
self.patch_list.append(tri_patch)
|
556
|
+
self.uuid = bu.new_uuid()
|
471
557
|
|
472
558
|
def set_from_point_set(self,
|
473
559
|
point_set,
|
@@ -901,10 +987,10 @@ class Surface(rqsb.BaseSurface):
|
|
901
987
|
for patch in self.patch_list:
|
902
988
|
patch.vertical_rescale_points(ref_depth, scaling_factor)
|
903
989
|
|
904
|
-
def line_intersection(self, line_p, line_v, line_segment = False):
|
990
|
+
def line_intersection(self, line_p, line_v, line_segment = False, patch = None):
|
905
991
|
"""Returns x,y,z of an intersection point of straight line with the surface, or None if no intersection found."""
|
906
992
|
|
907
|
-
t, p = self.triangles_and_points()
|
993
|
+
t, p = self.triangles_and_points(patch = patch)
|
908
994
|
tp = p[t]
|
909
995
|
intersects = meet.line_triangles_intersects(line_p, line_v, tp, line_segment = line_segment)
|
910
996
|
indices = meet.intersects_indices(intersects)
|
@@ -912,21 +998,22 @@ class Surface(rqsb.BaseSurface):
|
|
912
998
|
return None
|
913
999
|
return intersects[indices[0]]
|
914
1000
|
|
915
|
-
def sample_z_at_xy_points(self, points, multiple_handling = 'any'):
|
1001
|
+
def sample_z_at_xy_points(self, points, multiple_handling = 'any', patch = None):
|
916
1002
|
"""Returns interpolated z values for an array of xy values.
|
917
1003
|
|
918
1004
|
arguments:
|
919
1005
|
points (numpy float array of shape (..., 2 or 3)): xy points to sample surface at (z values ignored)
|
920
1006
|
multiple_handling (str, default 'any'): one of 'any', 'minimum', 'maximum', 'exception'
|
1007
|
+
patch (int, optional): patch index; if None, results are for the full surface
|
921
1008
|
|
922
1009
|
returns:
|
923
1010
|
numpy float array of shape points.shape[:-1] being z values interpolated from the surface z values
|
924
1011
|
|
925
1012
|
notes:
|
926
1013
|
points must be in the same crs as the surface;
|
927
|
-
NaN will be set for any points that do not intersect with the surface in the xy projection;
|
928
|
-
multiple_handling argument controls behaviour when one sample point intersects
|
929
|
-
|
1014
|
+
NaN will be set for any points that do not intersect with the patch or surface in the xy projection;
|
1015
|
+
multiple_handling argument controls behaviour when one sample point intersects more than once:
|
1016
|
+
'any' a random one of the intersection z values is returned; 'minimum' or 'maximum': the
|
930
1017
|
numerical min or max of the z values is returned; 'exception': a ValueError is raised
|
931
1018
|
"""
|
932
1019
|
|
@@ -938,7 +1025,7 @@ class Surface(rqsb.BaseSurface):
|
|
938
1025
|
else:
|
939
1026
|
sample_xy = np.zeros((points.size // 2, 3), dtype = float)
|
940
1027
|
sample_xy[:, :2] = points.reshape((-1, 2))
|
941
|
-
t, p = self.triangles_and_points()
|
1028
|
+
t, p = self.triangles_and_points(patch = patch)
|
942
1029
|
p_list = vec.points_in_triangles_njit(sample_xy, p[t], 1)
|
943
1030
|
vertical = np.array((0.0, 0.0, 1.0), dtype = float)
|
944
1031
|
z = np.full(sample_xy.shape[0], np.NaN, dtype = float)
|
@@ -957,17 +1044,18 @@ class Surface(rqsb.BaseSurface):
|
|
957
1044
|
raise ValueError(f'multiple {self.title} surface intersections at xy: {sample_xy[p_index]}')
|
958
1045
|
return z.reshape(points.shape[:-1])
|
959
1046
|
|
960
|
-
def normal_vectors(self, add_as_property: bool = False) -> np.ndarray:
|
961
|
-
"""Returns the normal vectors for each triangle in the surface.
|
962
|
-
|
1047
|
+
def normal_vectors(self, add_as_property: bool = False, patch = None) -> np.ndarray:
|
1048
|
+
"""Returns the normal vectors for each triangle in the patch or surface.
|
1049
|
+
|
963
1050
|
arguments:
|
964
|
-
add_as_property (bool): if True, face_surface_normal_vectors_array is added as a property to the model
|
1051
|
+
add_as_property (bool): if True, face_surface_normal_vectors_array is added as a property to the model
|
1052
|
+
patch (int, optional): patch index; if None, normal vectors for triangles in all patches are returned
|
965
1053
|
|
966
1054
|
returns:
|
967
|
-
normal_vectors_array (np.ndarray): the normal vectors corresponding to each triangle in the surface
|
1055
|
+
normal_vectors_array (np.ndarray): the normal vectors corresponding to each triangle in the surface
|
968
1056
|
"""
|
969
1057
|
crs = rqc.Crs(self.model, uuid = self.crs_uuid)
|
970
|
-
triangles, points = self.triangles_and_points()
|
1058
|
+
triangles, points = self.triangles_and_points(patch = patch)
|
971
1059
|
if crs.xy_units != crs.z_units:
|
972
1060
|
points = points.copy()
|
973
1061
|
wam.convert_lengths(points[:, 2], crs.z_units, crs.xy_units)
|
@@ -1027,13 +1115,13 @@ class Surface(rqsb.BaseSurface):
|
|
1027
1115
|
return ep
|
1028
1116
|
|
1029
1117
|
def resampled_surface(self, title = None):
|
1030
|
-
"""Creates a new
|
1031
|
-
|
1118
|
+
"""Creates a new surface which is a refined version of this surface; each triangle is divided equally into 4 new triangles.
|
1119
|
+
|
1032
1120
|
arguments:
|
1033
|
-
title (str):
|
1034
|
-
|
1121
|
+
title (str): title for the output triangulated set, if None the title will be inherited from the input surface
|
1122
|
+
|
1035
1123
|
returns:
|
1036
|
-
resqpy.surface.Surface object, with extra_metadata ('resampled from surface':
|
1124
|
+
resqpy.surface.Surface object, with extra_metadata ('resampled from surface': uuid), where uuid is for the original surface uuid
|
1037
1125
|
"""
|
1038
1126
|
rt, rp = self.triangles_and_points()
|
1039
1127
|
edge1 = np.mean(rp[rt[:]][:, ::2, :], axis = 1)
|
@@ -1051,7 +1139,7 @@ class Surface(rqsb.BaseSurface):
|
|
1051
1139
|
# TODO: implement alternate solution using edge functions in olio triangulation to optimise
|
1052
1140
|
points_unique, inverse = np.unique(allpoints, axis = 0, return_inverse = True)
|
1053
1141
|
tris = np.array(tris)
|
1054
|
-
tris_unique = np.empty(shape = tris.shape)
|
1142
|
+
tris_unique = np.empty(shape = tris.shape, dtype = int)
|
1055
1143
|
tris_unique[:, 0] = inverse[tris[:, 0]]
|
1056
1144
|
tris_unique[:, 1] = inverse[tris[:, 1]]
|
1057
1145
|
tris_unique[:, 2] = inverse[tris[:, 2]]
|
@@ -34,8 +34,10 @@ class AnyTimeSeries(BaseResqpy):
|
|
34
34
|
dt_text = rqet.find_tag_text(child, 'DateTime')
|
35
35
|
assert dt_text, 'missing DateTime field in xml for time series'
|
36
36
|
year_offset = rqet.find_tag_int(child, 'YearOffset')
|
37
|
-
if year_offset:
|
37
|
+
if year_offset is not None:
|
38
38
|
assert self.timeframe == 'geologic'
|
39
|
+
if year_offset > 0:
|
40
|
+
log.warning(f'positive year offset in xml indicates future geological time: {year_offset}')
|
39
41
|
self.timestamps.append(year_offset) # todo: trim and check timestamp
|
40
42
|
else:
|
41
43
|
assert self.timeframe == 'human'
|
@@ -29,7 +29,7 @@ class GeologicTimeSeries(ats.AnyTimeSeries):
|
|
29
29
|
|
30
30
|
note:
|
31
31
|
if instantiating from an existing RESQML time series, its Time entries must all have YearOffset data
|
32
|
-
which should be large negative integers
|
32
|
+
which should be large negative integers (or zero if reaching the current era)
|
33
33
|
|
34
34
|
:meta common:
|
35
35
|
"""
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{resqpy-4.14.2 → resqpy-4.14.4}/resqpy/derived_model/_add_edges_per_column_property_array.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|