26 #include "../Rocblas/include/Rocblas.h"
27 #include "../Rocsurf/include/Rocsurf.h"
38 COM::Attribute *maxdianglev =
40 _buf->resize_array( maxdianglev, 0);
45 COM::Attribute *mindianglev =
47 _buf->resize_array( mindianglev, 0);
51 COM::Attribute *maxtrnangv =
53 _buf->resize_array( maxtrnangv, 0);
58 COM::Attribute *mintrnangv =
60 _buf->resize_array( mintrnangv, 0);
64 COM::Attribute *neighbor_features =
65 _buf->new_attribute(
"FO_neighbor_features",
'n',
COM_CHAR, 1,
"");
66 _buf->resize_array( neighbor_features, 0);
68 COM::Attribute *qsedges =
69 _buf->new_attribute(
"FO_qsedges",
'e',
COM_CHAR, 1,
"");
70 _buf->resize_array( qsedges, 0);
71 _buf->init_done(
false);
82 std::vector< COM::Pane*>::iterator it =
_panes.begin();
83 Manifold::PM_iterator pm_it=
_surf->pm_begin();
85 int nedges=0, nvertices=0;
86 std::vector<std::map<Edge_ID, double> > edge_maps(
_panes.size());
87 std::vector<std::map<Edge_ID, double> > diangle_maps(
_panes.size());
89 for (
int i=0, local_npanes =
_panes.size();
90 i<local_npanes; ++
i, ++it, ++pm_it) {
91 COM::Pane *pane = *it;
92 std::map< Edge_ID, double> &emap_pn = edge_maps[
i];
93 std::map< Edge_ID, double> &diangle_pn = diangle_maps[
i];
95 nvertices += pane->size_of_real_nodes();
99 (pane->attribute(
COM_NC)->pointer());
102 ( pane->attribute(
_eigvecs->id())->pointer());
103 char *tranks =
reinterpret_cast<char*
>
104 ( pane->attribute(
_tangranks->id())->pointer());
105 char *strong =
reinterpret_cast<char*
>
106 ( pane->attribute(
_strong->id())->pointer());
107 double *minvs =
reinterpret_cast<double*
>
108 ( pane->attribute(mindianglev->id())->pointer());
109 double *maxvs =
reinterpret_cast<double*
>
110 ( pane->attribute(maxdianglev->id())->pointer());
111 double *minta =
reinterpret_cast<double*
>
112 ( pane->attribute(mintrnangv->id())->pointer());
113 double *maxta =
reinterpret_cast<double*
>
114 ( pane->attribute(maxtrnangv->id())->pointer());
120 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.
next()) {
121 int ne=ene.
size_of_edges(), uindex=ene[ne-1]-1, vindex=ene[0]-1, windex=0;
124 for (
int k=0;
k<ne; ++
k, uindex=vindex, vindex=windex) {
125 windex = ene[ (
k+1)%ne]-1;
127 Edge_ID eid(
j+1,
k), eid_opp = pm_it->get_opposite_real_edge( eid);
130 if ( pm_it->is_physical_border_edge( eid_opp))
131 { ++nedges;
continue; }
133 Vector_3 tng = pnts[ windex] - pnts[vindex];
135 double feg = es[3*vindex+2]* tng;
141 const Vector_3 &n2 = eid_opp.is_border() ?
142 pm_it->get_bd_normal( eid_opp) : fnrms[eid_opp.eid()-1];
143 double costheta = n1*n2;
144 if ( costheta>1) costheta = 1;
145 else if (costheta<-1) costheta = -1;
150 if ( tranks[vindex]==2) tranks[vindex] = 1;
151 if ( tranks[windex]==2) tranks[windex] = 1;
153 if ( fangle>
pi*0.505 && fangle !=
pi)
154 strong[vindex] = strong[windex] = 2;
156 strong[vindex] = strong[windex] = 1;
158 std::map< Edge_ID, double>::iterator rit = diangle_pn.find(eid);
160 if ( rit == diangle_pn.end()) diangle_pn[eid] = fangle;
161 else fangle = rit->second;
164 if ( fangle > maxvs[vindex]) maxvs[vindex] = fangle;
165 if ( feg > maxta[vindex]) maxta[vindex] = feg;
169 if ( -fangle<minvs[vindex]) minvs[vindex] = -fangle;
170 if ( feg < minta[vindex]) minta[vindex] = feg;
177 if ( fangle > maxvs[vindex]) maxvs[vindex] = fangle;
178 if ( feg > maxta[vindex]) maxta[vindex] = feg;
181 if ( -fangle < minvs[vindex]) minvs[vindex] = -fangle;
182 if ( feg < minta[vindex]) minta[vindex] = feg;
186 diangle_pn[eid] = fangle; emap_pn[ eid] = feg;
193 std::cout <<
"There are " << nedges/2 <<
" edges and "
194 << nvertices <<
" vertices " << std::endl;
197 _surf->reduce_on_shared_nodes( mindianglev, Manifold::OP_MIN);
198 _surf->reduce_on_shared_nodes( maxdianglev, Manifold::OP_MAX);
200 _surf->reduce_on_shared_nodes( mintrnangv, Manifold::OP_MIN);
201 _surf->reduce_on_shared_nodes( maxtrnangv, Manifold::OP_MAX);
202 _surf->reduce_on_shared_nodes(
_strong, Manifold::OP_MAX);
206 pm_it=
_surf->pm_begin();
209 for (
int i=0, local_npanes =
_panes.size();
i<local_npanes;
210 ++
i, ++it, ++pm_it) {
211 COM::Pane *pane = *it;
212 std::map< Edge_ID, double> &emap_pn = edge_maps[
i];
213 std::map< Edge_ID, double> &diangle_pn = diangle_maps[
i];
215 const double *minvs =
reinterpret_cast<double*
>
216 ( pane->attribute(mindianglev->id())->pointer());
217 const double *maxvs =
reinterpret_cast<double*
>
218 ( pane->attribute(maxdianglev->id())->pointer());
219 const double *minta =
reinterpret_cast<double*
>
220 ( pane->attribute(mintrnangv->id())->pointer());
221 double *maxta =
reinterpret_cast<double*
>
222 ( pane->attribute(maxtrnangv->id())->pointer());
224 char *tranks =
reinterpret_cast<char*
>
225 ( pane->attribute(
_tangranks->id())->pointer());
226 char *nnf =
reinterpret_cast<char*
>
227 ( pane->attribute(neighbor_features->id())->pointer());
231 for ( std::map< Edge_ID, double>::iterator eit=emap_pn.begin(),
232 rit=diangle_pn.begin(), eend=emap_pn.end(); eit!=eend; ++eit, ++rit) {
234 double feg = eit->second, fangle = rit->second;
238 int vi = eid.lid(), vindex = ene[vi]-1;
241 if ( !tranks[vindex] || tranks[vindex] ==
char(-1) || fangle >
_tol_angle_strong ||
242 ( feg < 0 && fangle == -minvs[vindex] ||
243 feg > 0 && fangle == maxvs[vindex]) &&
251 _surf->reduce_on_shared_nodes( neighbor_features, Manifold::OP_SUM);
254 pm_it=
_surf->pm_begin();
256 for (
int i=0, local_npanes =
_panes.size();
i<local_npanes;
257 ++
i, ++it, ++pm_it) {
258 COM::Pane *pane = *it;
259 std::map< Edge_ID, double> &emap_pn = edge_maps[
i];
260 std::map< Edge_ID, double> &diangle_pn = diangle_maps[
i];
261 std::set< Edge_ID> &eset_pn =
_edges[
i];
263 const double *minvs =
reinterpret_cast<double*
>
264 ( pane->attribute(mindianglev->id())->pointer());
265 const double *maxvs =
reinterpret_cast<double*
>
266 ( pane->attribute(maxdianglev->id())->pointer());
267 const double *minta =
reinterpret_cast<double*
>
268 ( pane->attribute(mintrnangv->id())->pointer());
269 double *maxta =
reinterpret_cast<double*
>
270 ( pane->attribute(maxtrnangv->id())->pointer());
272 char *strong =
reinterpret_cast<char*
>
273 ( pane->attribute(
_strong->id())->pointer());
274 char *tranks =
reinterpret_cast<char*
>
275 ( pane->attribute(
_tangranks->id())->pointer());
276 char *qses =
reinterpret_cast<char*
>
277 ( pane->attribute(qsedges->id())->pointer());
278 char *nnf =
reinterpret_cast<char*
>
279 ( pane->attribute(neighbor_features->id())->pointer());
283 for ( std::map< Edge_ID, double>::const_iterator eit=emap_pn.begin(),
284 rit=diangle_pn.begin(), eend=emap_pn.end(); eit!=eend; ++eit, ++rit) {
285 Edge_ID eid = eit->first, eid_opp = pm_it->get_opposite_real_edge( eid);
287 double feg = eit->second, fangle = rit->second, feg_opp;
291 int vindex = ene[vi]-1, windex = ene[ (vi+1)%ne]-1;
293 if ( (nnf[vindex] && nnf[windex]) &&
294 ( strong[vindex] || !tranks[vindex] || tranks[vindex] == char(-1) ||
295 feg < 0 && fangle == -minvs[vindex] ||
296 feg > 0 && fangle == maxvs[vindex] ||
299 nnf[vindex]==2 && nnf[windex]==2 &&
300 ( (feg_opp=emap_pn.find( eid_opp)->second)< 0 &&
301 fangle == -minvs[windex] ||
302 feg_opp > 0 && fangle == maxvs[windex]) &&
305 eset_pn.insert( eid);
306 qses[ eid.eid()-1] |= (1<<eid.lid());
312 _surf->update_bdedge_bitmap( qsedges);
316 pm_it=
_surf->pm_begin();
318 for (
int i=0, local_npanes =
_panes.size();
i<local_npanes;
319 ++
i, ++it, ++pm_it) {
320 std::set< Edge_ID> &eset_pn =
_edges[
i];
323 for ( std::set< Edge_ID>::iterator eit=eset_pn.begin();
324 eit!=eset_pn.end();) {
325 Edge_ID eid = *eit, eid_opp = pm_it->get_opposite_real_edge( eid);
327 if ( !eid_opp.is_border() && eset_pn.find(eid_opp)==eset_pn.end() ||
328 eid_opp.is_border() && !pm_it->get_bdedge_flag( eid_opp)) {
329 std::set< Edge_ID>::iterator to_delete = eit;
331 eset_pn.erase( to_delete);
344 if ( to_filter)
for ( ;;) {
345 std::vector< ObscendSet > obscends;
348 maxdianglev,mindianglev,
349 diangle_maps, obscends);
350 if ( nobscended==0)
break;
353 if ( !dropped)
break;
369 pm_it=
_surf->pm_begin();
370 for (
int i=0, local_npanes =
_panes.size();
371 i<local_npanes; ++
i, ++it, ++pm_it) {
372 COM::Pane *pane = *it;
373 std::set< Edge_ID> &eset_pn =
_edges[
i];
376 COM::Attribute *att_rdg = pane->attribute(
_ridges->id());
378 int n=eset_pn.size();
379 att_rdg->allocate( 2,
std::max(n,att_rdg->size_of_items()), 0);
380 int *rdgs =
reinterpret_cast<int*
>
381 ( pane->attribute(
_ridges->id())->pointer()), ii=0;
383 for ( std::set< Edge_ID>::const_iterator eit=eset_pn.begin();
384 eit!=eset_pn.end(); ++eit) {
386 Edge_ID eid = *eit, eid_opp = pm_it->get_opposite_real_edge( eid);
390 int vindex = eid.lid(), neighbor = (vindex+1)%ene.
size_of_edges();
391 vindex = ene[vindex]; neighbor=ene[neighbor];
393 if ( vindex<neighbor || eid_opp.is_border())
394 { rdgs[ii++] = vindex; rdgs[ii++] = neighbor; }
397 att_rdg->set_size( ii/2);
398 nredges += att_rdg->size_of_items();
402 std::cout <<
"Found " << nredges <<
" ridge edges " << std::endl;
405 _buf->delete_attribute( qsedges->name());
406 _buf->delete_attribute( neighbor_features->name());
407 _buf->delete_attribute( mintrnangv->name());
408 _buf->delete_attribute( maxtrnangv->name());
409 _buf->delete_attribute( mindianglev->name());
410 _buf->delete_attribute( maxdianglev->name());
411 _buf->init_done(
false);
417 Manifold::PM_iterator pm_it=
_surf->pm_begin();
421 for (
int i=0; it!=
iend; ++
i, ++it, ++pm_it) {
422 COM::Pane *pane = *it;
423 std::set< Edge_ID> &eset_pn =
_edges[
i];
425 char *tranks =
reinterpret_cast<char*
>
426 ( pane->attribute(tr_attr->id())->pointer());
427 const char *val_bndry=(
const char*)pane->attribute
432 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.
next()) {
434 Edge_ID eid(
j+1,
k), eid_opp = pm_it->get_opposite_real_edge( eid);
438 if ( pm_it->is_physical_border_edge( eid_opp) ||
439 (val_bndry && (val_bndry[
j] & (1<<
k)))) {
440 int vindex = ene[
k]-1;
442 if (tranks[ vindex]==2 || eset_pn.find(eid)==eset_pn.end()) {
443 if ( tranks[ vindex]==1) tranks[ vindex] = 0;
444 eset_pn.insert(eid); ++inserted;
451 int inserted_total = inserted;
453 MPI_Allreduce( &inserted, &inserted_total, 1, MPI_INT,
MPI_SUM,
454 _buf->get_communicator());
457 return inserted_total;
462 const bool upgrade_ridge,
463 COM::Attribute *neighbor_feas,
464 COM::Attribute *tr_attr,
467 COM::Attribute *vecsums_buf = NULL;
468 if ( upgrade_corners) {
469 vecsums_buf =
_buf->new_attribute(
"FO_vecsums_buf",
'n',
COM_DOUBLE, 3,
"");
470 _buf->resize_array( vecsums_buf, 0);
478 std::vector< COM::Pane*>::iterator it =
_panes.begin();
479 Manifold::PM_iterator pm_it=
_surf->pm_begin();
480 for (
int ii=0, local_npanes =
_panes.size();
481 ii<local_npanes; ++ii, ++it, ++pm_it) {
482 COM::Pane *pane = *it;
483 char *nnf =
reinterpret_cast<char*
>
484 ( pane->attribute(neighbor_feas->id())->pointer());
485 if ( upgrade_corners) {
487 (pane->attribute(
COM_NC)->pointer());
489 (pane->attribute(vecsums_buf->id())->pointer());
492 std::set< Edge_ID> &eset_pn =
_edges[ii];
493 for ( std::set< Edge_ID>::const_iterator eit=eset_pn.begin(),
494 eend = eset_pn.end(); eit!=eend; ++eit) {
497 int lid = eid.lid(), vindex = ene[lid]-1;
500 Edge_ID eid_opp = pm_it->get_opposite_real_edge( eid);
501 bool is_border_edge = pm_it->is_physical_border_edge( eid_opp);
503 ++nnf[ ene[(lid+1)%ene.size_of_edges()]-1];
505 if ( upgrade_corners) {
506 int windex = ene[(lid+1)%ene.size_of_edges()]-1;
507 Vector_3 diff = pnts[ windex] - pnts[vindex];
510 if ( is_border_edge) vss[windex] -= diff;
514 _surf->reduce_on_shared_nodes( neighbor_feas, Manifold::OP_SUM);
516 if ( upgrade_corners)
517 _surf->reduce_on_shared_nodes( vecsums_buf, Manifold::OP_SUM);
524 for (
int ii=0, local_npanes =
_panes.size(); ii<local_npanes; ++ii, ++it) {
525 COM::Pane *pane = *it;
526 char *nnf =
reinterpret_cast<char*
>
527 ( pane->attribute(neighbor_feas->id())->pointer());
528 char *tranks =
reinterpret_cast<char*
>
529 ( pane->attribute(tr_attr->id())->pointer());
530 if ( upgrade_corners)
532 (pane->attribute(vecsums_buf->id())->pointer());
534 for (
int j=0,
nj=pane->size_of_real_nodes();
j<
nj; ++
j) {
535 if ( upgrade_corners && ( nnf[
j]>=3 || nnf[
j] == 2 &&
536 vss[
j].squared_norm() >= tol_sqsin))
538 else if ( nnf[
j] == 0 &&
std::abs(tranks[
j]) == 1)
540 else if ( upgrade_ridge && tranks[j] == 2 && nnf[j] >= 2 ||
541 upgrade_corners && tranks[j] == -1)
549 _surf->reduce_on_shared_nodes( tr_attr, Manifold::OP_MIN);
551 if ( upgrade_corners) {
552 _buf->delete_attribute( vecsums_buf->name());
553 _buf->init_done(
false);
556 std::cout <<
"Found " << ncrns <<
" corner vertices" << std::endl;
571 const COM::Attribute *mintrnangv,
572 const std::vector<std::map<Edge_ID, double> > &edge_maps,
573 const COM::Attribute *maxdianglev,
574 const COM::Attribute *mindianglev,
575 const std::vector<std::map<Edge_ID, double> > &diangle_maps,
576 std::vector< ObscendSet > &obscends) {
581 Manifold::PM_iterator pm_it=
_surf->pm_begin();
582 COM::Pane *pane =
_panes[0];
585 typedef std::map< int, std::list< RidgeNeighbor> > ACH_Lists;
588 const std::set< Edge_ID> &eset_pn =
_edges[0];
589 for ( std::set< Edge_ID>::const_iterator eit=eset_pn.begin(),
590 eend=eset_pn.end(); eit!=eend; ++eit) {
592 Edge_ID eid = *eit, eid_opp = pm_it->get_opposite_real_edge( eid);
599 int vid = ene[lid], neighbor_id=ene[neighbor];
606 obscends.clear(); obscends.resize(
_panes.size());
612 (pane->attribute(
COM_NC)->pointer());
613 const char *tranks =
reinterpret_cast<char*
>
614 ( pane->attribute(
_tangranks->id())->pointer());
615 const double *minvs =
reinterpret_cast<double*
>
616 ( pane->attribute(mindianglev->id())->pointer());
617 const double *maxvs =
reinterpret_cast<double*
>
618 ( pane->attribute(maxdianglev->id())->pointer());
619 const double *minta =
reinterpret_cast<double*
>
620 (pane->attribute(mintrnangv->id())->pointer());
621 const double *maxta =
reinterpret_cast<double*
>
622 ( pane->attribute(maxtrnangv->id())->pointer());
623 char *strong =
reinterpret_cast<char*
>
624 ( pane->attribute(
_strong->id())->pointer());
625 const std::map< Edge_ID, double> &diangle_pn = diangle_maps[0];
626 const std::map< Edge_ID, double> &emap_pn = edge_maps[0];
629 for ( ACH_Lists::iterator ach_it = ach.begin(); ach_it!=ach.end(); ++ach_it) {
631 int vid= ach_it->first, index = (vid-1)*2;
632 int nedges = ach_it->second.size();
633 std::list< RidgeNeighbor>::iterator ait = ach_it->second.begin();
637 for (; ait!=ach_it->second.end(); ) {
640 double fangle = diangle_pn.find( eid)->second;
641 double feg = emap_pn.find( eid)->second;
645 ( strong[vid-1] || tranks[vid-1]==1 &&
648 ( feg<0 || fangle != maxvs[vid-1]) &&
649 ( feg>0 || fangle != -minvs[vid-1]))) ||
651 ( strong[vid-1]==2 || tranks[vid-1]==1 &&
653 feg != minta[vid-1] && feg != maxta[vid-1]) &&
654 ( feg<0 || fangle != maxvs[vid-1]) &&
655 ( feg>0 || fangle != -minvs[vid-1]))) {
656 obscend_pn[ ait->eid] = std::make_pair( vid, ait->vid);
657 ait = ach_it->second.erase( ait);
663 rdgngbs[index].
vid = 0; rdgngbs[index+1].
vid = -1;
667 ait = ach_it->second.begin();
670 rdgngbs[index] = *ait; rdgngbs[index+1].
vid=0;
672 double fangle = diangle_pn.find( eid)->second;
675 obscend_pn[ eid] = std::make_pair( ach_it->first, ait->vid);
677 else if ( nedges == 2) {
678 std::list< RidgeNeighbor>::iterator ait2 = ait; ++ait2;
679 int v1 = ait->vid, v2 = ait2->vid;
680 double fangle1 = diangle_pn.find( ait->eid)->second;
681 double fangle2 = diangle_pn.find( ait2->eid)->second;
685 ( pnts[v1-1]-pnts[vid-1], pnts[vid-1]-pnts[v2-1]) >
_tol_turn_angle)) {
687 obscend_pn[ ait->eid] = std::make_pair( vid, v1);
688 obscend_pn[ ait2->eid] = std::make_pair( vid, v2);
690 else if (!rdgngbs[index+1].vid)
691 { rdgngbs[index] = *ait; rdgngbs[index+1] = *ait2; }
695 int n_obscended = obscends[0].size();
696 std::cerr <<
"There are " << n_obscended
697 <<
" obscure-ended edges" << std::endl;
703 const std::vector<std::map<Edge_ID, double> > &diangle_maps,
704 const std::vector< ObscendSet > &obscends) {
706 std::vector< COM::Pane*>::iterator it =
_panes.begin();
707 Manifold::PM_iterator pm_it=
_surf->pm_begin();
708 int local_npanes =
_panes.size();
709 std::vector< ObscendSet > todelete(local_npanes);
711 for (
int i=0;
i<local_npanes; ++
i, ++it, ++pm_it) {
714 if ( obscend_pn.empty())
continue;
716 COM::Pane *pane = *it;
717 const char *tranks =
reinterpret_cast<char*
>
718 ( pane->attribute(
_tangranks->id())->pointer());
719 char *strong =
reinterpret_cast<char*
>
720 ( pane->attribute(
_strong->id())->pointer());
723 const std::map< Edge_ID, double> &diangle_pn = diangle_maps[
i];
725 for ( ObscendSet::const_iterator rit=obscend_pn.begin(),
726 rend=obscend_pn.end(); rit!=rend; ++rit) {
728 int cur=rit->second.first, next=rit->second.second, start=cur;
731 bool is_dangling = ( rdgngbs[ (cur-1)*2].vid==next &&
732 !rdgngbs[ (cur-1)*2+1].
vid ||
733 !rdgngbs[ (cur-1)*2].vid &&
734 !rdgngbs[ (cur-1)*2+1].
vid);
735 bool is_not_joint1 = ( rdgngbs[ (cur-1)*2].vid!=next &&
736 rdgngbs[ (cur-1)*2+1].
vid!=next), is_not_joint2=
false;
738 if ( !is_dangling && !is_not_joint1)
continue;
739 bool is_corner=
false, is_strong1=strong[cur-1] || !tranks[cur-1];
740 bool is_strong2=strong[next-1] || !tranks[next-1];
743 for ( ;!(is_corner = !tranks[next-1]) && next && next!=start; ) {
744 count_ks += diangle_pn.find( eid)->second>
_tol_kangle;
746 int index = (next-1)*2;
747 if ( rdgngbs[ index].vid == cur) {
748 cur = next; next = rdgngbs[index+1].
vid; eid = rdgngbs[index+1].
eid;
749 is_strong2=strong[next-1] || !tranks[next-1];
750 is_not_joint2 =
false;
753 Edge_ID eid_opp = pm_it->get_opposite_real_edge( eid);
755 is_not_joint2 = (rdgngbs[ index+1].
vid!=cur) &&
756 (obscend_pn.find(eid_opp) != obscend_pn.end());
758 if ( rdgngbs[ index+1].vid == cur) {
759 cur = next; next = rdgngbs[index].
vid; eid = rdgngbs[ index].
eid;
760 is_strong2=strong[next-1] || !tranks[next-1];
763 { cur = next; next = 0; }
768 if ( (is_dangling || is_not_joint1 && is_not_joint2) && count_ks<=
_tol_kstrong ||
769 is_strong1 && is_strong2 && count_ks==0) {
770 todelete_pn.insert( *rit);
782 Manifold::PM_iterator pm_it=
_surf->pm_begin();
786 for (
int i=0, local_npanes =
_panes.size();
787 i<local_npanes; ++
i, ++pm_it) {
788 std::set< Edge_ID> &eset_pn =
_edges[
i];
792 char *tranks =
reinterpret_cast<char*
>
793 ( pane->attribute(
_tangranks->id())->pointer());
797 std::cout <<
"There are " << obscend_pn.size()
798 <<
" obscure curves. " << std::endl;
800 for ( ObscendSet::const_iterator rit=obscend_pn.begin(),
801 rend=obscend_pn.end(); rit!=rend; ++rit) {
802 dropped += eset_pn.erase( rit->first);
803 eset_pn.erase( pm_it->get_opposite_real_edge( rit->first));
805 int cur = rit->second.first, next = rit->second.second, start=cur;
806 for ( ; tranks[next-1]; ) {
807 int index = (next-1)*2;
810 if ( rdgngbs[ index].vid == cur)
811 { cur = next; next = rdgngbs[index+1].
vid; eid = rdgngbs[ index+1].
eid; }
812 else if ( rdgngbs[ index+1].vid == cur)
813 { cur = next; next = rdgngbs[index].
vid; eid = rdgngbs[ index].
eid; }
815 { cur = next; next = 0; }
816 if ( next==0 || next==start)
break;
818 dropped += eset_pn.erase( eid);
819 eset_pn.erase( pm_it->get_opposite_real_edge( eid));
825 std::cerr <<
"Dropped " << dropped <<
" false candidate edges. " << std::endl;
COM::Attribute * _ridgeneighbors
int insert_boundary_edges(COM::Attribute *tr_attr)
#define COM_assertion(EX)
Error checking utility similar to the assert macro of the C language.
An adaptor for enumerating node IDs of an element.
#define PROP_END_NAMESPACE
void filter_and_identify_ridge_edges(bool filter_curves)
Filter out isolated ridge vertices and identify ridge edges.
#define PROP_BEGIN_NAMESPACE
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
COM::Attribute * _tangranks
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
std::vector< COM::Pane * > _panes
COM::Attribute * _eigvecs
RidgeNeighbor(int v, Edge_ID e)
**********************************************************************Rocstar Simulation Suite Illinois Rocstar LLC All rights reserved ****Illinois Rocstar LLC IL **www illinoisrocstar com **sales illinoisrocstar com WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **Arising OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE **********************************************************************INTERFACE SUBROUTINE knode iend
int size_of_edges() const
Number of edges per element.
void reclassify_ridge_vertices(const bool upgrade_corners, const bool upgrade_ridge, COM::Attribute *neighbor_feas, COM::Attribute *tr_attr, bool to_filter)
std::map< Edge_ID, std::pair< int, int > > ObscendSet
int build_ridge_neighbor_list(const COM::Attribute *maxtrnangv, const COM::Attribute *mintrnangv, const std::vector< std::map< Edge_ID, double > > &edge_maps, const COM::Attribute *maxranglev, const COM::Attribute *minranglev, const std::vector< std::map< Edge_ID, double > > &rangle_maps, std::vector< ObscendSet > &obscends)
Build the list of ridge nighbors and obtain a list of weak-ended vertices Return the number of obscen...
static double eval_angle(const Vector_3 &v1, const Vector_3 &v2)
COM::Attribute * _cnstr_bndry_edges
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer).
std::vector< std::set< Edge_ID > > _edges
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.
Some basic geometric data types.
int remove_obscure_curves(const std::vector< ObscendSet > &obscends)
bool filter_obscended_ridge(const std::vector< std::map< Edge_ID, double > > &edge_maps, const std::vector< std::map< Edge_ID, double > > &diangl_maps, const std::vector< ObscendSet > &obscends)
Filter out weak-ended curves.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_SUM
COM::Attribute * _facenormals
COM::Attribute * _ctangranks