Skip to content

Commit

Permalink
Merge pull request #180 from vincentcasseau/exportIndirPts
Browse files Browse the repository at this point in the history
Generator: closeMesh: conditionally export vertex indirection table
  • Loading branch information
benoit128 authored Sep 13, 2024
2 parents c8ad282 + f47c342 commit 56ee29d
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 35 deletions.
25 changes: 17 additions & 8 deletions Cassiopee/Generator/Generator/Generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -829,27 +829,36 @@ def closeLegacy(array, tol=1.e-12, suppressDegeneratedNGons=False):

def close(array, tol=1.e-12, rmOverlappingPts=True, rmOrphanPts=True,
rmDuplicatedFaces=True, rmDuplicatedElts=True,
rmDegeneratedFaces=True, rmDegeneratedElts=True):
rmDegeneratedFaces=True, rmDegeneratedElts=True,
indices=None):
"""Close an unstructured mesh defined by an array gathering points closer than tol.
Usage: close(array, tol)"""
exportIndirPts = False
if isinstance(indices, list) and not indices: exportIndirPts = True
if isinstance(array[0], list):
out = []
for a in array:
indirl = None
if len(a) == 5: # merge intra-borders (C-type meshes)
outl = generator.closeBorders([a], [], tol)[0]
else:
outl = generator.closeMesh(a, tol, rmOverlappingPts,
rmOrphanPts, rmDuplicatedFaces,
rmDuplicatedElts,
rmDegeneratedFaces,
rmDegeneratedElts)
rmDuplicatedElts, rmDegeneratedFaces,
rmDegeneratedElts, exportIndirPts)
if exportIndirPts: outl, indirl = outl
out.append(outl)
if exportIndirPts: indices.append(indirl)
return out
else:
return generator.closeMesh(array, tol, rmOverlappingPts,
rmOrphanPts, rmDuplicatedFaces,
rmDuplicatedElts, rmDegeneratedFaces,
rmDegeneratedElts)
out = generator.closeMesh(array, tol, rmOverlappingPts,
rmOrphanPts, rmDuplicatedFaces,
rmDuplicatedElts, rmDegeneratedFaces,
rmDegeneratedElts, exportIndirPts)
if exportIndirPts:
out, indirl = out
indices.append(indirl)
return out

def zip(array, tol=1e-12):
"""Zip a set of meshes defined by gathering exterior points closer than tol.
Expand Down
15 changes: 10 additions & 5 deletions Cassiopee/Generator/Generator/PyTree.py
Original file line number Diff line number Diff line change
Expand Up @@ -844,22 +844,27 @@ def _closeLegacy(t, tol=1.e-12, suppressDegeneratedNGons=False):

def close(a, tol=1.e-12, rmOverlappingPts=True, rmOrphanPts=True,
rmDuplicatedFaces=True, rmDuplicatedElts=True,
rmDegeneratedFaces=True, rmDegeneratedElts=True):
rmDegeneratedFaces=True, rmDegeneratedElts=True,
indices=None):
"""Merge vertices distant of tol and remove multiply defined vertices/faces/elements.
Usage: close(array, tol, rmOverlappingPts, rmOrphanPts, rmDuplicatedFaces,
rmDuplicatedElts, rmDegeneratedFaces, rmDegeneratedElts)"""
rmDuplicatedElts, rmDegeneratedFaces, rmDegeneratedElts,
indices)"""
t = Internal.copyRef(a)
_close(t, tol, rmOverlappingPts, rmOrphanPts, rmDuplicatedFaces,
rmDuplicatedElts, rmDegeneratedFaces, rmDegeneratedElts)
rmDuplicatedElts, rmDegeneratedFaces, rmDegeneratedElts,
indices=indices)
return t

def _close(t, tol=1.e-12, rmOverlappingPts=True, rmOrphanPts=True,
rmDuplicatedFaces=True, rmDuplicatedElts=True,
rmDegeneratedFaces=True, rmDegeneratedElts=True):
rmDegeneratedFaces=True, rmDegeneratedElts=True,
indices=None):
fields = C.getAllFields(t, 'nodes')
fields = Generator.close(fields, tol, rmOverlappingPts, rmOrphanPts,
rmDuplicatedFaces, rmDuplicatedElts,
rmDegeneratedFaces, rmDegeneratedElts)
rmDegeneratedFaces, rmDegeneratedElts,
indices=indices)
C.setFields(fields, t, 'nodes')
return None

Expand Down
8 changes: 5 additions & 3 deletions Cassiopee/Generator/Generator/close.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ PyObject* K_GENERATOR::closeMesh(PyObject* self, PyObject* args)
E_Bool rmDuplicatedElts = true;
E_Bool rmDegeneratedFaces = true;
E_Bool rmDegeneratedElts = true;
E_Bool exportIndirPts = false;

