26 #include "../Rocblas/include/Rocblas.h"
27 #include "../Rocsurf/include/Generic_element_2.h"
28 #include "../Rocsurf/include/Rocsurf.h"
33 #define MIN_ANGLE_WEIGHTED 1
37 const Vector_3 &mn,
int nrank)
const {
49 const double eps=1.e-6;
50 double w = 1/lambdas[0];
52 if (trank == 2)
return w;
53 else if ( trank==1 )
return eps*w;
54 else return eps*eps*w;
60 Vector_3 vs[2],
double scales[2],
int *is_strong)
const {
65 const double max_scale=0.07, min_scale=0.005;
68 scales[0] =
std::min( max_scale,
std::max(lambdas[1]/lambdas[0], min_scale));
69 scales[1] =
std::min( max_scale,
std::max(lambdas[2]/lambdas[0], min_scale));
78 *is_strong = acute_ridge || acute_corner ||
87 const double zero = 0., eps = 1.e-100;
93 std::vector< COM::Pane*>::iterator it =
_panes.begin();
94 Manifold::PM_iterator pm_it=
_surf->pm_begin();
95 for (
int i=0, local_npanes =
_panes.size();
96 i<local_npanes; ++
i, ++it, ++pm_it) {
97 COM::Pane *pane = *it;
100 (pane->attribute(
COM_NC)->pointer());
102 (pane->attribute(nodal_disps->id())->pointer()):NULL;
106 ( pane->attribute(
_vcenters->id())->pointer());
107 double *ws =
reinterpret_cast<double*
>
108 ( pane->attribute(
_weights->id())->pointer());
112 ( pane->attribute(
_As->id())->pointer());
114 ( pane->attribute(
_bmedial->id())->pointer());
116 const char *tranks =
reinterpret_cast<const char*
>
117 ( pane->attribute(
_tangranks->id())->pointer());
119 const char *strong =
reinterpret_cast<char*
>
120 ( pane->attribute(
_strong->id())->pointer());
125 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.
next()) {
131 bool has_feature=
false;
135 Ae[0] = Ae[1] = Ae[2] = mn =
Vector_3(0,0,0);
137 for (
int k=0;
k<ne; ++
k) {
138 int vindex = ene[
k]-1;
139 has_feature |= tranks[vindex]!=2;
157 mn = Ae[0]; nrank = 1;
165 Ae[0] = Ae[1] = Ae[2] =
Vector_3(0,0,0);
166 for (
int k=0;
k<ne; ++
k) {
167 int vindex = ene[
k]-1;
170 switch (tranks[ vindex]) {
176 if ( strong[vindex]) {
200 scales_f[0] = scales_e[0]; scales_f[1] = scales_e[1];
201 vs_f[0] = vs_e[0]; vs_f[1] = vs_e[1];
205 int uindex=ene[ne-1]-1, vindex=ene[0]-1;
207 for (
int k=0;
k<ne; ++
k) {
208 int windex = ene[(
k+1==ne)?0:k+1]-1;
210 Point_3 ps[3] = { pnts[uindex], pnts[vindex], pnts[windex] };
212 ps[0] += disps[uindex]; ps[1] += disps[vindex];
213 ps[2] += disps[windex];
222 ( tranks[uindex]==2 || tranks[windex]==2)) {
223 scales_v[0] = scales_e[0]; scales_v[1] = scales_e[1];
224 vs_v[0] = vs_e[0]; vs_v[1] = vs_e[1];
227 scales_v[0] = scales_f[0]; scales_v[1] = scales_f[1];
228 vs_v[0] = vs_f[0]; vs_v[1] = vs_f[1];
232 anipnt = scales_v[0]*(diff*vs_v[0])*vs_v[0]+
233 scales_v[1]*(diff*vs_v[1])*vs_v[1];
234 if ( disps) anipnt += disps[vindex];
239 #if MIN_ANGLE_WEIGHTED
246 vcnts[vindex] += w*anipnt;
249 uindex=vindex; vindex=windex;
261 COM::Attribute *normal_motion) {
263 const double zero = 0., eps = 1.e-100;
269 std::vector< COM::Pane*>::iterator it =
_panes.begin();
270 Manifold::PM_iterator pm_it=
_surf->pm_begin();
271 for (
int i=0, local_npanes =
_panes.size();
272 i<local_npanes; ++
i, ++it, ++pm_it) {
273 COM::Pane *pane = *it;
276 ( pane->attribute(
_As->id())->pointer());
278 ( pane->attribute(
_vnormals->id())->pointer());
281 (pane->attribute(
COM_NC)->pointer());
283 (pane->attribute(nodal_disps->id())->pointer()) : NULL;
286 const char *tranks =
reinterpret_cast<const char*
>
287 ( pane->attribute(
_tangranks->id())->pointer());
289 ( pane->attribute(
_eigvalues->id())->pointer());
292 ( pane->attribute(normal_motion->id())->pointer()) : NULL;
293 double *ws = normal_motion ?
reinterpret_cast<double*
>
294 ( pane->attribute(
_weights->id())->pointer()) : NULL;
295 const double *farea = normal_motion ?
reinterpret_cast<double*
>
296 ( pane->attribute(
_faceareas->id())->pointer()) : NULL;
297 const char *weak =
reinterpret_cast<const char*
>
298 ( pane->attribute(
_weak->id())->pointer());
299 const int *cnstrs =
_cnstr_nodes ?
reinterpret_cast<const int*
>
300 ( pane->attribute(
_cnstr_nodes->id())->pointer()) : NULL;
304 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.next()) {
305 int ne = ene.size_of_edges();
309 Ae[0] = Ae[1] = Ae[2] =
Vector_3(0,0,0);
310 bool is_weak =
false;
312 for (
int k=0;
k<ne; ++
k) {
313 int vindex = ene[
k]-1;
314 if ( weak[vindex]) { is_weak =
true;
break; }
316 if ( !is_weak)
continue;
319 for (
int k=0;
k<ne; ++
k) {
320 int vindex = ene[
k]-1;
326 ( lambdas[vindex], tranks[vindex]-(cnstrs && cnstrs[vindex]));
338 for (
int k=0;
k<ne; ++
k) {
339 int vindex = ene[
k]-1;
343 if ( disps) diff -= disps[vindex];
345 double offset = diff*mn_face, cos_a=mn_face*vnrms[vindex];
346 if (cos_a<0) offset = -
offset;
350 double a = lambdas[vindex][1]/lambdas[vindex][0];
351 nmotion[vindex] += a*(w*
offset)*vnrms[vindex];
359 _surf->reduce_on_shared_nodes( normal_motion, Manifold::OP_SUM);
static void compute_eigenvectors(Vector_3 A[3], Vector_3 &lambdas)
COM::Attribute * _eigvalues
An adaptor for enumerating node IDs of an element.
#define PROP_END_NAMESPACE
COM::Attribute * _cnstr_nodes
#define PROP_BEGIN_NAMESPACE
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
COM::Attribute * _vcenters
COM::Attribute * _faceareas
SURF::Vector_3< Real > Vector_3
COM::Attribute * _tangranks
real *8 function offset(vNorm, x2, y2, z2)
void denoise_surface(const COM::Attribute *disps_buf, COM::Attribute *normal_motion)
std::vector< COM::Pane * > _panes
bool is_strong(const Vector_3 *es, const Vector_3 &lambdas, const Vector_3 &mn, int nrank) const
COM::Attribute * _facecenters
bool is_acute_ridge(const Vector_3 *es, const Vector_3 &lambdas, const Vector_3 &mn, int nrank) const
int size_of_edges() const
Number of edges per element.
COM::Attribute * _bmedial
COM::Attribute * _weights
static void div(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for division.
void compute_anisotropic_vertex_centers(const COM::Attribute *disps_buf)
bool is_acute_corner(const Vector_3 *es, const Vector_3 &lambdas, const Vector_3 &mn, int nrank) const
static double eval_angle(const Vector_3 &v1, const Vector_3 &v2)
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer).
COM::Attribute * _vnormals
void next()
Go to the next element within the connectivity tables of a pane.
Some basic geometric data types.
double get_nonuniform_weight(const Vector_3 &lambdas, int trank)
void get_tangents(const Vector_3 *es, const Vector_3 &lambdas, const Vector_3 &mn, int nrank, Vector_3 vs[2], double scales[2], int *is_strong=NULL) const
int eigen_analyze_vertex(Vector_3 A_io[3], Vector_3 &b_io, double angle_defect=0)