00001 #include "btol_face_algs.h"
00002
00003
00004
00005 #include <vgl/vgl_point_2d.h>
00006 #include <vdgl/vdgl_digital_curve.h>
00007 #include <vdgl/vdgl_interpolator.h>
00008 #include <vdgl/vdgl_edgel_chain.h>
00009 #include <vtol/vtol_vertex_sptr.h>
00010 #include <vtol/vtol_vertex_2d.h>
00011 #include <vtol/vtol_edge_2d.h>
00012 #include <vtol/vtol_face_2d.h>
00013 #include <vsol/vsol_point_2d.h>
00014 #include <vsol/vsol_polygon_2d.h>
00015 #include <bsol/bsol_algs.h>
00016 #include "btol_vertex_algs.h"
00017
00018
00019
00020
00021
00022 static bool properly_ordered_verts(vtol_one_chain_sptr const& cycle,
00023 vcl_vector<vtol_vertex_sptr>& verts)
00024 {
00025 if (!cycle||!cycle->is_cycle())
00026 return false;
00027 int n = cycle->num_edges();
00028 for (int i = 0; i<n; i++)
00029 {
00030 vtol_edge_sptr e = cycle->edge(i);
00031 verts.push_back(e->v1());
00032 }
00033 return true;
00034 }
00035
00036
00037 bool btol_face_algs::vtol_to_vgl(vtol_face_2d_sptr const & face,
00038 vgl_polygon<double>& poly)
00039 {
00040 if (!face)
00041 return false;
00042 #if 0
00043 poly.clear();
00044 poly.new_sheet();
00045 vcl_vector<vtol_one_chain_sptr> one_chains;
00046 face->one_chains(one_chains);
00047 if (one_chains.size()!=1)
00048 return false;
00049 vcl_vector<vtol_vertex_sptr> verts;
00050 face->vertices(verts);
00051 if (!verts.size())
00052 return false;
00053 for (vcl_vector<vtol_vertex_sptr>::iterator vit = verts.begin();
00054 vit != verts.end(); vit++)
00055 {
00056 vtol_vertex_2d* v = (*vit)->cast_to_vertex_2d();
00057 if (v)
00058 poly.push_back(v->x(), v->y());
00059 }
00060 #endif
00061 poly.clear();
00062 poly.new_sheet();
00063 vcl_vector<vtol_vertex_sptr>* outside_verts =
00064 face->outside_boundary_vertices();
00065 for (vcl_vector<vtol_vertex_sptr>::iterator vit = outside_verts->begin();
00066 vit != outside_verts->end(); ++vit)
00067 {
00068 vtol_vertex_2d* v = (*vit)->cast_to_vertex_2d();
00069 if (v)
00070 poly.push_back(v->x(), v->y());
00071 }
00072 delete outside_verts;
00073
00074 vcl_vector<vtol_one_chain_sptr>* hole_chains = face->get_hole_cycles();
00075 vcl_vector<vcl_vector<vtol_vertex_sptr> > all_hole_verts;
00076 for (vcl_vector<vtol_one_chain_sptr>::iterator cit = hole_chains->begin();
00077 cit != hole_chains->end(); cit++)
00078 {
00079 vcl_vector<vtol_vertex_sptr> hole_verts;
00080 if (!properly_ordered_verts(*cit, hole_verts))
00081 return false;
00082 poly.new_sheet();
00083 for (vcl_vector<vtol_vertex_sptr>::iterator vit = hole_verts.begin();
00084 vit != hole_verts.end(); ++vit)
00085 {
00086 vtol_vertex_2d_sptr v = (*vit)->cast_to_vertex_2d();
00087 if (v)
00088 poly.push_back(v->x(), v->y());
00089 }
00090 }
00091 delete hole_chains;
00092 return true;
00093 }
00094
00095
00096 bool btol_face_algs::vgl_to_vtol(vgl_polygon<double>const & poly,
00097 vtol_face_2d_sptr& face)
00098 {
00099
00100 vcl_vector<vtol_one_chain_sptr> chains;
00101 int n_sheets = poly.num_sheets();
00102 for (int i = 0; i<n_sheets; i++)
00103 {
00104 vtol_one_chain_sptr chain = new vtol_one_chain();
00105 vcl_vector<vgl_point_2d<double> > s = poly[i];
00106 vgl_point_2d<double> p0 = s[0];
00107 vtol_vertex_2d_sptr vs = new vtol_vertex_2d(p0.x(), p0.y()), v0 = vs, vi;
00108 vtol_edge_2d_sptr e;
00109 for (vcl_vector<vgl_point_2d<double> >::iterator pit = s.begin()+1;
00110 pit != s.end(); ++pit)
00111 {
00112 vgl_point_2d<double> pi = *pit;
00113 vi = new vtol_vertex_2d(pi.x(), pi.y());
00114 e = new vtol_edge_2d(v0, vi);
00115 chain->add_edge(e, i==0);
00116 v0 = vi;
00117 }
00118
00119 e = new vtol_edge_2d(vi, vs);
00120 chain->add_edge(e, i==0);
00121 chain->set_cycle(true);
00122 chains.push_back(chain);
00123 }
00124
00125
00126 face = new vtol_face_2d(chains);
00127 return true;
00128 }
00129
00130
00131 bool btol_face_algs::edge_intersects(vtol_face_2d_sptr const & face,
00132 vtol_edge_2d_sptr const & edge)
00133 {
00134 if (!face||!edge)
00135 return false;
00136
00137 vsol_box_2d_sptr face_bounds = face->get_bounding_box();
00138 vsol_box_2d_sptr edge_bounds = edge->get_bounding_box();
00139 if (!bsol_algs::meet(face_bounds, edge_bounds))
00140 return false;
00141 vsol_curve_2d_sptr c = edge->curve();
00142 vdgl_digital_curve_sptr dc = c->cast_to_vdgl_digital_curve();
00143 if (!dc)
00144 {
00145 vcl_cout << "In btol_face_algs::edge_intersects(.) -"
00146 << " only digital curve geometry implemented\n";
00147 return false;
00148 }
00149
00150 vgl_polygon<double> poly;
00151 btol_face_algs::vtol_to_vgl(face, poly);
00152
00153 vdgl_interpolator_sptr intp = dc->get_interpolator();
00154 vdgl_edgel_chain_sptr ec = intp->get_edgel_chain();
00155 int nedgl = ec->size();
00156 for (int i=0; i<nedgl; i++)
00157 if (poly.contains((*ec)[i].x(), (*ec)[i].y()))
00158 return true;
00159 return false;
00160 }
00161
00162
00163
00164 bool btol_face_algs::
00165 intersecting_edges(vtol_face_2d_sptr const & face,
00166 vcl_vector<vtol_edge_2d_sptr> const & edges,
00167 vcl_vector<vtol_edge_2d_sptr>& inter_edges)
00168 {
00169 if (!face||!edges.size())
00170 return false;
00171 inter_edges.clear();
00172 bool empty = true;
00173 for (vcl_vector<vtol_edge_2d_sptr>::const_iterator eit = edges.begin();
00174 eit != edges.end(); eit++)
00175 if (btol_face_algs::edge_intersects(face, *eit))
00176 {
00177 inter_edges.push_back(*eit);
00178 empty = false;
00179 }
00180 return !empty;
00181 }
00182
00183
00184 vsol_point_2d_sptr btol_face_algs::centroid(vtol_face_2d_sptr const & face)
00185 {
00186 if (!face)
00187 return (vsol_point_2d*)0;
00188 vcl_vector<vtol_vertex_sptr> verts;
00189 face->vertices(verts);
00190 int n = 0;
00191 double x0=0, y0=0;
00192 for (vcl_vector<vtol_vertex_sptr>::iterator vit = verts.begin();
00193 vit != verts.end(); vit++, n++)
00194 {
00195 vtol_vertex_2d_sptr v = (*vit)->cast_to_vertex_2d();
00196 x0 += v->x();
00197 y0 += v->y();
00198 }
00199 if (!n)
00200 return (vsol_point_2d*)0;
00201 x0 /=n;
00202 y0 /=n;
00203 return new vsol_point_2d(x0, y0);
00204 }
00205
00206 vtol_face_2d_sptr btol_face_algs::box(const double x0, const double y0,
00207 const double width, const double height)
00208 {
00209 double w = width/2, h = height/2;
00210 vcl_vector<vtol_vertex_sptr> verts;
00211 vtol_vertex_2d* v0 = new vtol_vertex_2d(x0-w, y0-h);
00212 vtol_vertex_2d* v1 = new vtol_vertex_2d(x0+w, y0-h);
00213 vtol_vertex_2d* v2 = new vtol_vertex_2d(x0+w, y0+h);
00214 vtol_vertex_2d* v3 = new vtol_vertex_2d(x0-w, y0+h);
00215 verts.push_back(v0); verts.push_back(v1);
00216 verts.push_back(v2); verts.push_back(v3);
00217 vtol_face_2d_sptr f = new vtol_face_2d(verts);
00218 return f;
00219 }
00220
00221
00222
00223 vtol_one_chain_sptr btol_face_algs::
00224 one_chain(vcl_vector<vtol_vertex_sptr> const& verts)
00225 {
00226 vtol_one_chain_sptr out;
00227 int n = verts.size();
00228 if (n<3)
00229 return out;
00230 vtol_vertex_2d_sptr v0 = verts[0]->cast_to_vertex_2d(), vs = v0, vi;
00231 vtol_edge_2d_sptr e;
00232 out = new vtol_one_chain();
00233 for (int i = 1; i<n; i++)
00234 {
00235 vi = verts[i]->cast_to_vertex_2d();
00236 e = new vtol_edge_2d(v0, vi);
00237 out->add_edge(e, true);
00238 v0=vi;
00239 }
00240
00241 e = new vtol_edge_2d(vi, vs);
00242 out->add_edge(e, true);
00243 out->set_cycle(true);
00244 return out;
00245 }
00246
00247
00248
00249 vtol_face_2d_sptr btol_face_algs::
00250 transform(vtol_face_2d_sptr const& face,
00251 vnl_matrix_fixed<double, 3, 3> const& T)
00252 {
00253 vtol_face_2d_sptr out;
00254 if (!face)
00255 return out;
00256
00257 vcl_vector<vtol_vertex_sptr>* outside_verts =
00258 face->outside_boundary_vertices();
00259
00260 vcl_vector<vtol_vertex_sptr> trans_outside_verts;
00261 for (vcl_vector<vtol_vertex_sptr>::iterator vit = outside_verts->begin();
00262 vit != outside_verts->end(); ++vit)
00263 {
00264 vtol_vertex_2d_sptr new_v =
00265 btol_vertex_algs::transform((*vit)->cast_to_vertex_2d(), T);
00266 if (!new_v)
00267 return out;
00268 trans_outside_verts.push_back(new_v->cast_to_vertex());
00269 }
00270 delete outside_verts;
00271
00272 vcl_vector<vtol_one_chain_sptr>* hole_chains = face->get_hole_cycles();
00273 vcl_vector<vcl_vector<vtol_vertex_sptr> > trans_hole_verts;
00274 for (vcl_vector<vtol_one_chain_sptr>::iterator cit = hole_chains->begin();
00275 cit != hole_chains->end(); cit++)
00276 {
00277 vcl_vector<vtol_vertex_sptr> hole_verts, t_hole_verts;
00278 if (!properly_ordered_verts(*cit, hole_verts))
00279 return out;
00280 for (vcl_vector<vtol_vertex_sptr>::iterator vit = hole_verts.begin();
00281 vit != hole_verts.end(); ++vit)
00282 {
00283 vtol_vertex_2d_sptr v = (*vit)->cast_to_vertex_2d();
00284 vtol_vertex_2d_sptr new_v =
00285 btol_vertex_algs::transform(v, T);
00286 if (!new_v)
00287 return out;
00288 t_hole_verts.push_back(new_v->cast_to_vertex());
00289 }
00290 trans_hole_verts.push_back(t_hole_verts);
00291 }
00292 delete hole_chains;
00293
00294
00295 vcl_vector<vtol_one_chain_sptr> new_chains;
00296 new_chains.push_back(btol_face_algs::one_chain(trans_outside_verts));
00297 for (vcl_vector<vcl_vector<vtol_vertex_sptr> >::iterator vts =
00298 trans_hole_verts.begin(); vts != trans_hole_verts.end(); ++vts)
00299 new_chains.push_back(btol_face_algs::one_chain(*vts));
00300
00301
00302 return new vtol_face_2d(new_chains);
00303 }
00304
00305
00306
00307
00308 bool btol_face_algs::vsol_to_vtol(vsol_polygon_2d_sptr const & poly,
00309 vtol_face_2d_sptr& face)
00310 {
00311 if (!poly)
00312 return false;
00313 int n_verts = poly->size();
00314 if (!n_verts)
00315 return false;
00316 vcl_vector<vtol_vertex_sptr> verts;
00317 for (int i = 0; i<n_verts; i++)
00318 {
00319 vsol_point_2d_sptr p = poly->vertex(i);
00320 vtol_vertex_sptr v = (new vtol_vertex_2d(p->x(), p->y()))->cast_to_vertex();
00321 verts.push_back(v);
00322 }
00323 face = new vtol_face_2d(verts);
00324 return true;
00325 }