if (!PYPARSETUPLE_(args, O_ R_ BB_ BBBB_,
if (!PYPARSETUPLE_(args, O_ R_ BBB_ BBBB_,
&array, &eps, &rmOverlappingPts, &rmOrphanPts,
&rmDuplicatedFaces, &rmDuplicatedElts,
&rmDegeneratedFaces, &rmDegeneratedElts)) return NULL;
&rmDegeneratedFaces, &rmDegeneratedElts,
&exportIndirPts)) return NULL;

// Check array
E_Int im, jm, km;
Expand Down Expand Up @@ -84,7 +86,7 @@ PyObject* K_GENERATOR::closeMesh(PyObject* self, PyObject* args)
PyObject* tpl = K_CONNECT::V_cleanConnectivity(
varString, *f, *cn, eltType, eps,
rmOverlappingPts, rmOrphanPts, rmDuplicatedFaces, rmDuplicatedElts,
rmDegeneratedFaces, rmDegeneratedElts);
rmDegeneratedFaces, rmDegeneratedElts, exportIndirPts);

RELEASESHAREDU(array, f, cn);
if (tpl == NULL) return array;
Expand Down
6 changes: 6 additions & 0 deletions Cassiopee/Generator/test/closePT_t1.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@
a3 = C.convertArray2Tetra(a)
a3 = G.close(a3, 1.e-3)
test.testT(a3, 3)

# test close non structure tetra avec retour de la table d indir. des vertices
indices = []
a3 = C.convertArray2Tetra(a)
a3 = G.close(a3, 1.e-3, indices=indices)
test.testO(indices, 4)
6 changes: 4 additions & 2 deletions Cassiopee/Generator/test/close_t1.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
a3 = G.close(a3, 1.e-3)
test.testA([a3], 3)

# test close NGON
# test close NGON avec retour de la table d indir. des vertices
indices = []
a4 = G.cylinder((0.,0.,0.), 0.5, 1., 360., 0.01, 10., (10,10,10))
a4 = C.convertArray2NGon(a4)
a4 = C.addVars(a4, 'F')
a4 = G.close(a4, 5.e-3)
a4 = G.close(a4, 5.e-3, indices=indices)
test.testA([a4], 4)
test.testO(indices, 5)
9 changes: 6 additions & 3 deletions Cassiopee/KCore/KCore/Connect/connect.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,15 +423,17 @@ namespace K_CONNECT
K_FLD::FldArrayI& cn, const char* eltType,
E_Float tol=0., E_Bool rmOverlappingPts=true, E_Bool rmOrphanPts=true,
E_Bool rmDuplicatedFaces=true, E_Bool rmDuplicatedElts=true,
E_Bool rmDegeneratedFaces=true, E_Bool rmDegeneratedElts=true);
E_Bool rmDegeneratedFaces=true, E_Bool rmDegeneratedElts=true,
E_Bool exportIndirPts=false);

// Clean connectivity - NGON
PyObject* V_cleanConnectivityNGon(
E_Int posx, E_Int posy, E_Int posz, const char* varString,
K_FLD::FldArrayF& f, K_FLD::FldArrayI& cn,
E_Float tol=0., E_Bool rmOverlappingPts=true, E_Bool rmOrphanPts=true,
E_Bool rmDuplicatedFaces=true, E_Bool rmDuplicatedElts=true,
E_Bool rmDegeneratedFaces=true, E_Bool rmDegeneratedElts=true);
E_Bool rmDegeneratedFaces=true, E_Bool rmDegeneratedElts=true,
E_Bool exportIndirPts=false);

E_Int V_identifyDirtyPoints(
E_Int posx, E_Int posy, E_Int posz,
Expand Down Expand Up @@ -459,7 +461,8 @@ namespace K_CONNECT
E_Int posx, E_Int posy, E_Int posz, const char* varString,
K_FLD::FldArrayF& f, K_FLD::FldArrayI& cn, const char* eltType,
E_Float tol=0., E_Bool rmOverlappingPts=true, E_Bool rmOrphanPts=true,
E_Bool rmDuplicatedElts=true, E_Bool rmDegeneratedElts=true);
E_Bool rmDuplicatedElts=true, E_Bool rmDegeneratedElts=true,
E_Bool exportIndirPts=false);

