diff --git a/example/example.cpp b/example/example.cpp index 997f954f..bbd904b4 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -544,15 +544,15 @@ void serializeGeobody(COMMON_NS::DataObjectRepository * repo, EML2_NS::AbstractH RESQML2_NS::BoundaryFeature* geobodyBoundary = repo->createGeobodyBoundaryFeature("6d3c158c-303f-4b0d-bfc0-9ce4102ea616", "Geobody boundary"); RESQML2_NS::GeobodyBoundaryInterpretation* geobodyBoundaryInterp = repo->createGeobodyBoundaryInterpretation(geobodyBoundary, "12c301a4-3e8b-401a-aca3-8d6f02d5d6d5", "Geobody boundary interp"); RESQML2_NS::PointSetRepresentation* geobodyBoundaryPointSetRep = repo->createPointSetRepresentation(geobodyBoundaryInterp, "fbc5466c-94cd-46ab-8b48-2ae2162b372f", "Geobody boundary PointSetRep"); - double geobodyBoundaryPointCoords[18] = { 10, 70, 310, 11, 21, 280, 150, 30, 310, 400, 0, 365, 450, 75, 341, 475, 100, 352 }; - geobodyBoundaryPointSetRep->pushBackGeometryPatch(6, geobodyBoundaryPointCoords, hdfProxy); + double geobodyBoundaryPointCoords[12] = { 10, 70, 11, 21, 150, 30, 400, 0, 450, 75, 475, 100 }; + geobodyBoundaryPointSetRep->pushBackXyGeometryPatch(6, geobodyBoundaryPointCoords, hdfProxy); // 3D RESQML2_NS::RockVolumeFeature* geobody = repo->createGeobodyFeature("e221f9da-ead3-4a9d-8324-fc2e6606cb01", "Geobody"); RESQML2_NS::GeobodyInterpretation* geobodyInterp = repo->createGeobodyInterpretation(geobody, "d445041f-6364-44e7-a7f8-ade5a93bfd49", "Geobody interp"); RESQML2_NS::PointSetRepresentation* geobodyGraphNode = repo->createPointSetRepresentation(geobodyInterp, "8442a6b7-a97b-431e-abda-f72cf7ef346f", "Geobody graph node"); double geobodyPointCoords[18] = { 50, 30, 330, 10, 28, 3000, 100, 50, 350, 300, 100, 400, 400, 20, 400, 400, 300, 400 }; - geobodyGraphNode->pushBackGeometryPatch(6, geobodyPointCoords, hdfProxy); + geobodyGraphNode->pushBackXyzGeometryPatch(6, geobodyPointCoords, hdfProxy); //RESQML2_NS::SubRepresentation* geobodyGraphEdge = repo->createSubRepresentation(geobodyBoundaryInterp, "7e0450aa-c39d-49f8-bee4-62fc42bb849d", "Geobody graph edge"); } @@ -631,7 +631,7 @@ void serializeBoundaries(COMMON_NS::DataObjectRepository * repo, EML2_NS::Abstra RESQML2_NS::PointSetRepresentation* h1i1PointSetRep = repo->createPointSetRepresentation(horizon1Interp1, "", "Horizon1 Interp1 PointSetRep"); double pointCoords[18] = { 10, 70, 301, 11, 21, 299, 150, 30, 301, 400, 0, 351, 450, 75, 340, 475, 100, 350 }; - h1i1PointSetRep->pushBackGeometryPatch(6, pointCoords, hdfProxy); + h1i1PointSetRep->pushBackXyzGeometryPatch(6, pointCoords, hdfProxy); // Horizon 1 triangulated representation h1i1triRep = repo->createTriangulatedSetRepresentation(horizon1Interp1, @@ -2496,7 +2496,7 @@ bool serialize(const string & filePath) repo.setHdfProxyFactory(new HdfProxyFactoryExample()); auto* exoticHdfPox = repo.createHdfProxy("", "Dummy Exotic HDF proxy", "", "", COMMON_NS::DataObjectRepository::openingMode::READ_ONLY); double dummyPoints[3] = { 1.0, 2.0, 3.0 }; - repo.createPointSetRepresentation("", "")->pushBackGeometryPatch(1, dummyPoints, exoticHdfPox); + repo.createPointSetRepresentation("", "")->pushBackXyzGeometryPatch(1, dummyPoints, exoticHdfPox); return true; } @@ -2897,9 +2897,39 @@ void deserializeGeobody(COMMON_NS::DataObjectRepository * repo) { //2d std::vector geobodyBoundarySet = repo->getGeobodyBoundarySet(); - for (size_t i = 0; i < geobodyBoundarySet.size(); ++i) { - showAllMetadata(geobodyBoundarySet[i]); - cout << "interp count : " << geobodyBoundarySet[i]->getInterpretationCount() << endl; + for (RESQML2_NS::BoundaryFeature const* feature : geobodyBoundarySet) { + showAllMetadata(feature); + const auto interpCount = feature->getInterpretationCount(); + cout << "interp count : " << interpCount << endl; + for (size_t j = 0; j < interpCount; ++j) { + const auto* interp = feature->getInterpretation(j); + showAllMetadata(interp); + const auto repCount = interp->getRepresentationCount(); + cout << "rep count : " << repCount << endl; + for (size_t k = 0; k < repCount; ++k) { + auto const* psRep = dynamic_cast(interp->getRepresentation(k)); + if (psRep != nullptr) { + auto ptCount = psRep->getXyzPointCountOfAllPatches(); + cout << "point count : " << ptCount << endl; + if (psRep->isIn2D(0)) { + cout << "Patch 0 in 2d !" << endl; + } + else { + cout << "Patch 0 in 3d !" << endl; + } + std::unique_ptr xyPoints(new double[ptCount * 2]); + psRep->getXyPointsOfPatch(0, xyPoints.get()); + for (size_t ptIdx = 0; ptIdx < ptCount; ++ptIdx) { + cout << "pt2D " << ptIdx << ": " << xyPoints[ptIdx * 2] << " " << xyPoints[ptIdx * 2 + 1] << endl; + } + std::unique_ptr allXyzPoints(new double[ptCount * 3]); + psRep->getXyzPointsOfAllPatches(allXyzPoints.get()); + for (size_t ptIdx = 0; ptIdx < ptCount; ++ptIdx) { + cout << "pt3D " << ptIdx << ": " << allXyzPoints[ptIdx * 3] << " " << allXyzPoints[ptIdx * 3 + 1] << " " << allXyzPoints[ptIdx * 3 + 2] << endl; + } + } + } + } } //3d diff --git a/src/resqml2/AbstractRepresentation.cpp b/src/resqml2/AbstractRepresentation.cpp index 0241b053..52368a01 100644 --- a/src/resqml2/AbstractRepresentation.cpp +++ b/src/resqml2/AbstractRepresentation.cpp @@ -105,7 +105,7 @@ gsoap_eml2_3::resqml22__Seismic3dCoordinates* AbstractRepresentation::getSeismic } gsoap_resqml2_0_1::resqml20__PointGeometry* AbstractRepresentation::createPointGeometryPatch2_0_1(uint64_t patchIndex, - double const * points, EML2_NS::AbstractLocal3dCrs const* localCrs, uint64_t const* numPoints, uint32_t numDimensionsInArray, EML2_NS::AbstractHdfProxy* proxy) + double const * points, EML2_NS::AbstractLocal3dCrs const* localCrs, uint64_t const* dimensions, uint32_t numDimensionsInArray, EML2_NS::AbstractHdfProxy* proxy) { if (localCrs == nullptr) { localCrs = getRepository()->getDefaultCrs(); @@ -126,22 +126,24 @@ gsoap_resqml2_0_1::resqml20__PointGeometry* AbstractRepresentation::createPointG geom->LocalCrs = localCrs->newResqmlReference(); // XML - gsoap_resqml2_0_1::resqml20__Point3dHdf5Array* xmlPts = gsoap_resqml2_0_1::soap_new_resqml20__Point3dHdf5Array(gsoapProxy2_0_1->soap); - xmlPts->Coordinates = gsoap_resqml2_0_1::soap_new_eml20__Hdf5Dataset(gsoapProxy2_0_1->soap); - xmlPts->Coordinates->HdfProxy = proxy->newResqmlReference(); - ostringstream oss; - oss << "points_patch" << patchIndex; - xmlPts->Coordinates->PathInHdfFile = getHdfGroup() + "/" + oss.str(); - geom->Points = xmlPts; - - // HDF - std::unique_ptr numValues(new uint64_t[numDimensionsInArray + 1]); - for (size_t i = 0; i < numDimensionsInArray; ++i) { - numValues[i] = numPoints[i]; + auto* xmlCoords = gsoap_resqml2_0_1::soap_new_eml20__Hdf5Dataset(gsoapProxy2_0_1->soap); + xmlCoords->HdfProxy = proxy->newResqmlReference(); + xmlCoords->PathInHdfFile = getHdfGroup() + "/" + "points_patch" + std::to_string(patchIndex); + if (dimensions[numDimensionsInArray - 1] == 3) { + gsoap_resqml2_0_1::resqml20__Point3dHdf5Array* xmlPts = gsoap_resqml2_0_1::soap_new_resqml20__Point3dHdf5Array(gsoapProxy2_0_1->soap); + xmlPts->Coordinates = xmlCoords; + geom->Points = xmlPts; + } + else if (dimensions[numDimensionsInArray - 1] == 2) { + gsoap_resqml2_0_1::resqml20__Point2dHdf5Array* xmlPts = gsoap_resqml2_0_1::soap_new_resqml20__Point2dHdf5Array(gsoapProxy2_0_1->soap); + xmlPts->Coordinates = xmlCoords; + geom->Points = xmlPts; + } + else { + throw invalid_argument("Only support PointGeometryPatch2_0_1 2D and 3D"); } - numValues[numDimensionsInArray] = 3; // 3 for X, Y and Z - proxy->writeArrayNdOfDoubleValues(getHdfGroup(), oss.str(), points, numValues.get(), numDimensionsInArray + 1); + proxy->writeArrayNdOfDoubleValues(getHdfGroup(), "points_patch" + std::to_string(patchIndex), points, dimensions, numDimensionsInArray); return geom; } @@ -151,7 +153,7 @@ gsoap_resqml2_0_1::resqml20__PointGeometry* AbstractRepresentation::createPointG } gsoap_eml2_3::resqml22__PointGeometry* AbstractRepresentation::createPointGeometryPatch2_2(uint64_t patchIndex, - double const * points, EML2_NS::AbstractLocal3dCrs const* localCrs, uint64_t const* numPoints, uint32_t numDimensionsInArray, EML2_NS::AbstractHdfProxy* proxy) + double const * points, EML2_NS::AbstractLocal3dCrs const* localCrs, uint64_t const* dimensions, uint32_t numDimensionsInArray, EML2_NS::AbstractHdfProxy* proxy) { if (localCrs == nullptr) { localCrs = getRepository()->getDefaultCrs(); @@ -172,23 +174,27 @@ gsoap_eml2_3::resqml22__PointGeometry* AbstractRepresentation::createPointGeomet geom->LocalCrs = localCrs->newEml23Reference(); // XML - size_t valueCount = numPoints[0] * 3; - for (size_t dimIndex = 1; dimIndex < numDimensionsInArray; ++dimIndex) { - valueCount *= numPoints[dimIndex]; + size_t valueCount = 1; + for (size_t dimIndex = 0; dimIndex < numDimensionsInArray; ++dimIndex) { + valueCount *= dimensions[dimIndex]; + } + if (dimensions[numDimensionsInArray - 1] == 3) { + gsoap_eml2_3::resqml22__Point3dExternalArray* xmlPts = gsoap_eml2_3::soap_new_resqml22__Point3dExternalArray(gsoapProxy2_3->soap); + xmlPts->Coordinates = gsoap_eml2_3::soap_new_eml23__ExternalDataArray(gsoapProxy2_3->soap); + xmlPts->Coordinates->ExternalDataArrayPart.push_back(createExternalDataArrayPart(getHdfGroup() + "/points_patch" + std::to_string(patchIndex), valueCount, proxy)); + geom->Points = xmlPts; + } + else if (dimensions[numDimensionsInArray - 1] == 2) { + gsoap_eml2_3::resqml22__Point2dExternalArray* xmlPts = gsoap_eml2_3::soap_new_resqml22__Point2dExternalArray(gsoapProxy2_3->soap); + xmlPts->Coordinates = gsoap_eml2_3::soap_new_eml23__ExternalDataArray(gsoapProxy2_3->soap); + xmlPts->Coordinates->ExternalDataArrayPart.push_back(createExternalDataArrayPart(getHdfGroup() + "/points_patch" + std::to_string(patchIndex), valueCount, proxy)); + geom->Points = xmlPts; } - gsoap_eml2_3::resqml22__Point3dExternalArray* xmlPts = gsoap_eml2_3::soap_new_resqml22__Point3dExternalArray(gsoapProxy2_3->soap); - xmlPts->Coordinates = gsoap_eml2_3::soap_new_eml23__ExternalDataArray(gsoapProxy2_3->soap); - xmlPts->Coordinates->ExternalDataArrayPart.push_back(createExternalDataArrayPart(getHdfGroup() + "/points_patch" + std::to_string(patchIndex), valueCount, proxy)); - geom->Points = xmlPts; - - // HDF - std::unique_ptr numValues(new uint64_t[numDimensionsInArray + 1]); - for (uint32_t i = 0; i < numDimensionsInArray; ++i) { - numValues[i] = numPoints[i]; + else { + throw invalid_argument("Only support PointGeometryPatch2_2 2D and 3D"); } - numValues[numDimensionsInArray] = 3; // 3 for X, Y and Z - proxy->writeArrayNdOfDoubleValues(getHdfGroup(), "points_patch" + std::to_string(patchIndex), points, numValues.get(), numDimensionsInArray + 1); + proxy->writeArrayNdOfDoubleValues(getHdfGroup(), "points_patch" + std::to_string(patchIndex), points, dimensions, numDimensionsInArray); return geom; } diff --git a/src/resqml2/AbstractRepresentation.h b/src/resqml2/AbstractRepresentation.h index 244a5a24..5c15ea12 100644 --- a/src/resqml2/AbstractRepresentation.h +++ b/src/resqml2/AbstractRepresentation.h @@ -447,18 +447,18 @@ namespace RESQML2_NS * geometry. * @param [in,out] points All the points to set ordered according the topology * of the representation it is based on. It should be 3 * - * numPoints sized. + * numPoints sized if 3d and 2 * numPoints sized if 2d, etc... * @param [in,out] localCrs The local CRS where the points lie on. - * @param [in,out] numPoints The number of points for each dimension of the array - * to write. + * @param [in,out] dimensions The dimensions of the array to write. * @param numDimensionsInArray The number of dimensions in the array to write. * @param [in,out] proxy The HDF proxy where to write the points. It must be * already opened for writing and won't be closed in this * method. * - * @returns Null if it fails, else the new point geometry patch 2 0 1. + * @returns Null if it fails, else the new 2.0.1 point geometry patch. */ - gsoap_resqml2_0_1::resqml20__PointGeometry* createPointGeometryPatch2_0_1(uint64_t patchIndex, double const * points, EML2_NS::AbstractLocal3dCrs const* localCrs, uint64_t const * numPoints, uint32_t numDimensionsInArray, EML2_NS::AbstractHdfProxy * proxy); + gsoap_resqml2_0_1::resqml20__PointGeometry* createPointGeometryPatch2_0_1(uint64_t patchIndex, + double const * points, EML2_NS::AbstractLocal3dCrs const* localCrs, uint64_t const * dimensions, uint32_t numDimensionsInArray, EML2_NS::AbstractHdfProxy * proxy); /** * Creates a v2.2 point geometry patch. @@ -467,10 +467,9 @@ namespace RESQML2_NS * geometry. * @param [in,out] points All the points to set ordered according the topology * of the representation it is based on. It should be 3 * - * numPoints sized. + * numPoints sized if 3d and 2 * numPoints sized if 2d, etc... * @param [in,out] localCrs The local CRS where the points lie on. - * @param [in,out] numPoints The number of points for each dimension of the array - * to write. + * @param [in,out] dimensions The dimensions of the array to write. * @param numDimensionsInArray The number of dimensions in the array to write. * @param [in,out] proxy The HDF proxy where to write the points. It must be * already opened for writing and won't be closed in this @@ -478,7 +477,8 @@ namespace RESQML2_NS * * @returns Null if it fails, else the new point geometry patch 2 0 1. */ - gsoap_eml2_3::resqml22__PointGeometry* createPointGeometryPatch2_2(uint64_t patchIndex, double const * points, EML2_NS::AbstractLocal3dCrs const* localCrs, uint64_t const * numPoints, uint32_t numDimensionsInArray, EML2_NS::AbstractHdfProxy * proxy); + gsoap_eml2_3::resqml22__PointGeometry* createPointGeometryPatch2_2(uint64_t patchIndex, + double const * points, EML2_NS::AbstractLocal3dCrs const* localCrs, uint64_t const * dimensions, uint32_t numDimensionsInArray, EML2_NS::AbstractHdfProxy * proxy); /** * Gets hdf proxy dor from point geometry patch diff --git a/src/resqml2/PointSetRepresentation.h b/src/resqml2/PointSetRepresentation.h index e648cc05..0b2d675a 100644 --- a/src/resqml2/PointSetRepresentation.h +++ b/src/resqml2/PointSetRepresentation.h @@ -35,12 +35,12 @@ namespace RESQML2_NS virtual ~PointSetRepresentation() = default; /** - * Pushes back a new patch of points. + * Pushes back a new patch of XYZ points. * * @exception std::invalid_argument If proxy == nullptr and no default HDF proxy is * defined in the repository. * @exception std::invalid_argument If localCrs == nullptr and no default local CRS - * id defined in the repository. + * is defined in the repository. * * @param xyzPointCount The xyz points count in this patch. * @param [in] xyzPoints The xyz values of the points of the patch. Ordered by xyz and @@ -52,10 +52,50 @@ namespace RESQML2_NS * nullptr (default), then the repository default local CRS will * be used. */ - DLL_IMPORT_OR_EXPORT virtual void pushBackGeometryPatch( - unsigned int xyzPointCount, double const * xyzPoints, + DLL_IMPORT_OR_EXPORT virtual void pushBackXyzGeometryPatch( + uint64_t xyzPointCount, double const * xyzPoints, EML2_NS::AbstractHdfProxy* proxy = nullptr, EML2_NS::AbstractLocal3dCrs * localCrs = nullptr) = 0; + /** + * Pushes back a new patch of XY points. + * + * @exception std::invalid_argument If proxy == nullptr and no default HDF proxy is + * defined in the repository. + * @exception std::invalid_argument If localCrs == nullptr and no default local CRS + * is defined in the repository. + * + * @param xyPointCount The xy points count in this patch. + * @param [in] xyPoints The xy values of the points of the patch. Ordered by xy and + * then by @p xyPointCount. Size is 2 * xyPointCount. + * @param [in,out] proxy (Optional) The HDF proxy which defines where the xy points + * will be stored. If @c nullptr (default), then the repository + * default HDF proxy will be used. + * @param [in] localCrs (Optional) The local CRS where the points are given. If @c + * nullptr (default), then the repository default local CRS will + * be used. + */ + DLL_IMPORT_OR_EXPORT virtual void pushBackXyGeometryPatch( + uint64_t xyPointCount, double const* xyPoints, + EML2_NS::AbstractHdfProxy* proxy = nullptr, EML2_NS::AbstractLocal3dCrs* localCrs = nullptr) = 0; + + /** + * Check if a point set representation patch is in 2 dimensions (i.e XY) instead of 3 dimensions (i.e XYZ) + * + * @param [in] patchIndex The index of the patch + */ + DLL_IMPORT_OR_EXPORT virtual bool isIn2D(uint64_t patchIndex) const = 0; + + /** + * Get all the XY points of a particular patch of this representation. XY points are given in + * the local CRS. You probably want to check first if the patch in in 2D using method bool isIn2D(uint64_t patchIndex). + * + * @param patchIndex Zero-based index of the patch. + * @param [in,out] xyPoints A linearized 2d array where the first (quickest) dimension is + * coordinate dimension (XY) and second dimension is vertex + * dimension. It must be pre allocated. + */ + DLL_IMPORT_OR_EXPORT virtual void getXyPointsOfPatch(uint64_t patchIndex, double* xyPoints) const = 0; + /** The standard XML tag without XML namespace for serializing this data object. */ DLL_IMPORT_OR_EXPORT static constexpr char const* XML_TAG = "PointSetRepresentation"; diff --git a/src/resqml2_0_1/PointSetRepresentation.cpp b/src/resqml2_0_1/PointSetRepresentation.cpp index 3152c681..96d3908d 100644 --- a/src/resqml2_0_1/PointSetRepresentation.cpp +++ b/src/resqml2_0_1/PointSetRepresentation.cpp @@ -64,8 +64,8 @@ PointSetRepresentation::PointSetRepresentation(RESQML2_NS::AbstractFeatureInterp setInterpretation(interp); } -void PointSetRepresentation::pushBackGeometryPatch( - unsigned int xyzPointCount, double const * xyzPoints, +void PointSetRepresentation::pushBackXyzGeometryPatch( + uint64_t xyzPointCount, double const* xyzPoints, EML2_NS::AbstractHdfProxy * proxy, EML2_NS::AbstractLocal3dCrs * localCrs) { if (localCrs == nullptr) { @@ -80,8 +80,31 @@ void PointSetRepresentation::pushBackGeometryPatch( patch->Count = xyzPointCount; // XYZ points - uint64_t pointCountDims = xyzPointCount; - patch->Geometry = createPointGeometryPatch2_0_1(patch->PatchIndex, xyzPoints, localCrs, &pointCountDims, 1, proxy); + uint64_t pointCountDims[2] = { xyzPointCount, 3 }; + patch->Geometry = createPointGeometryPatch2_0_1(patch->PatchIndex, xyzPoints, localCrs, pointCountDims, 2, proxy); + + static_cast<_resqml20__PointSetRepresentation*>(gsoapProxy2_0_1)->NodePatch.push_back(patch); + getRepository()->addRelationship(this, localCrs); +} + +void PointSetRepresentation::pushBackXyGeometryPatch( + uint64_t xyPointCount, double const* xyPoints, + EML2_NS::AbstractHdfProxy* proxy, EML2_NS::AbstractLocal3dCrs* localCrs) +{ + if (localCrs == nullptr) { + localCrs = getRepository()->getDefaultCrs(); + if (localCrs == nullptr) { + throw std::invalid_argument("A (default) CRS must be provided."); + } + } + + resqml20__NodePatch* patch = soap_new_resqml20__NodePatch(gsoapProxy2_0_1->soap); + patch->PatchIndex = static_cast<_resqml20__PointSetRepresentation*>(gsoapProxy2_0_1)->NodePatch.size(); + patch->Count = xyPointCount; + + // XYZ points + uint64_t pointCountDims[2] = { xyPointCount, 2 }; + patch->Geometry = createPointGeometryPatch2_0_1(patch->PatchIndex, xyPoints, localCrs, pointCountDims, 2, proxy); static_cast<_resqml20__PointSetRepresentation*>(gsoapProxy2_0_1)->NodePatch.push_back(patch); getRepository()->addRelationship(this, localCrs); @@ -94,11 +117,7 @@ COMMON_NS::DataObjectReference PointSetRepresentation::getHdfProxyDor() const resqml20__PointGeometry* PointSetRepresentation::getPointGeometry2_0_1(uint64_t patchIndex) const { - if (patchIndex >= getPatchCount()) { - throw range_error("The index of the patch is not in the allowed range of patch."); - } - - return static_cast<_resqml20__PointSetRepresentation*>(gsoapProxy2_0_1)->NodePatch[patchIndex]->Geometry; + return static_cast<_resqml20__PointSetRepresentation*>(gsoapProxy2_0_1)->NodePatch.at(patchIndex)->Geometry; } uint64_t PointSetRepresentation::getXyzPointCountOfPatch(unsigned int patchIndex) const @@ -112,18 +131,66 @@ uint64_t PointSetRepresentation::getXyzPointCountOfPatch(unsigned int patchIndex void PointSetRepresentation::getXyzPointsOfPatch(unsigned int patchIndex, double * xyzPoints) const { - if (patchIndex >= getPatchCount()) - throw range_error("The index of the patch is not in the allowed range of patch."); + resqml20__PointGeometry const* pointGeom = getPointGeometry2_0_1(patchIndex); + if (pointGeom != nullptr) { + if (pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__Point3dHdf5Array) + { + eml20__Hdf5Dataset const* dataset = static_cast(pointGeom->Points)->Coordinates; + EML2_NS::AbstractHdfProxy* hdfProxy = getHdfProxyFromDataset(dataset); + hdfProxy->readArrayNdOfDoubleValues(dataset->PathInHdfFile, xyzPoints); + } + else if (pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__Point2dHdf5Array) + { + eml20__Hdf5Dataset const* dataset = static_cast(pointGeom->Points)->Coordinates; + EML2_NS::AbstractHdfProxy* hdfProxy = getHdfProxyFromDataset(dataset); + hdfProxy->readArrayNdOfDoubleValues(dataset->PathInHdfFile, xyzPoints); + const uint64_t pointCount = getXyzPointCountOfPatch(patchIndex); + for (size_t pointIndex = pointCount - 1; pointIndex >= 1; --pointIndex) { + xyzPoints[pointIndex * 3 + 2] = std::numeric_limits::quiet_NaN(); + xyzPoints[pointIndex * 3 + 1] = xyzPoints[pointIndex * 2 + 1]; + xyzPoints[pointIndex * 3] = xyzPoints[pointIndex * 2]; + } + xyzPoints[2] = std::numeric_limits::quiet_NaN(); + } + else { + throw invalid_argument("The geometry of the point set representation is neither simple 3d or 2d."); + } + } + else { + throw invalid_argument("The geometry of the point set representation either does not exist."); + } +} - resqml20__PointGeometry* pointGeom = getPointGeometry2_0_1(patchIndex); - if (pointGeom != nullptr && pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__Point3dHdf5Array) - { - eml20__Hdf5Dataset const * dataset = static_cast(pointGeom->Points)->Coordinates; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - hdfProxy->readArrayNdOfDoubleValues(dataset->PathInHdfFile, xyzPoints); +void PointSetRepresentation::getXyPointsOfPatch(uint64_t patchIndex, double* xyPoints) const +{ + resqml20__PointGeometry const* pointGeom = getPointGeometry2_0_1(patchIndex); + if (pointGeom != nullptr) { + if (pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__Point3dHdf5Array) + { + eml20__Hdf5Dataset const* dataset = static_cast(pointGeom->Points)->Coordinates; + EML2_NS::AbstractHdfProxy* hdfProxy = getHdfProxyFromDataset(dataset); + + const uint64_t pointCount = getXyzPointCountOfPatch(patchIndex); + std::unique_ptr xyzPoints(new double[pointCount*3]); + hdfProxy->readArrayNdOfDoubleValues(dataset->PathInHdfFile, xyzPoints.get()); + for (size_t pointIndex = 0; pointIndex < pointCount; ++pointIndex) { + xyPoints[pointIndex * 2] = xyzPoints[pointIndex * 3]; + xyPoints[pointIndex * 2 + 1] = xyzPoints[pointIndex * 3 + 1]; + } + } + else if (pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__Point2dHdf5Array) + { + eml20__Hdf5Dataset const* dataset = static_cast(pointGeom->Points)->Coordinates; + EML2_NS::AbstractHdfProxy* hdfProxy = getHdfProxyFromDataset(dataset); + hdfProxy->readArrayNdOfDoubleValues(dataset->PathInHdfFile, xyPoints); + } + else { + throw invalid_argument("The geometry of the point set representation is neither simple 3d or 2d."); + } + } + else { + throw invalid_argument("The geometry of the point set representation either does not exist."); } - else - throw invalid_argument("The geometry of the representation either does not exist or it is not an explicit one."); } uint64_t PointSetRepresentation::getPatchCount() const diff --git a/src/resqml2_0_1/PointSetRepresentation.h b/src/resqml2_0_1/PointSetRepresentation.h index 512609eb..3627d962 100644 --- a/src/resqml2_0_1/PointSetRepresentation.h +++ b/src/resqml2_0_1/PointSetRepresentation.h @@ -87,10 +87,21 @@ namespace RESQML2_0_1_NS DLL_IMPORT_OR_EXPORT uint64_t getPatchCount() const final; - DLL_IMPORT_OR_EXPORT void pushBackGeometryPatch( - unsigned int xyzPointCount, double const * xyzPoints, + DLL_IMPORT_OR_EXPORT void pushBackXyzGeometryPatch( + uint64_t xyzPointCount, double const* xyzPoints, EML2_NS::AbstractHdfProxy* proxy = nullptr, EML2_NS::AbstractLocal3dCrs * localCrs = nullptr) final; + DLL_IMPORT_OR_EXPORT void pushBackXyGeometryPatch( + uint64_t xyPointCount, double const* xyPoints, + EML2_NS::AbstractHdfProxy* proxy = nullptr, EML2_NS::AbstractLocal3dCrs* localCrs = nullptr) final; + + DLL_IMPORT_OR_EXPORT bool isIn2D(uint64_t patchIndex) const final { + gsoap_resqml2_0_1::resqml20__PointGeometry* pointGeom = getPointGeometry2_0_1(patchIndex); + return (pointGeom != nullptr && pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__Point2dHdf5Array); + } + + DLL_IMPORT_OR_EXPORT void getXyPointsOfPatch(uint64_t patchIndex, double* xyPoints) const final; + /** * The standard XML namespace for serializing this data object. */ diff --git a/src/resqml2_0_1/PolylineRepresentation.cpp b/src/resqml2_0_1/PolylineRepresentation.cpp index 8ed71bfd..575ea59d 100644 --- a/src/resqml2_0_1/PolylineRepresentation.cpp +++ b/src/resqml2_0_1/PolylineRepresentation.cpp @@ -127,8 +127,8 @@ void PolylineRepresentation::setGeometry(double const* points, unsigned int poin polylineRep->NodePatch->Count = pointCount; polylineRep->NodePatch->PatchIndex = 0; - uint64_t pointCountDims = pointCount; - polylineRep->NodePatch->Geometry = createPointGeometryPatch2_0_1(0, points, localCrs, &pointCountDims, 1, proxy); + uint64_t pointCountDims[2] = { pointCount, 3 }; + polylineRep->NodePatch->Geometry = createPointGeometryPatch2_0_1(0, points, localCrs, pointCountDims, 2, proxy); getRepository()->addRelationship(this, localCrs); } diff --git a/src/resqml2_0_1/PolylineSetRepresentation.cpp b/src/resqml2_0_1/PolylineSetRepresentation.cpp index a033c083..d4cc298b 100644 --- a/src/resqml2_0_1/PolylineSetRepresentation.cpp +++ b/src/resqml2_0_1/PolylineSetRepresentation.cpp @@ -123,11 +123,11 @@ void PolylineSetRepresentation::pushBackGeometryPatch( patch->ClosedPolylines = xmlClosedPolylines; // XYZ points - uint64_t nodeCount = 0; + uint64_t nodeCount[2] = { 0, 3 }; for (uint64_t i = 0; i < polylineCount; ++i) { - nodeCount += nodeCountPerPolyline[i]; + nodeCount[0] += nodeCountPerPolyline[i]; } - patch->Geometry = createPointGeometryPatch2_0_1(patch->PatchIndex, nodes, localCrs, &nodeCount, 1, proxy); + patch->Geometry = createPointGeometryPatch2_0_1(patch->PatchIndex, nodes, localCrs, nodeCount, 2, proxy); static_cast<_resqml20__PolylineSetRepresentation*>(gsoapProxy2_0_1)->LinePatch.push_back(patch); getRepository()->addRelationship(this, localCrs); @@ -187,11 +187,12 @@ void PolylineSetRepresentation::pushBackGeometryPatch( &polylineCount, 1); // XYZ points - uint64_t xyzPtDim = 0; + uint64_t xyzPtDim[2] = { 0, 3 }; for (uint64_t i = 0; i < polylineCount; ++i) { - xyzPtDim += nodeCountPerPolyline[i]; + xyzPtDim[0] += nodeCountPerPolyline[i]; } - patch->Geometry = createPointGeometryPatch2_0_1(patch->PatchIndex, nodes, localCrs, &xyzPtDim, 1, proxy); + + patch->Geometry = createPointGeometryPatch2_0_1(patch->PatchIndex, nodes, localCrs, xyzPtDim, 2, proxy); static_cast<_resqml20__PolylineSetRepresentation*>(gsoapProxy2_0_1)->LinePatch.push_back(patch); getRepository()->addRelationship(this, localCrs); diff --git a/src/resqml2_0_1/TriangulatedSetRepresentation.cpp b/src/resqml2_0_1/TriangulatedSetRepresentation.cpp index 2d1715e3..9cea82ff 100644 --- a/src/resqml2_0_1/TriangulatedSetRepresentation.cpp +++ b/src/resqml2_0_1/TriangulatedSetRepresentation.cpp @@ -109,9 +109,9 @@ void TriangulatedSetRepresentation::pushBackTrianglePatch( patch->PatchIndex = triRep->TrianglePatch.size(); triRep->TrianglePatch.push_back(patch); - uint64_t pointCountDims = nodeCount; + uint64_t pointCountDims[2] = { nodeCount, 3 }; patch->NodeCount = nodeCount; - patch->Geometry = createPointGeometryPatch2_0_1(patch->PatchIndex, nodes, localCrs, &pointCountDims, 1, proxy); + patch->Geometry = createPointGeometryPatch2_0_1(patch->PatchIndex, nodes, localCrs, pointCountDims, 2, proxy); getRepository()->addRelationship(this, localCrs); getRepository()->addRelationship(this, proxy); diff --git a/src/resqml2_2/PointSetRepresentation.cpp b/src/resqml2_2/PointSetRepresentation.cpp index 77fc5c26..aaabdb5f 100644 --- a/src/resqml2_2/PointSetRepresentation.cpp +++ b/src/resqml2_2/PointSetRepresentation.cpp @@ -61,8 +61,8 @@ PointSetRepresentation::PointSetRepresentation(RESQML2_NS::AbstractFeatureInterp setInterpretation(interp); } -void PointSetRepresentation::pushBackGeometryPatch( - unsigned int xyzPointCount, double const * xyzPoints, +void PointSetRepresentation::pushBackXyzGeometryPatch( + uint64_t xyzPointCount, double const* xyzPoints, EML2_NS::AbstractHdfProxy * proxy, EML2_NS::AbstractLocal3dCrs * localCrs) { if (localCrs == nullptr) { @@ -73,9 +73,28 @@ void PointSetRepresentation::pushBackGeometryPatch( } // XYZ points - uint64_t pointCountDims = xyzPointCount; + uint64_t pointCountDims[2] = { xyzPointCount, 3 }; static_cast<_resqml22__PointSetRepresentation*>(gsoapProxy2_3)->NodePatchGeometry.push_back( - createPointGeometryPatch2_2(static_cast<_resqml22__PointSetRepresentation*>(gsoapProxy2_3)->NodePatchGeometry.size(), xyzPoints, localCrs, &pointCountDims, 1, proxy) + createPointGeometryPatch2_2(static_cast<_resqml22__PointSetRepresentation*>(gsoapProxy2_3)->NodePatchGeometry.size(), xyzPoints, localCrs, pointCountDims, 2, proxy) + ); + getRepository()->addRelationship(this, localCrs); +} + +void PointSetRepresentation::pushBackXyGeometryPatch( + uint64_t xyPointCount, double const* xyPoints, + EML2_NS::AbstractHdfProxy* proxy, EML2_NS::AbstractLocal3dCrs* localCrs) +{ + if (localCrs == nullptr) { + localCrs = getRepository()->getDefaultCrs(); + if (localCrs == nullptr) { + throw std::invalid_argument("A (default) CRS must be provided."); + } + } + + // XYZ points + uint64_t pointCountDims[2] = { xyPointCount, 2 }; + static_cast<_resqml22__PointSetRepresentation*>(gsoapProxy2_3)->NodePatchGeometry.push_back( + createPointGeometryPatch2_2(static_cast<_resqml22__PointSetRepresentation*>(gsoapProxy2_3)->NodePatchGeometry.size(), xyPoints, localCrs, pointCountDims, 2, proxy) ); getRepository()->addRelationship(this, localCrs); } @@ -87,11 +106,7 @@ COMMON_NS::DataObjectReference PointSetRepresentation::getHdfProxyDor() const resqml22__PointGeometry* PointSetRepresentation::getPointGeometry2_2(uint64_t patchIndex) const { - if (patchIndex >= getPatchCount()) { - throw range_error("The index of the patch is not in the allowed range of patch."); - } - - return static_cast<_resqml22__PointSetRepresentation*>(gsoapProxy2_3)->NodePatchGeometry[patchIndex]; + return static_cast<_resqml22__PointSetRepresentation*>(gsoapProxy2_3)->NodePatchGeometry.at(patchIndex); } uint64_t PointSetRepresentation::getXyzPointCountOfPatch(unsigned int patchIndex) const @@ -100,31 +115,88 @@ uint64_t PointSetRepresentation::getXyzPointCountOfPatch(unsigned int patchIndex throw range_error("The index of the patch is not in the allowed range of patch."); } auto const* ptArray = static_cast<_resqml22__PointSetRepresentation*>(gsoapProxy2_3)->NodePatchGeometry[patchIndex]->Points; - resqml22__Point3dExternalArray const* externalPtArray = dynamic_cast(ptArray); - if (externalPtArray == nullptr) { - throw range_error("Does only support point set where points are in a resqml22__Point3dExternalArray"); + if (ptArray->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__Point3dExternalArray) + { + resqml22__Point3dExternalArray const* externalPtArray = dynamic_cast(ptArray); + + uint64_t result = 0; + for (auto* dataArrayPart : externalPtArray->Coordinates->ExternalDataArrayPart) { + result += std::accumulate(std::begin(dataArrayPart->Count), std::end(dataArrayPart->Count), static_cast(1), std::multiplies()); + } + return result / 3; } + else if (ptArray->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__Point2dExternalArray) + { + resqml22__Point2dExternalArray const* externalPtArray = dynamic_cast(ptArray); - uint64_t result = 0; - for (auto* dataArrayPart : externalPtArray->Coordinates->ExternalDataArrayPart) { - result += std::accumulate(std::begin(dataArrayPart->Count), std::end(dataArrayPart->Count), static_cast(1), std::multiplies()); + uint64_t result = 0; + for (auto* dataArrayPart : externalPtArray->Coordinates->ExternalDataArrayPart) { + result += std::accumulate(std::begin(dataArrayPart->Count), std::end(dataArrayPart->Count), static_cast(1), std::multiplies()); + } + return result / 2; + } + else { + throw invalid_argument("The geometry of the point set representation is neither simple 3d or 2d."); } - return result / 3; } void PointSetRepresentation::getXyzPointsOfPatch(unsigned int patchIndex, double * xyzPoints) const { - if (patchIndex >= getPatchCount()) - throw range_error("The index of the patch is not in the allowed range of patch."); + resqml22__PointGeometry const* pointGeom = getPointGeometry2_2(patchIndex); + if (pointGeom != nullptr) { + if (pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__Point3dExternalArray) + { + auto const* daPart = static_cast(pointGeom->Points)->Coordinates->ExternalDataArrayPart[0]; + getOrCreateHdfProxyFromDataArrayPart(daPart)->readArrayNdOfDoubleValues(daPart->PathInExternalFile, xyzPoints); + } + else if (pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__Point2dExternalArray) + { + auto const* daPart = static_cast(pointGeom->Points)->Coordinates->ExternalDataArrayPart[0]; + getOrCreateHdfProxyFromDataArrayPart(daPart)->readArrayNdOfDoubleValues(daPart->PathInExternalFile, xyzPoints); + const uint64_t pointCount = getXyzPointCountOfPatch(patchIndex); + for (size_t pointIndex = pointCount - 1; pointIndex >= 1; --pointIndex) { + xyzPoints[pointIndex * 3 + 2] = std::numeric_limits::quiet_NaN(); + xyzPoints[pointIndex * 3 + 1] = xyzPoints[pointIndex * 2 + 1]; + xyzPoints[pointIndex * 3] = xyzPoints[pointIndex * 2]; + } + xyzPoints[2] = std::numeric_limits::quiet_NaN(); + } + else { + throw invalid_argument("The geometry of the point set representation is neither simple 3d or 2d."); + } + } + else { + throw invalid_argument("The geometry of the point set representation either does not exist."); + } +} - resqml22__PointGeometry* pointGeom = getPointGeometry2_2(patchIndex); - if (pointGeom != nullptr && pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__Point3dExternalArray) - { - auto const* daPart = static_cast(pointGeom->Points)->Coordinates->ExternalDataArrayPart[0]; - getOrCreateHdfProxyFromDataArrayPart(daPart)->readArrayNdOfDoubleValues(daPart->PathInExternalFile, xyzPoints); +void PointSetRepresentation::getXyPointsOfPatch(uint64_t patchIndex, double* xyPoints) const +{ + resqml22__PointGeometry const* pointGeom = getPointGeometry2_2(patchIndex); + if (pointGeom != nullptr) { + if (pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__Point3dExternalArray) + { + auto const* daPart = static_cast(pointGeom->Points)->Coordinates->ExternalDataArrayPart[0]; + const uint64_t pointCount = getXyzPointCountOfPatch(patchIndex); + std::unique_ptr xyzPoints(new double[pointCount * 3]); + getOrCreateHdfProxyFromDataArrayPart(daPart)->readArrayNdOfDoubleValues(daPart->PathInExternalFile, xyzPoints.get()); + for (size_t pointIndex = 0; pointIndex < pointCount; ++pointIndex) { + xyPoints[pointIndex * 2] = xyzPoints[pointIndex * 3]; + xyPoints[pointIndex * 2 + 1] = xyzPoints[pointIndex * 3 + 1]; + } + } + else if (pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__Point2dExternalArray) + { + auto const* daPart = static_cast(pointGeom->Points)->Coordinates->ExternalDataArrayPart[0]; + getOrCreateHdfProxyFromDataArrayPart(daPart)->readArrayNdOfDoubleValues(daPart->PathInExternalFile, xyPoints); + } + else { + throw invalid_argument("The geometry of the point set representation is neither simple 3d or 2d."); + } + } + else { + throw invalid_argument("The geometry of the point set representation either does not exist."); } - else - throw invalid_argument("The geometry of the representation either does not exist or it is not an explicit one."); } uint64_t PointSetRepresentation::getPatchCount() const diff --git a/src/resqml2_2/PointSetRepresentation.h b/src/resqml2_2/PointSetRepresentation.h index bd7d4ece..92aab0c5 100644 --- a/src/resqml2_2/PointSetRepresentation.h +++ b/src/resqml2_2/PointSetRepresentation.h @@ -87,9 +87,20 @@ namespace RESQML2_2_NS DLL_IMPORT_OR_EXPORT uint64_t getPatchCount() const final; - DLL_IMPORT_OR_EXPORT void pushBackGeometryPatch( - unsigned int xyzPointCount, double const * xyzPoints, - EML2_NS::AbstractHdfProxy* proxy = nullptr, EML2_NS::AbstractLocal3dCrs * localCrs = nullptr) final; + DLL_IMPORT_OR_EXPORT void pushBackXyzGeometryPatch( + uint64_t xyzPointCount, double const* xyzPoints, + EML2_NS::AbstractHdfProxy* proxy = nullptr, EML2_NS::AbstractLocal3dCrs* localCrs = nullptr) final; + + DLL_IMPORT_OR_EXPORT void pushBackXyGeometryPatch( + uint64_t xyPointCount, double const* xyPoints, + EML2_NS::AbstractHdfProxy* proxy = nullptr, EML2_NS::AbstractLocal3dCrs* localCrs = nullptr) final; + + DLL_IMPORT_OR_EXPORT bool isIn2D(uint64_t patchIndex) const final { + gsoap_eml2_3::resqml22__PointGeometry* pointGeom = getPointGeometry2_2(patchIndex); + return (pointGeom != nullptr && pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__Point2dExternalArray); + } + + DLL_IMPORT_OR_EXPORT void getXyPointsOfPatch(uint64_t patchIndex, double* xyPoints) const final; /** * The standard XML namespace for serializing this data object. diff --git a/src/resqml2_2/PolylineRepresentation.cpp b/src/resqml2_2/PolylineRepresentation.cpp index bc960818..b3792734 100644 --- a/src/resqml2_2/PolylineRepresentation.cpp +++ b/src/resqml2_2/PolylineRepresentation.cpp @@ -129,8 +129,8 @@ void PolylineRepresentation::setGeometry(double const* points, unsigned int poin } _resqml22__PolylineRepresentation* polylineRep = static_cast<_resqml22__PolylineRepresentation*>(gsoapProxy2_3); - uint64_t pointCountDims = pointCount; - polylineRep->NodePatchGeometry = createPointGeometryPatch2_2(0, points, localCrs, &pointCountDims, 1, proxy); + uint64_t pointCountDims[2] = { pointCount, 3 }; + polylineRep->NodePatchGeometry = createPointGeometryPatch2_2(0, points, localCrs, pointCountDims, 2, proxy); getRepository()->addRelationship(this, localCrs); } diff --git a/src/resqml2_2/PolylineSetRepresentation.cpp b/src/resqml2_2/PolylineSetRepresentation.cpp index a939cda1..33088422 100644 --- a/src/resqml2_2/PolylineSetRepresentation.cpp +++ b/src/resqml2_2/PolylineSetRepresentation.cpp @@ -108,15 +108,15 @@ void PolylineSetRepresentation::pushBackGeometryPatch( patch->ClosedPolylines = xmlClosedPolylines; // XYZ points - uint64_t nodeCount = 0; + uint64_t nodeCount[2] = { 0, 3 }; uint64_t intervalCount = 0; for (size_t i = 0; i < polylineCount; ++i) { - nodeCount += nodeCountPerPolyline[i]; + nodeCount[0] += nodeCountPerPolyline[i]; intervalCount += nodeCountPerPolyline[i] - 1; } - patch->NodeCount = nodeCount; + patch->NodeCount = nodeCount[0]; patch->IntervalCount = intervalCount; - patch->Geometry = createPointGeometryPatch2_2(static_cast<_resqml22__PolylineSetRepresentation*>(gsoapProxy2_3)->LinePatch.size(), nodes, localCrs, &nodeCount, 1, proxy); + patch->Geometry = createPointGeometryPatch2_2(static_cast<_resqml22__PolylineSetRepresentation*>(gsoapProxy2_3)->LinePatch.size(), nodes, localCrs, nodeCount, 2, proxy); static_cast<_resqml22__PolylineSetRepresentation*>(gsoapProxy2_3)->LinePatch.push_back(patch); getRepository()->addRelationship(this, localCrs); @@ -163,15 +163,15 @@ void PolylineSetRepresentation::pushBackGeometryPatch( patch->ClosedPolylines = xmlClosedPolylines; // XYZ points - uint64_t nodeCount = 0; + uint64_t nodeCount[2] = { 0, 3 }; uint64_t intervalCount = 0; for (size_t i = 0; i < polylineCount; ++i) { - nodeCount += nodeCountPerPolyline[i]; + nodeCount[0] += nodeCountPerPolyline[i]; intervalCount += nodeCountPerPolyline[i] - 1; } - patch->NodeCount = nodeCount; + patch->NodeCount = nodeCount[0]; patch->IntervalCount = intervalCount; - patch->Geometry = createPointGeometryPatch2_2(static_cast<_resqml22__PolylineSetRepresentation*>(gsoapProxy2_3)->LinePatch.size(), nodes, localCrs, &nodeCount, 1, proxy); + patch->Geometry = createPointGeometryPatch2_2(static_cast<_resqml22__PolylineSetRepresentation*>(gsoapProxy2_3)->LinePatch.size(), nodes, localCrs, nodeCount, 2, proxy); static_cast<_resqml22__PolylineSetRepresentation*>(gsoapProxy2_3)->LinePatch.push_back(patch); getRepository()->addRelationship(this, localCrs); diff --git a/src/resqml2_2/StreamlinesRepresentation.cpp b/src/resqml2_2/StreamlinesRepresentation.cpp index 24908f78..df9f0191 100644 --- a/src/resqml2_2/StreamlinesRepresentation.cpp +++ b/src/resqml2_2/StreamlinesRepresentation.cpp @@ -193,14 +193,14 @@ void StreamlinesRepresentation::setGeometry( auto* polyline = soap_new_resqml22__PolylineSetPatch(getGsoapContext()); rep->Geometry = polyline; - uint64_t nodeCount = 0; + uint64_t nodeCount[2] = { 0, 3 }; uint64_t intervalCount = 0; const uint64_t lineCount = getLineCount(); for (size_t lineIndex = 0; lineIndex < lineCount; ++lineIndex) { - nodeCount += nodeCountPerPolyline[lineIndex]; - intervalCount += nodeCount - 1; + nodeCount[0] += nodeCountPerPolyline[lineIndex]; + intervalCount += nodeCount[0] - 1; } - polyline->NodeCount = nodeCount; + polyline->NodeCount = nodeCount[0]; polyline->IntervalCount = intervalCount; eml23__BooleanConstantArray* closedPolylines = soap_new_eml23__BooleanConstantArray(getGsoapContext()); @@ -229,7 +229,7 @@ void StreamlinesRepresentation::setGeometry( throw std::invalid_argument("A (default) CRS must be provided."); } } - polyline->Geometry = createPointGeometryPatch2_2(0, xyzPoints, localCrs, &nodeCount, 1, hdfProxy); + polyline->Geometry = createPointGeometryPatch2_2(0, xyzPoints, localCrs, nodeCount, 2, hdfProxy); getRepository()->addRelationship(this, localCrs); } diff --git a/src/resqml2_2/TriangulatedSetRepresentation.cpp b/src/resqml2_2/TriangulatedSetRepresentation.cpp index fc8d035a..bea36f11 100644 --- a/src/resqml2_2/TriangulatedSetRepresentation.cpp +++ b/src/resqml2_2/TriangulatedSetRepresentation.cpp @@ -110,9 +110,9 @@ void TriangulatedSetRepresentation::pushBackTrianglePatch( resqml22__TrianglePatch* patch = soap_new_resqml22__TrianglePatch(gsoapProxy2_3->soap); - uint64_t pointCountDims = nodeCount; + uint64_t pointCountDims[2] = { nodeCount, 3 }; patch->NodeCount = nodeCount; - patch->Geometry = createPointGeometryPatch2_2(triRep->TrianglePatch.size(), nodes, localCrs, &pointCountDims, 1, proxy); + patch->Geometry = createPointGeometryPatch2_2(triRep->TrianglePatch.size(), nodes, localCrs, pointCountDims, 2, proxy); getRepository()->addRelationship(this, localCrs); getRepository()->addRelationship(this, proxy); diff --git a/swig/swigResqml2Include.i b/swig/swigResqml2Include.i index 3b62d754..cbe002a9 100644 --- a/swig/swigResqml2Include.i +++ b/swig/swigResqml2Include.i @@ -3165,9 +3165,67 @@ namespace RESQML2_NS class PointSetRepresentation : public AbstractRepresentation { public: - void pushBackGeometryPatch( - unsigned int xyzPointCount, double * xyzPoints, - EML2_NS::AbstractHdfProxy* proxy = nullptr, EML2_NS::AbstractLocal3dCrs * localCrs = nullptr); + /** + * Pushes back a new patch of XYZ points. + * + * @exception std::invalid_argument If proxy == nullptr and no default HDF proxy is + * defined in the repository. + * @exception std::invalid_argument If localCrs == nullptr and no default local CRS + * is defined in the repository. + * + * @param xyzPointCount The xyz points count in this patch. + * @param [in] xyzPoints The xyz values of the points of the patch. Ordered by xyz and + * then by @p xyzPointCount. Size is 3 * xyzPointCount. + * @param [in,out] proxy (Optional) The HDF proxy which defines where the xyz points + * will be stored. If @c nullptr (default), then the repository + * default HDF proxy will be used. + * @param [in] localCrs (Optional) The local CRS where the points are given. If @c + * nullptr (default), then the repository default local CRS will + * be used. + */ + virtual void pushBackXyzGeometryPatch( + uint64_t xyzPointCount, double const * xyzPoints, + EML2_NS::AbstractHdfProxy* proxy = nullptr, EML2_NS::AbstractLocal3dCrs * localCrs = nullptr) = 0; + + /** + * Pushes back a new patch of XY points. + * + * @exception std::invalid_argument If proxy == nullptr and no default HDF proxy is + * defined in the repository. + * @exception std::invalid_argument If localCrs == nullptr and no default local CRS + * is defined in the repository. + * + * @param xyPointCount The xy points count in this patch. + * @param [in] xyPoints The xy values of the points of the patch. Ordered by xy and + * then by @p xyPointCount. Size is 2 * xyPointCount. + * @param [in,out] proxy (Optional) The HDF proxy which defines where the xy points + * will be stored. If @c nullptr (default), then the repository + * default HDF proxy will be used. + * @param [in] localCrs (Optional) The local CRS where the points are given. If @c + * nullptr (default), then the repository default local CRS will + * be used. + */ + virtual void pushBackXyGeometryPatch( + uint64_t xyPointCount, double const* xyPoints, + EML2_NS::AbstractHdfProxy* proxy = nullptr, EML2_NS::AbstractLocal3dCrs* localCrs = nullptr) = 0; + + /** + * Check if a point set representation patch is in 2 dimensions (i.e XY) instead of 3 dimensions (i.e XYZ) + * + * @param [in] patchIndex The index of the patch + */ + virtual bool isIn2D(uint64_t patchIndex) const = 0; + + /** + * Get all the XY points of a particular patch of this representation. XY points are given in + * the local CRS. You probably want to check first if the patch in in 2D using method bool isIn2D(uint64_t patchIndex). + * + * @param patchIndex Zero-based index of the patch. + * @param [in,out] xyPoints A linearized 2d array where the first (quickest) dimension is + * coordinate dimension (XY) and second dimension is vertex + * dimension. It must be pre allocated. + */ + virtual void getXyPointsOfPatch(uint64_t patchIndex, double* xyPoints) const = 0; }; #ifdef SWIGPYTHON