40 #define EXPORT_DEBUG_INFO 1
42 static const double half_pi = 1.5707963267949;
43 static const double pi = 3.14159265358979;
45 inline double SQR(
double x) {
return (x*x); }
48 void dsytrd3(
double A[3][3],
double Q[3][3],
double d[3],
double e[2])
66 for (
int i=0;
i < 3;
i++)
69 for (
int j=0;
j <
i;
j++)
70 Q[i][
j] = Q[
j][i] = 0.0;
74 h =
SQR(A[0][1]) +
SQR(A[0][2]);
89 for (
int i=1;
i < 3;
i++)
91 f = A[1][
i] * u[1] + A[
i][2] * u[2];
95 K *= 0.5 *
SQR(omega);
97 for (
int i=1;
i < 3;
i++)
98 q[
i] = q[
i] - K * u[
i];
101 d[1] = A[1][1] - 2.0*q[1]*u[1];
102 d[2] = A[2][2] - 2.0*q[2]*u[2];
105 for (
int j=1;
j < 3;
j++)
108 for (
int i=1;
i < 3;
i++)
109 Q[
i][
j] = Q[
i][
j] - f*u[
i];
113 e[1] = A[1][2] - q[1]*u[2] - u[1]*q[2];
117 for (
int i=0;
i < 3;
i++)
124 int dsyevq3(
double A[3][3],
double Q[3][3],
double w[3])
148 double g, r, p, f, b,
s, c, t;
159 for (
int l=0; l < 2; l++)
166 for (m=l; m < 2; m++)
168 g = fabs(w[m])+fabs(w[m+1]);
169 if (fabs(e[m]) + g == g)
179 g = (w[l+1] - w[l]) / (e[l] + e[l]);
182 g = w[m] - w[l] + e[l]/(g + r);
184 g = w[m] - w[l] + e[l]/(g - r);
188 for (
int i=m-1;
i >= l;
i--)
192 if (fabs(f) > fabs(g))
208 r = (w[
i] - g)*s + 2.0*c*b;
214 for (
int k=0;
k < 3;
k++)
217 Q[
k][
i+1] = s*Q[
k][
i] + c*t;
218 Q[
k][
i] = c*Q[
k][
i] - s*t;
232 std::cout <<
"Entering Rocmop::smooth_medial" << std::endl;
242 #if EXPORT_DEBUG_INFO
243 COM::Attribute *vnormals =
const_cast<COM::Attribute*
>(
_usr_window->attribute(
"vnormals"));
244 COM::Attribute *vnrms =
_wrk_window->attribute(
"vnormals");
245 COM::Attribute *awnormals =
const_cast<COM::Attribute*
>(
_usr_window->attribute(
"angleweighted"));
246 COM::Attribute *awnrms =
_wrk_window->attribute(
"awnormals");
247 COM::Attribute *uwnormals =
const_cast<COM::Attribute*
>(
_usr_window->attribute(
"unitweighted"));
248 COM::Attribute *uwnrms =
_wrk_window->attribute(
"uwnormals");
249 COM::Attribute *tangranks =
const_cast<COM::Attribute*
>(
_usr_window->attribute(
"tangranks"));
250 COM::Attribute *tranks =
_wrk_window->attribute(
"tangranks");
251 COM::Attribute *evals =
_wrk_window->attribute(
"lambda");
252 COM::Attribute *eigenvalues =
const_cast<COM::Attribute*
>(
_usr_window->attribute(
"eigenvalues"));
253 COM::Attribute *ws =
_wrk_window->attribute(
"weights");
254 COM::Attribute *weights =
const_cast<COM::Attribute*
>(
_usr_window->attribute(
"adefects"));
276 const std::string att1(
"disps");
277 COM::Attribute *disps =
_wrk_window->attribute(att1);
282 std::cout <<
"Exiting Rocmop::smooth_medial" << std::endl;
288 std::cout <<
"Entering Rocmop::compute_medial_quadric" << std::endl;
291 const std::string att1(
"eigvecs"), att2(
"lambda"), att3(
"weights"),
292 att4(
"facenormals"), att5(
"facecenters"), att6(
"tangranks"),
293 att7(
"cntnranks"), att8(
"cntnvecs"), att9(
"vnormals"), att10(
"disps"),
294 att11(
"awnormals"), att12(
"uwnormals");
295 COM::Attribute *A_attr =
_wrk_window->attribute(att1);
296 COM::Attribute *bm_attr =
_wrk_window->attribute(att2);
297 COM::Attribute *aw_attr =
_wrk_window->attribute(att11);
298 COM::Attribute *uw_attr =
_wrk_window->attribute(att12);
299 COM::Attribute *r_attr =
_wrk_window->attribute(att3);
301 int facenormals_id =
_wrk_window->attribute(att4)->id();
302 int facecenters_id =
_wrk_window->attribute(att5)->id();
303 int tangranks_id =
_wrk_window->attribute(att6)->id();
304 int cntnranks_id =
_wrk_window->attribute(att7)->id();
305 int cntnvecs_id =
_wrk_window->attribute(att8)->id();
306 int vnormals_id =
_wrk_window->attribute(att9)->id();
307 int awnormals_id =
_wrk_window->attribute(att11)->id();
308 int uwnormals_id =
_wrk_window->attribute(att12)->id();
309 int disps_id =
_wrk_window->attribute(att10)->id();
317 std::vector< COM::Pane*> allpanes;
319 for(
int i =0, local_npanes = allpanes.size();
320 i<local_npanes; ++
i){
322 ( allpanes[
i]->attribute(disps_id)->pointer());
323 for(
int i =0,
ni = allpanes[
i]->size_of_real_nodes();
i<
ni; ++
i){
329 std::vector< COM::Pane*>::iterator it = allpanes.begin();
330 SURF::Window_manifold_2::PM_iterator pm_it=_wm->pm_begin();
331 for (
int i=0, local_npanes = allpanes.size();
332 i<local_npanes; ++
i, ++it, ++pm_it) {
333 COM::Pane *pane = *it;
337 (pane->attribute(
COM_NC)->pointer());
339 ( pane->attribute(facenormals_id)->pointer());
343 ( pane->attribute(A_attr->id())->pointer());
345 ( pane->attribute(bm_attr->id())->pointer());
347 ( pane->attribute(aw_attr->id())->pointer());
349 ( pane->attribute(uw_attr->id())->pointer());
350 double *
rs =
reinterpret_cast<double*
>
351 ( pane->attribute(r_attr->id())->pointer());
353 ( pane->attribute(facecenters_id)->pointer());
357 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.next()) {
363 int ne = ene.size_of_edges();
364 int uindex=ene[ne-1]-1, vindex=ene[0]-1;
367 for (
int k=0;
k<ne; ++
k) {
368 int windex = ene[(
k+1==ne)?0:k+1]-1;
377 pnts[windex]-pnts[vindex]};
379 double s =
std::sqrt((ts[0]*ts[0])*(ts[1]*ts[1]));
382 double cosw = ts[0]*ts[1]/
s;
383 if (cosw>1) cosw=1;
else if ( cosw<-1) cosw=-1;
413 double &r_v = rs[vindex];
416 A_v[0] += ns_nz[0]*nrm;
417 A_v[1] += ns_nz[1]*nrm;
418 A_v[2] += ns_nz[2]*nrm;
425 uindex=vindex; vindex=windex;
428 #if defined(BOUNDARY_TREATMENT) && BOUNDARY_TREATMENT
432 if ( h.is_border()) {
439 for (
int k=0;
k<2; ++
k) {
440 int vindex = ene[ (
k?h:h.next()).
id().lid()]-1;
444 double &r_v = rs[vindex];
448 A_v[0] += nrm_nz[0]*nrm;
449 A_v[1] += nrm_nz[1]*nrm;
450 A_v[2] += nrm_nz[2]*nrm;
455 }
while ( (h=h.next()) != h0);
461 _wm->reduce_on_shared_nodes( A_attr, SURF::Window_manifold_2::OP_SUM);
462 _wm->reduce_on_shared_nodes( bm_attr, SURF::Window_manifold_2::OP_SUM);
463 _wm->reduce_on_shared_nodes( aw_attr, SURF::Window_manifold_2::OP_SUM);
464 _wm->reduce_on_shared_nodes( uw_attr, SURF::Window_manifold_2::OP_SUM);
465 _wm->reduce_on_shared_nodes( r_attr, SURF::Window_manifold_2::OP_SUM);
468 it = allpanes.begin();
469 for (
int i=0, local_npanes = allpanes.size();
i<local_npanes; ++
i, ++it) {
471 COM::Pane *pane = *it;
475 ( pane->attribute(A_attr->id())->pointer());
477 ( pane->attribute(bm_attr->id())->pointer());
478 double *
rs =
reinterpret_cast<double*
>
479 ( pane->attribute(r_attr->id())->pointer());
480 int *tranks =
reinterpret_cast<int*
>
481 ( pane->attribute(tangranks_id)->pointer());
482 int *cranks =
reinterpret_cast<int*
>
483 ( pane->attribute(cntnranks_id)->pointer());
485 ( pane->attribute(cntnvecs_id)->pointer());
489 ( pane->attribute(
_cnstr_dirs->id())->pointer()):NULL;
491 ( pane->attribute(vnormals_id)->pointer());
493 ( pane->attribute(awnormals_id)->pointer());
495 ( pane->attribute(uwnormals_id)->pointer());
500 for (
int j=0, jn=pane->size_of_real_nodes();
j<jn; ++
j) {
504 if ( rs[
j]==0)
continue;
528 for (
int k=tranks[j]-1;
k>=0; --
k)
535 double tol = bs_m[
j][0]*5.e-3;
536 for (
int k=0;
k<orank; ++
k)
542 std::cout <<
"Exiting Rocmop::compute_medial_quadric" << std::endl;
550 const std::string att1(
"disps"), att2(
"lambda"), att3(
"weights"),
551 att4(
"cntnvecs"), att5(
"cntnranks");
555 COM::Attribute *c_attr =
_wrk_window->attribute(att2);
556 COM::Attribute *w_attr =
_wrk_window->attribute(att3);
557 int cntnvecs_id =
_wrk_window->attribute(att4)->id();
558 int cntnranks_id =
_wrk_window->attribute(att5)->id();
564 std::vector< COM::Pane*> allpanes;
566 std::vector< COM::Pane*>::iterator it = allpanes.begin();
568 for (
int i=0, local_npanes = allpanes.size();
569 i<local_npanes; ++
i, ++it, ++pm_it) {
570 COM::Pane *pane = *it;
573 ( pane->attribute(cntnvecs_id)->pointer());
575 (pane->attribute(
COM_NC)->pointer());
577 ( pane->attribute(c_attr->id())->pointer());
578 int *cranks =
reinterpret_cast<int*
>
579 ( pane->attribute(cntnranks_id)->pointer());
581 std::set< Edge_ID> &eset_pn =
_edges[
i];
582 for ( std::set< Edge_ID>::const_iterator eit=eset_pn.begin(),
583 eend=eset_pn.end(); eit!=eend; ++eit) {
585 bool is_border = eid.is_border();
586 if ( is_border) eid = pm_it->get_opposite_real_edge( eid);
592 int vindex=ene[eid.lid()]-1, windex=ene[(eid.lid()+1)%ne]-1;
593 if ( is_border)
std::swap( vindex, windex);
595 if ( cranks[vindex]>0) {
600 cs[vindex][0] += 0.5*(es[2*vindex]*diff_wv);
608 it = allpanes.begin(); pm_it=_wm->pm_begin();
609 for (
int i=0, local_npanes = allpanes.size();
610 i<local_npanes; ++
i, ++it, ++pm_it) {
611 COM::Pane *pane = *it;
614 ( pane->attribute(cntnvecs_id)->pointer());
616 ( pane->attribute( c_attr->id())->pointer());
617 int *cranks =
reinterpret_cast<int*
>
618 ( pane->attribute(cntnranks_id)->pointer());
621 std::set< Edge_ID> &eset_pn =
_edges[
i];
622 for ( std::set< Edge_ID>::const_iterator eit=eset_pn.begin(),
623 eend=eset_pn.end(); eit!=eend; ++eit) {
625 bool is_border = eid.is_border();
626 if ( is_border) eid = pm_it->get_opposite_real_edge( eid);
632 int vindex=ene[eid.lid()]-1, windex=ene[(eid.lid()+1)%ne]-1;
633 if ( is_border)
std::swap( vindex, windex);
635 if ( cranks[vindex]>0)
636 cs[vindex] = 0.5*cs[vindex][0]*es[2*vindex];
644 it = allpanes.begin(); pm_it=_wm->pm_begin();
645 for (
int i=0, local_npanes = allpanes.size();
646 i<local_npanes; ++
i, ++it, ++pm_it) {
647 COM::Pane *pane = *it;
650 ( pane->attribute( c_attr->id())->pointer());
652 ( pane->attribute( disps_id)->pointer());
653 double *ws =
reinterpret_cast<double*
>
654 ( pane->attribute(w_attr->id())->pointer());
657 std::set< Edge_ID> &eset_pn =
_edges[
i];
658 for ( std::set< Edge_ID>::const_iterator eit=eset_pn.begin(),
659 eend=eset_pn.end(); eit!=eend; ++eit) {
661 bool is_border = eid.is_border();
662 if ( is_border) eid = pm_it->get_opposite_real_edge( eid);
668 int vindex=ene[eid.lid()]-1, windex=ene[(eid.lid()+1)%ne]-1;
669 if ( is_border)
std::swap( vindex, windex);
672 if ( ws[vindex]>0) w =
std::min( w, 1./ws[vindex]);
674 ds[vindex] += w*cs[vindex];
686 const std::string att1(
"disps"), att2(
"lambda"), att3(
"weights"),
687 att4(
"cntnvecs"), att5(
"cntnranks"), att6(
"tangranks");
689 COM::Attribute *c_attr =
_wrk_window->attribute(att2);
690 COM::Attribute *w_attr =
_wrk_window->attribute(att3);
691 int cntnvecs_id =
_wrk_window->attribute(att4)->id();
692 int cntnranks_id =
_wrk_window->attribute(att5)->id();
693 int tangranks_id =
_wrk_window->attribute(
"tangranks")->id();
699 std::vector< COM::Pane*> allpanes;
702 std::vector< COM::Pane*>::iterator it = allpanes.begin();
703 for (
int i=0, local_npanes = allpanes.size();
i<local_npanes; ++
i, ++it) {
704 COM::Pane *pane = *it;
707 ( pane->attribute(cntnvecs_id)->pointer());
709 (pane->attribute(
COM_NC)->pointer());
711 ( pane->attribute(c_attr->id())->pointer());
712 double *ws =
reinterpret_cast<double*
>
713 ( pane->attribute(w_attr->id())->pointer());
715 ( pane->attribute(disps_id)->pointer());
716 int *tranks =
reinterpret_cast<int*
>
717 ( pane->attribute(tangranks_id)->pointer());
718 int *cranks =
reinterpret_cast<int*
>
719 ( pane->attribute(cntnranks_id)->pointer());
725 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.
next()) {
727 int uindex=ene[ne-1]-1, vindex=ene[0]-1;
730 for (
int k=0;
k<ne; ++
k) {
731 int windex = ene[(
k+1==ne)?0:k+1]-1;
734 if ( tranks[vindex]==2) {
735 std::cout <<
"cranks[vindex]-1 = " << cranks[vindex]-1 << std::endl;
737 pnts[windex]-pnts[vindex]};
744 ( diff_uv*diff_wv/
std::sqrt((diff_wv*diff_wv)*(diff_uv*diff_uv)));
745 std::cout <<
"theta = " << theta << std::endl;
748 std::cout <<
"theta 2 = " << theta << std::endl;
750 for (
int k=cranks[vindex]-1; k>=0; --
k) {
751 cs[vindex][
k] += theta*(es[2*vindex+
k]*(diff_uv+diff_wv));
760 uindex=vindex; vindex=windex;
768 it = allpanes.begin();
769 for (
int i=0, local_npanes = allpanes.size();
i<local_npanes; ++
i, ++it) {
770 COM::Pane *pane = *it;
773 ( pane->attribute( c_attr->id())->pointer());
774 double *ws =
reinterpret_cast<double*
>
775 ( pane->attribute( w_attr->id())->pointer());
776 int *tranks =
reinterpret_cast<int*
>
777 ( pane->attribute(tangranks_id)->pointer());
779 ( pane->attribute(cntnvecs_id)->pointer());
780 int *cranks =
reinterpret_cast<int*
>
781 ( pane->attribute(cntnranks_id)->pointer());
784 for (
int j=0,
nj=pane->size_of_real_nodes();
j<
nj; ++
j) {
787 for (
int k=cranks[
j]-1;
k>=0; --
k) {
788 s += (cs[
j][
k]*es[2*
j+
k])/ws[
j];
799 it = allpanes.begin();
800 for (
int i=0, local_npanes = allpanes.size();
i<local_npanes; ++
i, ++it) {
801 COM::Pane *pane = *it;
804 ( pane->attribute( c_attr->id())->pointer());
805 double *ws =
reinterpret_cast<double*
>
806 ( pane->attribute( w_attr->id())->pointer());
808 ( pane->attribute( disps_id)->pointer());
809 int *tranks =
reinterpret_cast<int*
>
810 ( pane->attribute( tangranks_id)->pointer());
813 for (
int j=0,
nj=pane->size_of_real_nodes();
j<
nj; ++
j) {
818 std::cout <<
"ds[" << j <<
"] += " << w <<
" * " << cs[
j] << std::endl;
830 const std::string att1(
"tangranks"), att2(
"weights2"),
831 att3(
"barycrds"), att4(
"PNelemids");
832 int tangranks_id =
_wrk_window->attribute(att1)->id(),
837 std::vector< COM::Pane*> allpanes;
839 std::vector< COM::Pane*>::iterator it = allpanes.begin();
840 for (
int i=0, local_npanes = allpanes.size();
i<local_npanes; ++
i, ++it) {
841 COM::Pane *pane = *it;
844 (pane->attribute(
COM_NC)->pointer());
846 ( pane->attribute(c_attr->id())->pointer());
847 double *ws =
reinterpret_cast<double*
>
848 ( pane->attribute(w_attr->id())->pointer());
849 int *tranks =
reinterpret_cast<int*
>
850 ( pane->attribute(tangranks_id)->pointer());
851 double *ws2 =
reinterpret_cast<double*
>
852 ( pane->attribute(weights2_id)->pointer());
853 double *bcs =
reinterpret_cast<double*
>
854 ( pane->attribute(barycrds_id)->pointer());
855 int *PNids =
reinterpret_cast<int*
>
856 ( pane->attribute(PNelemid_id)->pointer());
861 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.
next()) {
863 int uindex=ene[ne-1]-1, vindex=ene[0]-1;
867 for (
int k=0;
k<ne; ++
k) {
868 int windex = ene[(
k+1==ne)?0:k+1]-1;
871 if ( tranks[vindex]==rank) {
873 pnts[windex]-pnts[vindex]};
885 double temp = ws[windex];
887 if(temp != ws[windex]){
888 ws2[windex] = ws[windex];
889 bcs[windex*2]= xs[0];
890 bcs[windex*2+1] = xs[1];
895 uindex=vindex; vindex=windex;
906 std::cout <<
"Entering Rocmop::evaluate_face_normals" << std::endl;
911 std::cout <<
"Getting attribute ids" << std::endl;
913 const std::string att1(
"facenormals");
914 const std::string att2(
"facecenters");
915 int facenormals_id =
_wrk_window->attribute(att1)->id();
916 int facecenters_id =
_wrk_window->attribute(att2)->id();
919 std::vector< COM::Pane*> allpanes;
922 std::vector< COM::Pane*>::iterator it = allpanes.begin();
923 for (
int i=0, local_npanes = allpanes.size();
i<local_npanes; ++
i, ++it) {
924 COM::Pane *pane = *it;
928 pane->size_of_real_nodes()==0,
929 "Coordinates must be stored in contiguous layout.");
932 (pane->attribute(
COM_NC)->pointer());
934 ( pane->attribute(facenormals_id)->pointer());
936 ( pane->attribute(facecenters_id)->pointer());
944 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.
next()) {
953 e.Jacobian( ps, nc, J);
959 e.interpolate_to_center( ps, &cnts[
j]);
965 std::cout <<
"Exiting Rocmop::evaluate_face_normals" << std::endl;
972 COM::Attribute *maxedgev =
976 COM::Attribute *minedgev =
982 std::vector< COM::Pane*> allpanes;
984 std::vector< COM::Pane*>::iterator it = allpanes.begin();
987 const std::string att1(
"eigvecs"), att2(
"tangranks");
989 int eigvecs_id =
_wrk_window->attribute(att1)->id();
990 int tangranks_id =
_wrk_window->attribute(att2)->id();
992 std::vector<std::map<Edge_ID, double> > edge_maps( allpanes.size());
993 for (
int i=0, local_npanes = allpanes.size();
994 i<local_npanes; ++
i, ++it, ++pm_it) {
995 COM::Pane *pane = *it;
996 std::map< Edge_ID, double> &edges_pn = edge_maps[
i];
1000 ( pane->attribute(eigvecs_id)->pointer());
1001 int *tranks =
reinterpret_cast<int*
>
1002 ( pane->attribute(tangranks_id)->pointer());
1003 double *minvs =
reinterpret_cast<double*
>
1004 ( pane->attribute(minedgev->id())->pointer());
1005 double *maxvs =
reinterpret_cast<double*
>
1006 ( pane->attribute(maxedgev->id())->pointer());
1010 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.
next()) {
1013 int vindex = ene[ h.id().lid()]-1;
1015 int windex = ene[ h.next().id().lid()]-1;
1018 if ( tranks[ vindex]==1) {
1019 int m = 1 + (tranks[windex]<2);
1021 double feg = m * (es[3*vindex+2]* tng);
1023 edges_pn[ h.id()] = feg;
1024 if ( feg > maxvs[vindex]) maxvs[vindex] = feg;
1025 if ( feg < minvs[vindex]) minvs[vindex] = feg;
1029 if ( h.is_border() && tranks[windex]==1) {
1030 int m = 1 + (tranks[vindex]<2);
1032 double feg = m * (es[3*windex+2]* tng);
1034 edges_pn[ h.opposite().id()] = feg;
1035 if ( feg > maxvs[windex]) maxvs[windex] = feg;
1036 if ( feg < minvs[windex]) minvs[windex] = feg;
1041 }
while ( (h=h.next()) != h0);
1049 it = allpanes.begin();
1052 for (
int i=0, local_npanes = allpanes.size();
i<local_npanes; ++
i, ++it) {
1053 COM::Pane *pane = *it;
1054 std::map< Edge_ID, double> &emap_pn = edge_maps[
i];
1055 std::set< Edge_ID> &eset_pn =
_edges[
i];
1057 const double *minvs =
reinterpret_cast<double*
>
1058 ( pane->attribute(minedgev->id())->pointer());
1059 const double *maxvs =
reinterpret_cast<double*
>
1060 ( pane->attribute(maxedgev->id())->pointer());
1063 for ( std::map< Edge_ID, double>::const_iterator eit=emap_pn.begin(),
1064 eend=emap_pn.end(); eit!=eend; ++eit) {
1066 int vindex = ene[eit->first.lid()]-1;
1069 if ( eit->second == minvs[vindex] || eit->second == maxvs[vindex])
1070 eset_pn.insert( eit->first);
1096 double eps = lambdas[0]*1.e-8;
1097 double gs[] = { b*es[0]/lambdas[0],
1099 b*es[2]/
std::max(eps,lambdas[2]) };
1104 std::max(lambdas[0]-lambdas[1], lambdas[1]-lambdas[2]) || ad >= .5*
pi)
1106 else if ( gs_abs[1] >= gs_abs[0] || lambdas[0]*
_dir_thres<lambdas[1]) {
1109 std::cerr <<
"Rocprop Warning: Mesh contains near cusp."
1110 <<
"lambdas[1]=" << lambdas[1] <<
" and lambdas[0]="
1111 << lambdas[0] << std::endl;
1115 if ( gs_abs[1] < gs_abs[0]) {
1117 if ( theta<fangle_min_eigen) fangle_min_eigen=theta;
1118 if ( theta>fangle_max_eigen) fangle_max_eigen=theta;
1126 *nrm_nz=( es[0]*b>0)?-es[0]:es[0];
1130 for (
int k=0;
k<nrank; ++
k) x -= gs[
k]*es[
k];
1154 double eps = lambdas[0]*1.e-8;
1155 double gs[] = { b*es[0]/lambdas[0],
1157 b*es[2]/
std::max(eps,lambdas[2]) };
1162 std::max(lambdas[0]-lambdas[1], lambdas[1]-lambdas[2]) ||
1163 gs_abs[2]>=gs_abs[1] && gs_abs[2] >= gs_abs[0])
1165 else if ( gs_abs[1] >= gs_abs[0] || lambdas[0]*
_dir_thres<lambdas[1]) {
1168 std::cerr <<
"Rocmop Warning: Mesh contains near cusp." << std::endl;
1176 *nrm_nz=( es[0]*b>0)?-es[0]:es[0];
1180 for (
int k=0;
k<orank; ++
k)
x -= gs[
k]*es[
k];
1181 *nrm_nz =
x.normalize();
1193 double abuf[3][3] = { {A[0][0], A[0][1], A[0][2]},
1194 {A[1][0], A[1][1], A[1][2]},
1195 {A[2][0], A[2][1], A[2][2]}};
1207 if ( lambdas[0]<lambdas[1]) {
1208 if ( lambdas[1]<lambdas[2]) {
1210 A[0] = buf[2]; A[1] = buf[1]; A[2] = buf[0];
1213 double t = lambdas[0];
1214 lambdas[0] = lambdas[1];
1217 if ( t<lambdas[2]) {
1218 lambdas[1] = lambdas[2]; lambdas[2] = t;
1219 A[1] = buf[2]; A[2] = buf[0];
1223 A[1] = buf[0]; A[2] = buf[2];
1227 else if ( lambdas[0]<lambdas[2]) {
1228 double t = lambdas[0];
1229 lambdas[0] = lambdas[2]; lambdas[2] = lambdas[1]; lambdas[1] = t;
1230 A[0] = buf[2]; A[1] = buf[0]; A[2] = buf[1];
1234 if ( lambdas[1]<lambdas[2]) {
1236 A[1] = buf[2]; A[2] = buf[1];
1239 A[1] = buf[1]; A[2] = buf[2];
1247 if ( type == 1 || type == -1)
1249 "Constrained direction must be normalized");
1259 ndirs = 1; dirs[0] = dir;
1266 sqnrm = dir[1]*dir[1]+dir[2]*dir[2];
1271 sqnrm = dir[0]*dir[0]+dir[1]*dir[1];
1277 dirs[0] *=
s; dirs[1] *=
s;
int eigen_analyze_vertex(Vector_3< double > A_io[3], Vector_3< double > &b_io, Vector_3< double > *nrm_nz, double angle_defect)
void swap(int &a, int &b)
subroutine rs(nm, n, a, w, matz, z, fv1, fv2, ierr)
An adaptor for enumerating node IDs of an element.
const COM::Window * _usr_window
The user's window.
Contains the prototypes for the Pane object.
char _wght_scheme
Weighting scheme.
#define COM_assertion_msg(EX, msg)
void identify_ridge_edges()
Identify ridge edges.
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
This file contains the prototypes for Roccom API.
This class encapsulate a halfedge over a window manifold.
bool _reorthog
Reorthogonalize?
double _eig_thres
Eigenvalue thresholds.
void compute_medial_quadric()
Compute medial quadric for every vertex.
static void compute_eigenvectors(Vector_3< double > A[3], Vector_3< double > &lambdas)
std::vector< Pane_manifold_2 >::iterator PM_iterator
This is a helper class for accessing nodal data.
void evaluate_face_normals()
Evaluate face normals (copied from FaceOffset_3.[hC].
void redistribute_vertices_smooth()
Redistribute smooth vertices within their tangent spaces.
static void get_constraint_directions(int type, const Vector_3< double > &dir, int &ndirs, Vector_3< double > dirs[2])
Get orthonormals of the constraints.
int size_of_edges() const
Number of edges per element.
double angle(Vector_3< double > v1, Vector_3< double > v2)
Compute the angle between two vectors.
void get_redist_safe_factor(COM::Attribute *c_attr, COM::Attribute *w_attr, int rank)
int _rediter
No.iterations for vertex redistribution.
COM::Window * _wrk_window
The working window.
int size_of_nodes() const
Number of nodes per element.
Type squared_norm() const
#define MOP_END_NAMESPACE
static Vector_3 cross_product(const Vector_3 &v, const Vector_3 &w)
CImg< _cimg_Tfloat > atan(const CImg< T > &instance)
void redistribute_vertices_ridge()
Redistribute ridge vertices within their tangent spaces.
Definition for Rocblas API.
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
void smooth_surf_medial()
Smooths a surface using the medial quadric.
double _dir_thres
Another threshold.
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer).
static void solve(const FT &a1, const FT &a2, const FT &b1, const FT &b2, const FT &c1, const FT &c2, FT &x, FT &y)
COM::Attribute * _cnstr_dirs
Stores directions of nodal contraints.
const COM::Attribute * _cnstr_types
Stores types of nodal constraints.
#define MOP_BEGIN_NAMESPACE
void set(const Value *p, Element_node_enumerator &ene, int strd)
initialize the accessor with a pointer and a specific stride.
static void copy(const Attribute *x, Attribute *y)
Wrapper for copy.
CImg< _cimg_Tfloat > acos(const CImg< T > &instance)
void next()
Go to the next element within the connectivity tables of a pane.
void int int REAL REAL REAL *z blockDim dim * ni
Geometric helper function header file.
void info()
Print informations about CImg environement variables.
std::vector< std::set< Edge_ID > > _edges
ridge edges