Skip to content

Commit

Permalink
Support for Point 2d set
Browse files Browse the repository at this point in the history
Fix #335
  • Loading branch information
philippeVerney committed May 23, 2024
1 parent 6c897ef commit 44c6d87
Show file tree
Hide file tree
Showing 16 changed files with 426 additions and 130 deletions.
46 changes: 38 additions & 8 deletions example/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -2897,9 +2897,39 @@ void deserializeGeobody(COMMON_NS::DataObjectRepository * repo)
{
//2d
std::vector<RESQML2_NS::BoundaryFeature*> 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<RESQML2_NS::PointSetRepresentation const*>(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<double[]> 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<double[]> 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
Expand Down
66 changes: 36 additions & 30 deletions src/resqml2/AbstractRepresentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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<uint64_t[]> 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;
}
Expand All @@ -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();
Expand All @@ -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<uint64_t[]> 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;
}
Expand Down
18 changes: 9 additions & 9 deletions src/resqml2/AbstractRepresentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -467,18 +467,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.
*/
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
Expand Down
48 changes: 44 additions & 4 deletions src/resqml2/PointSetRepresentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <tt>proxy == nullptr</tt> and no default HDF proxy is
* defined in the repository.
* @exception std::invalid_argument If <tt>localCrs == nullptr</tt> 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
Expand All @@ -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 <tt>proxy == nullptr</tt> and no default HDF proxy is
* defined in the repository.
* @exception std::invalid_argument If <tt>localCrs == nullptr</tt> 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 <tt>2 * xyPointCount</tt>.
* @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";

Expand Down
Loading

0 comments on commit 44c6d87

Please sign in to comment.