bool Surface_mesh:: is_collapse_ok(Halfedge v0v1) { Halfedge v1v0(opposite_halfedge(v0v1)); Vertex v0(to_vertex(v1v0)); Vertex v1(to_vertex(v0v1)); Vertex vv, vl, vr; Halfedge h1, h2; // the edges v1-vl and vl-v0 must not be both boundary edges if (!is_boundary(v0v1)) { vl = to_vertex(next_halfedge(v0v1)); h1 = next_halfedge(v0v1); h2 = next_halfedge(h1); if (is_boundary(opposite_halfedge(h1)) && is_boundary(opposite_halfedge(h2))) return false; } // the edges v0-vr and vr-v1 must not be both boundary edges if (!is_boundary(v1v0)) { vr = to_vertex(next_halfedge(v1v0)); h1 = next_halfedge(v1v0); h2 = next_halfedge(h1); if (is_boundary(opposite_halfedge(h1)) && is_boundary(opposite_halfedge(h2))) return false; } // if vl and vr are equal or both invalid -> fail if (vl == vr) return false; // edge between two boundary vertices should be a boundary edge if ( is_boundary(v0) && is_boundary(v1) && !is_boundary(v0v1) && !is_boundary(v1v0)) return false; // test intersection of the one-rings of v0 and v1 Vertex_around_vertex_circulator vv_it, vv_end; vv_it = vv_end = vertices(v0); do { vv = vv_it; if (vv != v1 && vv != vl && vv != vr) if (find_halfedge(vv, v1).is_valid()) return false; } while (++vv_it != vv_end); // passed all tests return true; }
static void close_mime(struct mimestack **stack, int *iseof, FILE *fpin, FILE *fpout) { char buf[BUFSIZ]; int is_closing; struct mimestack *b; for (;;) { if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; break; } fprintf(fpout, "%s", buf); if (!(b=is_boundary(*stack, buf, &is_closing))) continue; if (!is_closing) continue; pop_mimestack_to(stack, b); break; } }
static void find_boundary(struct mimestack **stack, int *iseof, FILE *fpin, FILE *fpout, int doappend) { char buf[BUFSIZ]; for (;;) { int is_closing; struct mimestack *b; if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; return; } if (!(b=is_boundary(*stack, buf, &is_closing))) { if (fpout) fprintf(fpout, "%s", buf); if (strchr(buf, '\n') == 0) { int c; do { if ((c=getc(fpin)) == EOF) { *iseof=1; return; } if (fpout) putc(c, fpout); } while (c != '\n'); } continue; } if (fpout) fprintf(fpout, "--%s%s\n", b->boundary, is_closing ? "--":""); if (is_closing) { pop_mimestack_to(stack, b); continue; } break; } }
Surface_mesh::Normal Surface_mesh:: compute_vertex_normal(Vertex v) const { Point nn(0,0,0); Halfedge h = halfedge(v); if (h.is_valid()) { const Halfedge hend = h; const Point p0 = vpoint_[v]; Point n, p1, p2; Scalar cosine, angle; do { if (!is_boundary(h)) { p1 = vpoint_[to_vertex(h)]; p1 -= p0; p1.normalize(); p2 = vpoint_[from_vertex(prev_halfedge(h))]; p2 -= p0; p2.normalize(); cosine = p1.dot(p2) / sqrt(p1.dot(p1)*p2.dot(p2)); if (cosine < -1.0) cosine = -1.0; else if (cosine > 1.0) cosine = 1.0; angle = acos(cosine); n = p1.cross(p2).normalized(); n *= angle; nn += n; } h = cw_rotated_halfedge(h); } while (h != hend); nn.normalize(); } return nn; }
typename viennagrid::result_of::coord< MeshT >::type surface_meshsegment(MeshT const & mesh_obj) { typedef typename viennagrid::result_of::const_element_range<MeshT, ElementTypeOrTag>::type ElementRange; typedef typename viennagrid::result_of::iterator<ElementRange>::type ElementIterator; typename viennagrid::result_of::coord<MeshT>::type result = 0; ElementRange facets(mesh_obj); for (ElementIterator fit = facets.begin(); fit != facets.end(); ++fit) { if (is_boundary(mesh_obj, *fit)) result += viennagrid::volume(*fit); } return result; }
static void detect(AccessorT accessor, MeshT1 const & seg0, MeshT2 const & seg1) { typedef typename viennagrid::result_of::cell_tag<MeshT1>::type CellTag; typedef typename viennagrid::result_of::element<MeshT1, typename CellTag::facet_tag>::type FacetType; typedef typename viennagrid::result_of::const_handle<MeshT1, typename CellTag::facet_tag>::type ConstFacetHandleType; typedef typename viennagrid::result_of::const_element_range<MeshT1, typename CellTag::facet_tag>::type FacetRange; typedef typename viennagrid::result_of::iterator<FacetRange>::type FacetIterator; std::set<ConstFacetHandleType> facets_ptrs_seg0; // // Step 1: Write facets of segment 1 to a map: // FacetRange facets_seg0(seg0); for (FacetIterator fit = facets_seg0.begin(); fit != facets_seg0.end(); ++fit) { const FacetType & facet = *fit; if (is_boundary(seg0, facet)) facets_ptrs_seg0.insert( fit.handle() ); } // // Step 2: Compare facet in segment 2 with those stored in the map // FacetRange facets_seg1(seg1); for (FacetIterator fit = facets_seg1.begin(); fit != facets_seg1.end(); ++fit) { const FacetType & facet = *fit; if (facets_ptrs_seg0.find( fit.handle() ) != facets_ptrs_seg0.end()) accessor(facet) = true; } }
void Surface_mesh:: adjust_outgoing_halfedge(Vertex v) { Halfedge h = halfedge(v); const Halfedge hh = h; if (h.is_valid()) { do { if (is_boundary(h)) { set_halfedge(v, h); return; } h = cw_rotated_halfedge(h); } while (h != hh); } }
static int good_boundary(const char *boundary, struct mimestack *m, const char *errmsg, FILE *fp) { int dummy; int l=strlen(boundary); const char *p; char buf[BUFSIZ]; if (is_boundary(m, boundary, &dummy)) return (0); for (p=errmsg; *p; ) { if (*p == '-' && p[1] == '-' && strncasecmp(p+2, boundary, l) == 0) return (0); while (*p) if (*p++ == '\n') break; } if (fp) { if (my_rewind(fp) < 0) { perror("fseek"); exit(1); } while (fgets(buf, sizeof(buf), fp)) { if (buf[0] == '-' && buf[1] == '-' && strncasecmp(buf+2, boundary, l) == 0) return (0); } } return (1); }
bool Surface_mesh:: is_flip_ok(Edge e) const { // boundary edges cannot be flipped if (is_boundary(e)) return false; // check if the flipped edge is already present in the mesh Halfedge h0 = halfedge(e, 0); Halfedge h1 = halfedge(e, 1); Vertex v0 = to_vertex(next_halfedge(h0)); Vertex v1 = to_vertex(next_halfedge(h1)); if (v0 == v1) // this is generally a bad sign !!! return false; if (find_halfedge(v0, v1).is_valid()) return false; return true; }
void cal_onePath(Location *cur) { int min, i; Location buf[6]; if(cur->type == STONE) min = 100; else { if(is_boundary((*cur))) min = 0; else { get_round((*cur), buf); min = 100; for(i = 0; i < 6; i++) { if(min > abs(buf[i].path)) { min = buf[i].path; } } if(min != 100) min++; } } cur->path = min; }
// Retriangulate a cavity formed when a constraint edge is inserted, following Shewchuck and Brown. // The cavity is defined by a counterclockwise list of vertices v[0] to v[m-1] as in Shewchuck and Brown, Figure 5. static void cavity_delaunay(MutableTriangleTopology& parent_mesh, RawField<const EV,VertexId> X, RawArray<const VertexId> cavity, Random& random) { // Since the algorithm generates meshes which may be inconsistent with the outer mesh, and the cavity // array may have duplicate vertices, we use a temporary mesh and then copy the triangles over when done. // In the temporary, vertices are indexed consecutively from 0 to m-1. const int m = cavity.size(); assert(m >= 3); const auto mesh = new_<MutableTriangleTopology>(); Field<Perturbed2,VertexId> Xc(m,uninit); for (const int i : range(m)) Xc.flat[i] = Perturbed2(cavity[i].id,X[cavity[i]]); mesh->add_vertices(m); const auto xs = Xc.flat[0], xe = Xc.flat[m-1]; // Set up data structures for prev, next, pi in the paper const Field<VertexId,VertexId> prev(m,uninit), next(m,uninit); for (int i=0;i<m-1;i++) { next.flat[i] = VertexId(i+1); prev.flat[i+1] = VertexId(i); } const Array<VertexId> pi_(m-2,uninit); for (int i=1;i<=m-2;i++) pi_[i-1] = VertexId(i); #define PI(i) pi_[(i)-1] // Randomly shuffle [1,m-2], subject to vertices closer to xs-xe than both their neighbors occurring later for (int i=m-2;i>=2;i--) { int j; for (;;) { j = random.uniform<int>(0,i)+1; const auto pj = PI(j); if (!( segment_directions_oriented(xe,xs,Xc[pj],Xc[prev[pj]]) && segment_directions_oriented(xe,xs,Xc[pj],Xc[next[pj]]))) break; } swap(PI(i),PI(j)); // Remove PI(i) from the list const auto pi = PI(i); next[prev[pi]] = next[pi]; prev[next[pi]] = prev[pi]; } // Add the first triangle mesh->add_face(vec(VertexId(0),PI(1),VertexId(m-1))); // Add remaining triangles, flipping to ensure Delaunay const Field<bool,VertexId> marked(m); Array<HalfedgeId> fan; bool used_chew = false; for (int i=2;i<m-1;i++) { const auto pi = PI(i); insert_cavity_vertex(mesh,Xc,marked,pi,next[pi],prev[pi]); if (marked[pi]) { used_chew = true; marked[pi] = false; // Retriangulate the fans of triangles that have all three vertices marked auto e = mesh->reverse(mesh->halfedge(pi)); auto v = mesh->src(e); bool mv = marked[v]; marked[v] = false; fan.clear(); do { const auto h = mesh->prev(e); e = mesh->reverse(mesh->next(e)); v = mesh->src(e); const bool mv2 = marked[v]; marked[v] = false; if (mv) { if (mv2) fan.append(h); if (!mv2 || mesh->is_boundary(e)) { chew_fan(mesh,Xc,pi,fan,random); fan.clear(); } } mv = mv2; } while (!mesh->is_boundary(e)); } } #undef PI // If we ran Chew's algorithm, validate the output. I haven't tested this // case enough to be confident of its correctness. if (used_chew) assert_delaunay("Failure in extreme special case. If this triggers, please email [email protected]: ", mesh,Xc,Tuple<>(),false,false); // Copy triangles from temporary mesh to real mesh for (const auto f : mesh->faces()) { const auto v = mesh->vertices(f); parent_mesh.add_face(vec(cavity[v.x.id],cavity[v.y.id],cavity[v.z.id])); } }
static void checksign(struct mimestack **stack, int *iseof, struct header *h, FILE *fpin, FILE *fpout, int argc, char **argv) { char buf[BUFSIZ]; struct header *h2; char signed_content[TEMPNAMEBUFSIZE]; char signature[TEMPNAMEBUFSIZE]; int signed_file, signature_file; FILE *signed_file_fp, *signature_file_fp; int clos_flag; int need_nl, check_boundary; struct mimestack *b=0; struct mime_header *mh; int qpdecode=0; signed_file=mimegpg_tempfile(signed_content); if (signed_file < 0 || (signed_file_fp=fdopen(signed_file, "w+")) == 0) { if (signed_file > 0) { close(signed_file); unlink(signed_content); } perror("open"); exit(1); } noexec(signed_file_fp); find_boundary(stack, iseof, fpin, NULL, 0); if (*iseof) return; need_nl=0; check_boundary=1; while (!*iseof) { const char *p; if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; continue; } if (check_boundary && (b=is_boundary(*stack, buf, &clos_flag)) != 0) break; if (need_nl) fprintf(signed_file_fp, "\r\n"); for (p=buf; *p && *p != '\n'; p++) putc(*p, signed_file_fp); need_nl=check_boundary= *p != 0; } if (my_rewind(signed_file_fp) < 0) { perror(signed_content); fclose(signed_file_fp); unlink(signed_content); exit(1); } if (clos_flag) { fclose(signed_file_fp); unlink(signed_content); if (b) pop_mimestack_to(stack, b); find_boundary(stack, iseof, fpin, fpout, 1); return; } h=read_headers(stack, iseof, fpin, fpout, 0); if (!h || !(h2=find_header(h, "content-type:"))) { fclose(signed_file_fp); unlink(signed_content); if (!*iseof) find_boundary(stack, iseof, fpin, fpout, 1); return; } mh=parse_mime_header(h2->header+sizeof("content-type:")-1); if (!mh) { perror("malloc"); free_header(h); fclose(signed_file_fp); unlink(signed_content); exit(1); } if (!mh || strcasecmp(mh->header_name, "application/pgp-signature")) { if (!mh) free_mime_header(mh); free_header(h); fclose(signed_file_fp); unlink(signed_content); if (!*iseof) find_boundary(stack, iseof, fpin, fpout, 1); return; } free_mime_header(mh); /* ** In rare instances, the signature is qp-encoded. */ if ((h2=find_header(h, "content-transfer-encoding:")) != NULL) { mh=parse_mime_header(h2->header +sizeof("content-transfer-encoding:")-1); if (!mh) { perror("malloc"); free_header(h); fclose(signed_file_fp); unlink(signed_content); exit(1); } if (strcasecmp(mh->header_name, "quoted-printable") == 0) qpdecode=1; free_mime_header(mh); } free_header(h); signature_file=mimegpg_tempfile(signature); if (signature_file < 0 || (signature_file_fp=fdopen(signature_file, "w+")) == 0) { if (signature_file > 0) { close(signature_file); unlink(signature); } fclose(signed_file_fp); unlink(signed_content); perror("open"); exit(1); } while (!*iseof) { const char *p; if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; continue; } if ((b=is_boundary(*stack, buf, &clos_flag)) != 0) break; for (p=buf; *p; p++) { int n; if (!qpdecode) { putc(*p, signature_file_fp); continue; } if (*p == '=' && p[1] == '\n') break; if (*p == '=' && p[1] && p[2]) { n=nybble(p[1]) * 16 + nybble(p[2]); if ( (char)n ) { putc((char)n, signature_file_fp); p += 2; } p += 2; continue; } putc(*p, signature_file_fp); /* If some spits out qp-lines > BUFSIZ, they deserve ** this crap. */ } } fflush(signature_file_fp); if (ferror(signature_file_fp) || fclose(signature_file_fp)) { unlink(signature); fclose(signed_file_fp); unlink(signed_content); perror("open"); exit(1); } dochecksign(*stack, signed_file_fp, fpout, signed_content, signature, argc, argv); fclose(signed_file_fp); unlink(signature); unlink(signed_content); fprintf(fpout, "\n--%s--\n", b->boundary); while (!clos_flag) { if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; break; } if (!(b=is_boundary(*stack, buf, &clos_flag))) clos_flag=0; } if (b) pop_mimestack_to(stack, b); if (iseof) return; }
static void dogpgsign(struct mimestack **stack, struct header *h, int *iseof, FILE *fpin, FILE *fpout, int argc, char **argv) { struct header *hp; char buf[BUFSIZ]; struct gpgmime_forkinfo gpg; int clos_flag=0; struct mimestack *b=0; int rc; char signed_content_name[TEMPNAMEBUFSIZE]; int signed_content; FILE *signed_content_fp; const char *boundary; int need_crlf; for (hp=h; hp; hp=hp->next) { if (encode_header(hp->header)) continue; fprintf(fpout, "%s", hp->header); } signed_content=mimegpg_tempfile(signed_content_name); if (signed_content < 0 || (signed_content_fp=fdopen(signed_content, "w+")) == NULL) { if (signed_content >= 0) { close(signed_content); unlink(signed_content_name); } perror("mktemp"); exit(1); } noexec(signed_content_fp); unlink(signed_content_name); /* UNIX semantics */ for (hp=h; hp; hp=hp->next) { const char *p; if (!encode_header(hp->header)) continue; for (p=hp->header; *p; p++) { if (*p == '\r') continue; if (*p == '\n') putc('\r', signed_content_fp); putc(*p, signed_content_fp); } } /* ** Chew the content until the next MIME boundary. */ need_crlf=1; while (!*iseof) { const char *p; if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; break; } if (need_crlf) { if ((b=is_boundary(*stack, buf, &clos_flag)) != NULL) break; fprintf(signed_content_fp, "\r\n"); } need_crlf=0; for (;;) { for (p=buf; *p; p++) { if (*p == '\r') continue; if (*p == '\n') { need_crlf=1; break; } putc(*p, signed_content_fp); } if (*p == '\n') break; if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; break; } } } /* ** This needs some 'splainin. Note that we spit out a newline at ** the BEGINNING of each line, above. This generates the blank ** header->body separator line. Now, if we're NOT doing multiline ** content, we need to follow the last line of the content with a ** newline. If we're already doing multiline content, that extra ** newline (if it exists) is already there. */ if (!*stack) { fprintf(signed_content_fp, "\r\n"); } if (fflush(signed_content_fp) < 0 || ferror(signed_content_fp)) { perror(signed_content_name); exit(1); } boundary=get_boundary(*stack, "", signed_content_fp); if (my_rewind(signed_content_fp) < 0) { perror(signed_content_name); exit(1); } if (gpgmime_fork_signencrypt(NULL, GPG_SE_SIGN, argc, argv, &dumpgpg, fpout, &gpg)) { perror("fork"); exit(1); } fprintf(fpout, "Content-Type: multipart/signed;\n" " boundary=\"%s\";\n" " micalg=pgp-sha1;" " protocol=\"application/pgp-signature\"\n" "\n" "This is a mimegpg-signed message. If you see this text, it means that\n" "your E-mail software does not support MIME-formatted messages.\n" "\n--%s\n", boundary, boundary); while (fgets(buf, sizeof(buf), signed_content_fp) != NULL) { const char *p; gpgmime_write(&gpg, buf, strlen(buf)); for (p=buf; *p; p++) if (*p != '\r') putc(*p, fpout); } fprintf(fpout, "\n--%s\n" "Content-Type: application/pgp-signature\n" "Content-Transfer-Encoding: 7bit\n\n", boundary); rc=gpgmime_finish(&gpg); if (rc) { fprintf(stderr, "%s", gpgmime_getoutput(&gpg)); exit(1); } fprintf(fpout, "\n--%s--\n", boundary); fclose(signed_content_fp); if (*iseof) return; fprintf(fpout, "\n--%s%s\n", b->boundary, clos_flag ? "--":""); if (clos_flag) { pop_mimestack_to(stack, b); find_boundary(stack, iseof, fpin, fpout, 1); } }
static void dogpgencrypt(struct mimestack **stack, struct header *h, int *iseof, FILE *fpin, FILE *fpout, int argc, char **argv, int dosign) { struct header *hp; char buf[BUFSIZ]; struct gpgmime_forkinfo gpg; int clos_flag=0; struct mimestack *b=0; int rc; const char *boundary; int need_crlf; boundary=get_boundary(*stack, "", NULL); if (gpgmime_fork_signencrypt(NULL, (dosign ? GPG_SE_SIGN:0) | GPG_SE_ENCRYPT, argc, argv, &dumpgpg, fpout, &gpg)) { perror("fork"); exit(1); } for (hp=h; hp; hp=hp->next) { if (encode_header(hp->header)) continue; fprintf(fpout, "%s", hp->header); } fprintf(fpout, "Content-Type: multipart/encrypted;\n" " boundary=\"%s\";\n" " protocol=\"application/pgp-encrypted\"\n" "\n" "This is a mimegpg-encrypted message. If you see this text, it means\n" "that your E-mail software does not support MIME formatted messages.\n" "\n--%s\n" "Content-Type: application/pgp-encrypted\n" "Content-Transfer-Encoding: 7bit\n" "\n" "Version: 1\n" "\n--%s\n" "Content-Type: application/octet-stream\n" "Content-Transfer-Encoding: 7bit\n\n", boundary, boundary, boundary); /* For Eudora compatiblity */ gpgmime_write(&gpg, "Mime-Version: 1.0\r\n", 19); for (hp=h; hp; hp=hp->next) { const char *p; if (!encode_header(hp->header)) continue; for (p=hp->header; *p; p++) { if (*p == '\r') continue; if (*p == '\n') gpgmime_write(&gpg, "\r\n", 2); else gpgmime_write(&gpg, p, 1); } } /* ** Chew the content until the next MIME boundary. */ need_crlf=1; while (!*iseof) { const char *p; if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; break; } if (need_crlf) { if ((b=is_boundary(*stack, buf, &clos_flag)) != NULL) break; gpgmime_write(&gpg, "\r\n", 2); } need_crlf=0; for (;;) { for (p=buf; *p; p++) { if (*p == '\r') continue; if (*p == '\n') { need_crlf=1; break; } gpgmime_write(&gpg, p, 1); } if (*p == '\n') break; if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; break; } } } /* ** This needs some 'splainin. Note that we spit out a newline at ** the BEGINNING of each line, above. This generates the blank ** header->body separator line. Now, if we're NOT doing multiline ** content, we need to follow the last line of the content with a ** newline. If we're already doing multiline content, that extra ** newline (if it exists) is already there. */ if (!*stack) { gpgmime_write(&gpg, "\r\n", 2); } rc=gpgmime_finish(&gpg); if (rc) { fprintf(stderr, "%s", gpgmime_getoutput(&gpg)); exit(1); } fprintf(fpout, "\n--%s--\n", boundary); if (*iseof) return; fprintf(fpout, "\n--%s%s\n", b->boundary, clos_flag ? "--":""); if (clos_flag) { pop_mimestack_to(stack, b); find_boundary(stack, iseof, fpin, fpout, 1); } }
static struct header *read_headers(struct mimestack **stack, int *iseof, FILE *fpin, FILE *fpout, int doappend) { char buf[BUFSIZ]; struct read_header_context rhc; struct header *h; init_read_header_context(&rhc); while (!*iseof) { if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; break; } if (READ_START_OF_LINE(rhc)) { struct mimestack *b; int is_closing; if (strcmp(buf, "\n") == 0 || strcmp(buf, "\r\n") == 0) break; b=is_boundary(*stack, buf, &is_closing); if (b) { /* ** Corrupted MIME message. We should NOT ** see a MIME boundary in the middle of the ** headers! ** ** Ignore this damage. */ struct header *p; h=finish_header(&rhc); for (p=h; p; p=p->next) fprintf(fpout, "%s", p->header); fprintf(fpout, "--%s%s", b->boundary, is_closing ? "--":""); if (is_closing) { pop_mimestack_to(stack, b); find_boundary(stack, iseof, fpin, fpout, doappend); } free_header(h); init_read_header_context(&rhc); continue; /* From the top */ } } read_header(&rhc, buf); } return (finish_header(&rhc)); }
static void dodecrypt(struct mimestack **stack, int *iseof, FILE *fpin, FILE *fpout, int argc, char **argv, const char *temp_file, FILE *realout) { struct gpgmime_forkinfo gpg; char buf[BUFSIZ]; int is_closing; struct mimestack *b=NULL; int dowrite=1; int rc; const char *new_boundary; const char *output; if (gpgmime_forkdecrypt(NULL, argc, argv, &dumpdecrypt, fpout, &gpg)) { perror("fork"); exit(1); } for (;;) { if (fgets(buf, sizeof(buf), fpin) == NULL) { *iseof=1; break; } if (dowrite) gpgmime_write(&gpg, buf, strlen(buf)); if (!(b=is_boundary(*stack, buf, &is_closing))) continue; dowrite=0; if (!is_closing) continue; break; } rc=gpgmime_finish(&gpg); if (fflush(fpout) || ferror(fpout) || my_rewind(fpout) < 0) { perror(temp_file); fclose(fpout); unlink(temp_file); exit(1); } if (*iseof) return; output=gpgmime_getoutput(&gpg), new_boundary=get_boundary(*stack, output, rc ? NULL:fpout); open_result_multipart(realout, rc, new_boundary, output, gpgmime_getcharset(&gpg)); if (rc == 0) { int c; if (fseek(fpout, 0L, SEEK_SET) < 0) { perror(temp_file); fclose(fpout); unlink(temp_file); exit(1); } fprintf(realout, "\n--%s\n", new_boundary); while ((c=getc(fpout)) != EOF) if (c != '\r') putc(c, realout); } fprintf(realout, "\n--%s--\n", new_boundary); pop_mimestack_to(stack, b); }
void * motor_thread(void * arg) { int iret; int a_bound=0,b_bound=0; unsigned char low_gpio[4]={0,0,0,0}; unsigned char (*ptr)[4], *p; unsigned int a_step_delay=0, b_step_delay=0; ptr = step_data; while(run_motor_thread) { set_step_motor(low_gpio,a_motor.gpio); set_step_motor( low_gpio,b_motor.gpio); iret = pthread_cond_wait(&motor_update,&motion_mutex); autostop_counter = 0; while ((a_motor.state != MOTOR_STOP || b_motor.state != MOTOR_STOP) && (autostop_counter < AUTOSTOP_COUNTER)) { if(a_motor.state != MOTOR_STOP && a_step_delay ==0) { if(is_boundary(a_motor.gpio[4])) { ``````````````````````````````a_bound +=a_motor.state; if(a_bound > BOUNDARY_DETECT_NUM || a_bound < -BOUNDARY_DETECT_NUM) { a_motor.last_bound = a_motor.state; a_motor.state = MOTOR_STOP; a_bound = 0; printf("A motor boundary\n"); } } set_index(&(a_motor.data_index), a_motor.state); set_index(&(a_motor.data_index), a_motor.state); p = *( ptr+ a_motor.data_index); set_step_motor(p,a_motor.gpio); a_step_delay = a_motor.step_delay; } if(b_motor.state != MOTOR_STOP && b_step_delay == 0) { if(is_boundary(b_motor.gpio[4])) { b_bound +=b_motor.state; if(b_bound > BOUNDARY_DETECT_NUM || b_bound < -BOUNDARY_DETECT_NUM) { b_motor.last_bound = b_motor.state; b_motor.state = MOTOR_STOP; b_bound =0; printf("B motor boundary\n"); } } set_index(&(b_motor.data_index), b_motor.state); p=*(ptr+b_motor.data_index); set_step_motor( p,b_motor.gpio); b_step_delay = b_motor.step_delay; } exit_motion: usleep(QUATUM_DLAY_STEP_MOTOR); autostop_counter++; if (autostop_counter >= AUTOSTOP_COUNTER) { } if(a_step_delay) a_step_delay--; if(b_step_delay) b_step_delay--; } } pthread_exit(NULL); }
static apr_status_t upload_filter(ap_filter_t *f, apr_bucket_brigade *bbout, ap_input_mode_t mode, apr_read_type_e block, apr_off_t nbytes) { char* buf = 0 ; char* p = buf ; char* e ; int ret = APR_SUCCESS ; apr_size_t bytes = 0 ; apr_bucket* b ; apr_bucket_brigade* bbin ; upload_ctx* ctx = (upload_ctx*) f->ctx ; if ( ctx->parse_state == p_done ) { // send an EOS APR_BRIGADE_INSERT_TAIL(bbout, apr_bucket_eos_create(bbout->bucket_alloc) ) ; return APR_SUCCESS ; } /* should be more efficient to do this in-place without resorting * to a new brigade */ bbin = apr_brigade_create(f->r->pool, f->r->connection->bucket_alloc) ; if ( ret = ap_get_brigade(f->next, bbin, mode, block, nbytes) , ret != APR_SUCCESS ) return ret ; for ( b = APR_BRIGADE_FIRST(bbin) ; b != APR_BRIGADE_SENTINEL(bbin) ; b = APR_BUCKET_NEXT(b) ) { const char* ptr = buf ; if ( APR_BUCKET_IS_EOS(b) ) { ctx->parse_state = p_done ; APR_BRIGADE_INSERT_TAIL(bbout, apr_bucket_eos_create(bbout->bucket_alloc) ) ; apr_brigade_destroy(bbin) ; return APR_SUCCESS ; } else if ( apr_bucket_read(b, &ptr, &bytes, APR_BLOCK_READ) == APR_SUCCESS ) { const char* p = ptr ; while ( e = strchr(p, '\n'), ( e && ( e < (ptr+bytes) ) ) ) { const char* ptmp = p ; *e = 0 ; if ( ctx->leftover ) { // this'll be grossly inefficient if we get lots of // little buckets (we don't in my setup:-) ptmp = apr_pstrcat(f->r->pool, ctx->leftover, p, NULL) ; ctx->leftover = 0 ; } switch ( ctx->parse_state ) { case p_none: if ( is_boundary(ctx, ptmp) == boundary_part ) ctx->parse_state = p_head ; break ; case p_head: if ( (! *ptmp) || ( *ptmp == '\r') ) ctx->parse_state = p_field ; else set_header(ctx, ptmp) ; break ; case p_field: switch ( is_boundary(ctx, ptmp) ) { case boundary_part: end_body(ctx) ; ctx->parse_state = p_head ; break ; case boundary_end: end_body(ctx) ; ctx->parse_state = p_end ; break ; case boundary_none: if ( ctx->is_file ) { apr_brigade_puts(bbout, ap_filter_flush, f, ptmp) ; apr_brigade_putc(bbout, ap_filter_flush, f, '\n') ; } else set_body(ctx, ptmp) ; break ; } break ; case p_end: //APR_BRIGADE_INSERT_TAIL(bbout, // apr_bucket_eos_create(bbout->bucket_alloc) ) ; ctx->parse_state = p_done ; case p_done: break ; } if ( e - ptr >= bytes ) break ; p = e + 1 ; } if ( ( ctx->parse_state != p_end ) && ( ctx->parse_state != p_done ) ) { size_t bleft = bytes - (p-ptr) ; ctx->leftover = apr_pstrndup(f->r->pool, p, bleft ) ; #ifdef DEBUG ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0, f->r, "leftover %d bytes\n\t%s\n\t%s\n", bleft, ctx->leftover, p) ; #endif } } } apr_brigade_destroy(bbin) ; return ret ; }
void Surface_mesh:: split(Edge e, Vertex v) { Halfedge h0 = halfedge(e, 0); Halfedge o0 = halfedge(e, 1); Vertex v2 = to_vertex(o0); Halfedge e1 = new_edge(v, v2); Halfedge t1 = opposite_halfedge(e1); Face f0 = face(h0); Face f3 = face(o0); set_halfedge(v, h0); set_vertex(o0, v); if (!is_boundary(h0)) { Halfedge h1 = next_halfedge(h0); Halfedge h2 = next_halfedge(h1); Vertex v1 = to_vertex(h1); Halfedge e0 = new_edge(v, v1); Halfedge t0 = opposite_halfedge(e0); Face f1 = new_face(); set_halfedge(f0, h0); set_halfedge(f1, h2); set_face(h1, f0); set_face(t0, f0); set_face(h0, f0); set_face(h2, f1); set_face(t1, f1); set_face(e0, f1); set_next_halfedge(h0, h1); set_next_halfedge(h1, t0); set_next_halfedge(t0, h0); set_next_halfedge(e0, h2); set_next_halfedge(h2, t1); set_next_halfedge(t1, e0); } else { set_next_halfedge(prev_halfedge(h0), t1); set_next_halfedge(t1, h0); // halfedge handle of _vh already is h0 } if (!is_boundary(o0)) { Halfedge o1 = next_halfedge(o0); Halfedge o2 = next_halfedge(o1); Vertex v3 = to_vertex(o1); Halfedge e2 = new_edge(v, v3); Halfedge t2 = opposite_halfedge(e2); Face f2 = new_face(); set_halfedge(f2, o1); set_halfedge(f3, o0); set_face(o1, f2); set_face(t2, f2); set_face(e1, f2); set_face(o2, f3); set_face(o0, f3); set_face(e2, f3); set_next_halfedge(e1, o1); set_next_halfedge(o1, t2); set_next_halfedge(t2, e1); set_next_halfedge(o0, e2); set_next_halfedge(e2, o2); set_next_halfedge(o2, o0); } else { set_next_halfedge(e1, next_halfedge(o0)); set_next_halfedge(o0, e1); set_halfedge(v, e1); } if (halfedge(v2) == h0) set_halfedge(v2, t1); }
void go_computer() { int i; int oldx = computer.x; int oldy = computer.y; Location buf[6]; if(is_boundary(computer)) who_win(COMPUTER); if(is_inCircle(computer)) { i = max_cost(computer); inCircle = 1; } else i = min_path(computer); switch(i) { case 0: computer.y--; break; case 1: if((computer.x % 2) == 0) { computer.x--; computer.y--; } else { computer.x--; } break; case 2: if((computer.x % 2) == 0) { computer.x--; } else { computer.x--; computer.y++; } break; case 3: computer.y++; break; case 4: if((computer.x % 2) == 0) { computer.x++; } else { computer.x++; computer.y++; } break; case 5: if((computer.x % 2) == 0) { computer.x++; computer.y--; } else { computer.x++; } break; } //end switch if((oldx % 2) == 0) move(oldx, oldy*2); else move(oldx, oldy*2+1); draw_one(WAY); map[oldx][oldy].type = WAY; if((computer.x % 2) == 0) move(computer.x, computer.y*2); else move(computer.x, computer.y*2+1); draw_one(CAT); map[computer.x][computer.y].type = CAT; }
Surface_mesh::Face Surface_mesh:: add_face(const std::vector<Vertex>& vertices) { Vertex v; unsigned int i, ii, n((int)vertices.size()), id; std::vector<Halfedge> halfedges(n); std::vector<bool> is_new(n), needs_adjust(n, false); Halfedge inner_next, inner_prev, outer_next, outer_prev, boundary_next, boundary_prev, patch_start, patch_end; // cache for set_next_halfedge and vertex' set_halfedge typedef std::pair<Halfedge, Halfedge> NextCacheEntry; typedef std::vector<NextCacheEntry> NextCache; NextCache next_cache; next_cache.reserve(3*n); // don't allow degenerated faces assert (n > 2); // test for topological errors for (i=0, ii=1; i<n; ++i, ++ii, ii%=n) { if ( !is_boundary(vertices[i]) ) { std::cerr << "Surface_meshT::add_face: complex vertex\n"; return Face(); } halfedges[i] = find_halfedge(vertices[i], vertices[ii]); is_new[i] = !halfedges[i].is_valid(); if (!is_new[i] && !is_boundary(halfedges[i])) { std::cerr << "Surface_meshT::add_face: complex edge\n"; return Face(); } } // re-link patches if necessary for (i=0, ii=1; i<n; ++i, ++ii, ii%=n) { if (!is_new[i] && !is_new[ii]) { inner_prev = halfedges[i]; inner_next = halfedges[ii]; if (next_halfedge(inner_prev) != inner_next) { // here comes the ugly part... we have to relink a whole patch // search a free gap // free gap will be between boundary_prev and boundary_next outer_prev = opposite_halfedge(inner_next); outer_next = opposite_halfedge(inner_prev); boundary_prev = outer_prev; do boundary_prev = opposite_halfedge(next_halfedge(boundary_prev)); while (!is_boundary(boundary_prev) || boundary_prev==inner_prev); boundary_next = next_halfedge(boundary_prev); assert(is_boundary(boundary_prev)); assert(is_boundary(boundary_next)); // ok ? if (boundary_next == inner_next) { std::cerr << "Surface_meshT::add_face: patch re-linking failed\n"; return Face(); } // other halfedges' handles patch_start = next_halfedge(inner_prev); patch_end = prev_halfedge(inner_next); // relink next_cache.push_back(NextCacheEntry(boundary_prev, patch_start)); next_cache.push_back(NextCacheEntry(patch_end, boundary_next)); next_cache.push_back(NextCacheEntry(inner_prev, inner_next)); } } } // create missing edges for (i=0, ii=1; i<n; ++i, ++ii, ii%=n) if (is_new[i]) halfedges[i] = new_edge(vertices[i], vertices[ii]); // create the face Face f(new_face()); set_halfedge(f, halfedges[n-1]); // setup halfedges for (i=0, ii=1; i<n; ++i, ++ii, ii%=n) { v = vertices[ii]; inner_prev = halfedges[i]; inner_next = halfedges[ii]; id = 0; if (is_new[i]) id |= 1; if (is_new[ii]) id |= 2; if (id) { outer_prev = opposite_halfedge(inner_next); outer_next = opposite_halfedge(inner_prev); // set outer links switch (id) { case 1: // prev is new, next is old boundary_prev = prev_halfedge(inner_next); next_cache.push_back(NextCacheEntry(boundary_prev, outer_next)); set_halfedge(v, outer_next); break; case 2: // next is new, prev is old boundary_next = next_halfedge(inner_prev); next_cache.push_back(NextCacheEntry(outer_prev, boundary_next)); set_halfedge(v, boundary_next); break; case 3: // both are new if (!halfedge(v).is_valid()) { set_halfedge(v, outer_next); next_cache.push_back(NextCacheEntry(outer_prev, outer_next)); } else { boundary_next = halfedge(v); boundary_prev = prev_halfedge(boundary_next); next_cache.push_back(NextCacheEntry(boundary_prev, outer_next)); next_cache.push_back(NextCacheEntry(outer_prev, boundary_next)); } break; } // set inner link next_cache.push_back(NextCacheEntry(inner_prev, inner_next)); } else needs_adjust[ii] = (halfedge(v) == inner_next); // set face handle set_face(halfedges[i], f); } // process next halfedge cache NextCache::const_iterator ncIt(next_cache.begin()), ncEnd(next_cache.end()); for (; ncIt != ncEnd; ++ncIt) set_next_halfedge(ncIt->first, ncIt->second); // adjust vertices' halfedge handle for (i=0; i<n; ++i) if (needs_adjust[i]) adjust_outgoing_halfedge(vertices[i]); return f; }
// Delaunay retriangulate a triangle fan static void chew_fan(MutableTriangleTopology& parent_mesh, RawField<const Perturbed2,VertexId> X, const VertexId u, RawArray<HalfedgeId> fan, Random& random) { chew_fan_count_ += 1; #ifndef NDEBUG for (const auto e : fan) assert(parent_mesh.opposite(e)==u); for (int i=0;i<fan.size()-1;i++) GEODE_ASSERT(parent_mesh.src(fan[i])==parent_mesh.dst(fan[i+1])); #endif const int n = fan.size(); if (n < 2) return; chew_fan_count_ += 1024*n; // Collect vertices const Field<VertexId,VertexId> vertices(n+2,uninit); vertices.flat[0] = u; vertices.flat[1] = parent_mesh.src(fan[n-1]); for (int i=0;i<n;i++) vertices.flat[i+2] = parent_mesh.dst(fan[n-1-i]); // Delete original vertices for (const auto e : fan) parent_mesh.erase(parent_mesh.face(e)); // Make the vertices into a doubly linked list const Field<VertexId,VertexId> prev(n+2,uninit), next(n+2,uninit); prev.flat[0].id = n+1; next.flat[n+1].id = 0; for (int i=0;i<n+1;i++) { prev.flat[i+1].id = i; next.flat[i].id = i+1; } // Randomly shuffle the vertices, then pulling elements off the linked list in reverse order of our final shuffle. const Array<VertexId> pi(n+2,uninit); for (int i=0;i<n+2;i++) pi[i].id = i; random.shuffle(pi); for (int i=n+1;i>=0;i--) { const auto j = pi[i]; prev[next[j]] = prev[j]; next[prev[j]] = next[j]; } // Make a new singleton mesh const auto mesh = new_<MutableTriangleTopology>(); mesh->add_vertices(n+2); small_sort(pi[0],pi[1],pi[2]); mesh->add_face(vec(pi[0],pi[1],pi[2])); // Insert remaining vertices Array<HalfedgeId> work; for (int i=3;i<n+2;i++) { const auto j = pi[i]; const auto f = mesh->add_face(vec(j,next[j],prev[j])); work.append(mesh->reverse(mesh->opposite(f,j))); while (work.size()) { auto e = work.pop(); if ( !mesh->is_boundary(e) && incircle(X[vertices[mesh->src(e)]], X[vertices[mesh->dst(e)]], X[vertices[mesh->opposite(e)]], X[vertices[mesh->opposite(mesh->reverse(e))]])) { work.append(mesh->reverse(mesh->next(e))); work.append(mesh->reverse(mesh->prev(e))); e = mesh->unsafe_flip_edge(e); } } } // Copy triangles back to parent for (const auto f : mesh->faces()) { const auto vs = mesh->vertices(f); parent_mesh.add_face(vec(vertices[vs.x],vertices[vs.y],vertices[vs.z])); } }
void Surface_mesh:: garbage_collection() { if (!garbage_) return; int i, i0, i1, nV(vertices_size()), nE(edges_size()), nH(halfedges_size()), nF(faces_size()); Vertex v; Halfedge h; Face f; if (!vdeleted_) vdeleted_ = vertex_property<bool>("v:deleted", false); if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false); if (!fdeleted_) fdeleted_ = face_property<bool>("f:deleted", false); // setup handle mapping Vertex_property<Vertex> vmap = add_vertex_property<Vertex>("v:garbage-collection"); Halfedge_property<Halfedge> hmap = add_halfedge_property<Halfedge>("h:garbage-collection"); Face_property<Face> fmap = add_face_property<Face>("f:garbage-collection"); for (i=0; i<nV; ++i) vmap[Vertex(i)] = Vertex(i); for (i=0; i<nH; ++i) hmap[Halfedge(i)] = Halfedge(i); for (i=0; i<nF; ++i) fmap[Face(i)] = Face(i); // remove deleted vertices if (nV > 0) { i0=0; i1=nV-1; while (1) { // find first deleted and last un-deleted while (!vdeleted_[Vertex(i0)] && i0 < i1) ++i0; while ( vdeleted_[Vertex(i1)] && i0 < i1) --i1; if (i0 >= i1) break; // swap vprops_.swap(i0, i1); //add for(unsigned int j = 0;j<map_2skel.size();j++) { if(map_2skel[j] == i0) map_2skel[j] = i1; else if(map_2skel[j] == i1) map_2skel[j] = i0; } //end }; // remember new size nV = vdeleted_[Vertex(i0)] ? i0 : i0+1; } // remove deleted edges if (nE > 0) { i0=0; i1=nE-1; while (1) { // find first deleted and last un-deleted while (!edeleted_[Edge(i0)] && i0 < i1) ++i0; while ( edeleted_[Edge(i1)] && i0 < i1) --i1; if (i0 >= i1) break; // swap eprops_.swap(i0, i1); hprops_.swap(2*i0, 2*i1); hprops_.swap(2*i0+1, 2*i1+1); }; // remember new size nE = edeleted_[Edge(i0)] ? i0 : i0+1; nH = 2*nE; } // remove deleted faces if (nF > 0) { i0=0; i1=nF-1; while (1) { // find 1st deleted and last un-deleted while (!fdeleted_[Face(i0)] && i0 < i1) ++i0; while ( fdeleted_[Face(i1)] && i0 < i1) --i1; if (i0 >= i1) break; // swap fprops_.swap(i0, i1); }; // remember new size nF = fdeleted_[Face(i0)] ? i0 : i0+1; } // update vertex connectivity for (i=0; i<nV; ++i) { v = Vertex(i); if (!is_isolated(v)) set_halfedge(v, hmap[halfedge(v)]); } // update halfedge connectivity for (i=0; i<nH; ++i) { h = Halfedge(i); set_vertex(h, vmap[to_vertex(h)]); set_next_halfedge(h, hmap[next_halfedge(h)]); if (!is_boundary(h)) set_face(h, fmap[face(h)]); } // update handles of faces for (i=0; i<nF; ++i) { f = Face(i); set_halfedge(f, hmap[halfedge(f)]); } // remove handle maps remove_vertex_property(vmap); remove_halfedge_property(hmap); remove_face_property(fmap); // finally resize arrays vprops_.resize(nV); vprops_.free_memory(); hprops_.resize(nH); hprops_.free_memory(); eprops_.resize(nE); eprops_.free_memory(); fprops_.resize(nF); fprops_.free_memory(); deleted_vertices_ = deleted_edges_ = deleted_faces_ = 0; garbage_ = false; }