E_Int V_identifyDirtyElementsME(
E_Int dim, K_FLD::FldArrayI& cn, std::vector<E_Int>& indir,
Expand Down
54 changes: 40 additions & 14 deletions Cassiopee/KCore/KCore/Connect/v_cleanConnectivity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <unordered_set>
#include "Array/Array.h"
#include <string.h>
#include "kcore.h"
#include "String/kstring.h"
#include "Connect/connect.h"

Expand All @@ -40,7 +41,7 @@ PyObject* K_CONNECT::V_cleanConnectivity(
E_Float tol, E_Bool rmOverlappingPts,
E_Bool rmOrphanPts, E_Bool rmDuplicatedFaces,
E_Bool rmDuplicatedElts, E_Bool rmDegeneratedFaces,
E_Bool rmDegeneratedElts
E_Bool rmDegeneratedElts, E_Bool exportIndirPts
)
{
E_Int posx = K_ARRAY::isCoordinateXPresent(varString);
Expand All @@ -49,27 +50,28 @@ PyObject* K_CONNECT::V_cleanConnectivity(
if (posx == -1 || posy == -1 || posz == -1)
{
PyErr_SetString(PyExc_TypeError,
"cleanConnectivity: coord must be present in array.");
"cleanConnectivity: coords must be present in array.");
return NULL;
}
posx++; posy++; posz++;

PyObject* tpl = NULL;
PyObject* o = NULL;
if (K_STRING::cmp(eltType, "NGON") == 0 || K_STRING::cmp(eltType, "NGON*") == 0)
{
tpl = V_cleanConnectivityNGon(posx, posy, posz, varString, f, cn,
tol, rmOverlappingPts, rmOrphanPts,
rmDuplicatedFaces, rmDuplicatedElts,
rmDegeneratedFaces, rmDegeneratedElts);
o = V_cleanConnectivityNGon(posx, posy, posz, varString, f, cn,
tol, rmOverlappingPts, rmOrphanPts,
rmDuplicatedFaces, rmDuplicatedElts,
rmDegeneratedFaces, rmDegeneratedElts,
exportIndirPts);
}
else
{
tpl = V_cleanConnectivityME(posx, posy, posz, varString, f, cn,
eltType, tol, rmOverlappingPts,
rmOrphanPts, rmDuplicatedElts,
rmDegeneratedElts);
o = V_cleanConnectivityME(posx, posy, posz, varString, f, cn,
eltType, tol, rmOverlappingPts, rmOrphanPts,
rmDuplicatedElts, rmDegeneratedElts,
exportIndirPts);
}
return tpl;
return o;
}

// Nettoyage de la connectivite NGON
Expand All @@ -78,7 +80,8 @@ PyObject* K_CONNECT::V_cleanConnectivityNGon(
FldArrayF& f, FldArrayI& cn,
E_Float tol, E_Bool rmOverlappingPts, E_Bool rmOrphanPts,
E_Bool rmDuplicatedFaces, E_Bool rmDuplicatedElts,
E_Bool rmDegeneratedFaces, E_Bool rmDegeneratedElts
E_Bool rmDegeneratedFaces, E_Bool rmDegeneratedElts,
E_Bool exportIndirPts
)
{
E_Bool rmDirtyFaces = (rmDuplicatedFaces || rmDegeneratedFaces);
Expand Down Expand Up @@ -178,6 +181,8 @@ PyObject* K_CONNECT::V_cleanConnectivityNGon(
}
}
}

if (!exportIndirPts) indir.clear();

// --- 2. Identify dirty elements topologically ---
E_Int nuniqueElts = nelts;
Expand Down Expand Up @@ -365,6 +370,15 @@ PyObject* K_CONNECT::V_cleanConnectivityNGon(

RELEASESHAREDU(tpl, f2, cn2);
}

if (exportIndirPts)
{
PyObject* vmap = K_NUMPY::buildNumpyArray(npts, 1, 1);
E_Int* vmapp = K_NUMPY::getNumpyPtrI(vmap);
#pragma omp parallel for
for (E_Int i = 0; i < npts; i++) vmapp[i] = indir[i];
return Py_BuildValue("(OO)", tpl, vmap);
}
return tpl;
}

Expand Down Expand Up @@ -662,7 +676,8 @@ PyObject* K_CONNECT::V_cleanConnectivityME(
E_Int posx, E_Int posy, E_Int posz, const char* varString,
FldArrayF& f, FldArrayI& cn, const char* eltType,
E_Float tol, E_Bool rmOverlappingPts, E_Bool rmOrphanPts,
E_Bool rmDuplicatedElts, E_Bool rmDegeneratedElts
E_Bool rmDuplicatedElts, E_Bool rmDegeneratedElts,
E_Bool exportIndirPts
)
{
E_Bool rmDirtyElts = (rmDuplicatedElts || rmDegeneratedElts);
Expand Down Expand Up @@ -777,6 +792,8 @@ PyObject* K_CONNECT::V_cleanConnectivityME(
}
}
}

if (!exportIndirPts) indir.clear();

// 1.d Resize fields
//f.reAllocMat(nuniquePts,nfld);
Expand Down Expand Up @@ -864,6 +881,15 @@ PyObject* K_CONNECT::V_cleanConnectivityME(
}
RELEASESHAREDU(tpl, f2, cn2);
}

if (exportIndirPts)
{
PyObject* vmap = K_NUMPY::buildNumpyArray(npts, 1, 1);
E_Int* vmapp = K_NUMPY::getNumpyPtrI(vmap);
#pragma omp parallel for
for (E_Int i = 0; i < npts; i++) vmapp[i] = indir[i];
return Py_BuildValue("(OO)", tpl, vmap);
}
return tpl;
}

Expand Down

0 comments on commit 56ee29d

Please sign in to comment.