26 #include "../Rocblas/include/Rocblas.h"
27 #include "../Rocsurf/include/Generic_element_2.h"
28 #include "../Rocsurf/include/Rocsurf.h"
37 const COM::Attribute *tangranks,
38 const COM::Attribute *disps,
39 COM::Attribute *vcenters,
41 COM::Attribute *vert_weights_buf,
42 const COM::Attribute *edge_weights) {
43 const double alpha = 0.03;
50 std::vector< COM::Pane*>::iterator it =
_panes.begin();
51 for (
int i=0, local_npanes =
_panes.size();
i<local_npanes; ++
i, ++it) {
52 COM::Pane *pane = *it;
55 double *vws =
reinterpret_cast<double*
>
56 (pane->attribute(vert_weights_buf->id())->pointer());
58 const double *ews = edge_weights ?
reinterpret_cast<const double*
>
59 (pane->attribute(edge_weights->id())->pointer()) : NULL;
63 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.next()) {
64 int ne = ene.size_of_edges();
69 for (
int k=0;
k<ne; ++
k) {
70 vws[ene[
k]-1] += ews ? ews[
j*4+
k] + ews[
j*4+(
k+3)%4] : 1;
74 _surf->reduce_on_shared_nodes( vert_weights_buf, Manifold::OP_SUM);
82 for (
int i=0, local_npanes =
_panes.size();
i<local_npanes; ++
i, ++it) {
83 COM::Pane *pane = *it;
87 (pane->attribute(
COM_NC)->pointer());
89 (pane->attribute(disps->id())->pointer());
91 (pane->attribute(vert_normals->id())->pointer());
93 (pane->attribute(vcenters->id())->pointer());
97 (pane->attribute(buf->id())->pointer());
99 const double *vws =
reinterpret_cast<const double*
>
100 (pane->attribute(vert_weights_buf->id())->pointer());
102 const double *ews = edge_weights ?
reinterpret_cast<const double*
>
103 (pane->attribute(edge_weights->id())->pointer()) : NULL;
111 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.
next()) {
115 "NuLapacian now supports only quadrilateral meshes");
119 for (
int k=0;
k<ne; ++
k) {
120 int uindex = ene[
k]-1;
122 is_regular[
k] =
std::abs(vws[uindex]-4)<1.e-6;
123 pnts_buf[
k] = pnts[uindex] + ds[uindex];
130 for (
int k=0;
k<ne; ++
k) pnts_buf[
k] -= cnt;
133 int uindex=ene[ne-1]-1, vindex=ene[0]-1;
134 for (
int k=0;
k<ne; ++
k, uindex=vindex, vindex=ene[(
k==ne)?0:k]-1) {
137 Vector_3 tng = pnts[uindex]-pnts[vindex]+ vcnt[uindex]-vcnt[vindex];
138 double w = ews ? ews[
j*4+
k] : 0.5;
141 if ( is_regular[k_1]) {
145 dbuf[uindex] -= w * ( pnts_buf[k_1] * nrm_e * nrm_e +
146 alpha * pnts_buf[k_1]);
149 if ( is_regular[k]) {
153 dbuf[vindex] -= w * ( pnts_buf[
k] * nrm_e * nrm_e +
154 alpha * pnts_buf[
k]);
161 _surf->reduce_on_shared_nodes( buf, Manifold::OP_SUM);
165 for (
int i=0, local_npanes =
_panes.size();
i<local_npanes; ++
i, ++it) {
166 COM::Pane *pane = *it;
168 const char *tranks =
reinterpret_cast<const char*
>
169 ( pane->attribute( tangranks->id())->pointer());
170 const double *vws =
reinterpret_cast<const double*
>
171 ( pane->attribute( vert_weights_buf->id())->pointer());
174 ( pane->attribute( vcenters->id())->pointer());
176 ( pane->attribute( buf->id())->pointer());
179 ( pane->attribute(
_eigvecs->id())->pointer());
182 for (
int j=0,
nj=pane->size_of_real_nodes();
j<
nj; ++
j) {
186 vcnt[
j] = dbuf[
j] / vws[
j];
189 vcnt[
j] = (vcnt[
j]*es[3*
j+2])*es[3*
j+2];
190 else if ( tranks[
j] == 2)
191 vcnt[
j] -= (vcnt[
j]*es[3*
j])*es[3*
j];
An adaptor for enumerating node IDs of an element.
#define PROP_END_NAMESPACE
#define PROP_BEGIN_NAMESPACE
#define COM_assertion_msg(EX, msg)
SURF::Vector_3< Real > Vector_3
std::vector< COM::Pane * > _panes
COM::Attribute * _eigvecs
int size_of_edges() const
Number of edges per element.
static Vector_3 cross_product(const Vector_3 &v, const Vector_3 &w)
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer).
void next()
Go to the next element within the connectivity tables of a pane.
Some basic geometric data types.
void nulaplacian_smooth(const COM::Attribute *vert_normals, const COM::Attribute *tangranks, const COM::Attribute *disps, COM::Attribute *vcenters, COM::Attribute *buf, COM::Attribute *vert_weights_buf, const COM::Attribute *edge_weights=NULL)
Redistribute smooth vertices by NuLaplacian smoothing.