00001 #include "mlib/vec3.H"
00002 #include "geom/geom.H"
00003 #include "geom/world.H"
00004 #include "geom/body.H"
00005 #include "std/config.H"
00006
00007
00008 using mlib::Wtransf;
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 static int dm=DECODER_ADD(DEFINER);
00019 static int cm=DECODER_ADD(CSG_DEF);
00020
00021 TAGlist *DEFINER::_def_tags;
00022
00023
00024
00025 DEFINER::DEFINER(): _out_mask(XFORM)
00026 {
00027 }
00028
00029 CTAGlist &
00030 DEFINER::tags() const
00031 {
00032 if (!_def_tags) {
00033 _def_tags = new TAGlist;
00034 *_def_tags += new TAG_meth<DEFINER>("out_mask",
00035 &DEFINER::put_outmask,&DEFINER::get_outmask, 0);
00036 *_def_tags += new TAG_meth<DEFINER>("inputs",
00037 &DEFINER::put_inputs, &DEFINER::get_inputs, 1);
00038 }
00039 return *_def_tags;
00040 }
00041
00042
00043
00044
00045 DEFINER::~DEFINER()
00046 {
00047 for (int i = _inputs.num()-1; i>=0; i--) {
00048 _inputs[i]->rem_xf_output (this);
00049 _inputs[i]->rem_csg_output(this);
00050 }
00051 }
00052
00053
00054
00055
00056
00057 void
00058 DEFINER::add_input(
00059 GEOM *o
00060 )
00061 {
00062 _inputs += o;
00063 o->data_xform() += this;
00064 o->data_orig_body() += this;
00065 }
00066
00067
00068
00069
00070
00071 void
00072 DEFINER::rem_input(
00073 GEOM *o
00074 )
00075 {
00076 _inputs -= o;
00077 o->data_xform() -= this;
00078 o->data_orig_body() -= this;
00079 }
00080
00081 void
00082 DEFINER::visit(
00083 MOD &mod
00084 )
00085 {
00086 int i;
00087 if (_ob_delt.id().current())
00088 for (i = 0; i < _outputs.num(); i++)
00089 geom(i)->write_orig_body(geom(i)->orig_body(), mod);
00090 if (_xf_delt.id().current())
00091 for (i = 0; i < _outputs.num(); i++) {
00092 Wtransf xf_delt(xf_delta());
00093 geom(i)->write_xform(xf_delt * geom(i)->xform(), xf_delt, mod);
00094 }
00095 }
00096
00097
00098
00099 void
00100 DEFINER::put_inputs(TAGformat &d) const
00101 {
00102 d.id();
00103 for (int i = 0; i < _inputs.num(); i++)
00104 *d << _inputs[i]->name();
00105 d.end_id();
00106 }
00107
00108
00109
00110 void
00111 DEFINER::get_inputs(TAGformat &d)
00112 {
00113 for (int k = _inputs.num() - 1; k>= 0; k--)
00114 rem_input(_inputs[k]);
00115
00116 str_ptr str;
00117 GEOMptr o;
00118 for (int i = 0; i < 1000; i++) {
00119 if (!d)
00120 break;
00121 *d >> str;
00122 if (o = WORLD::lookup(str))
00123 add_input(&*o);
00124 else
00125 cerr << "DEFINER::decode- unknown object '" << str
00126 << "' ref'd by " << geom()->name() << endl;
00127 }
00128 }
00129
00130
00131 void
00132 COMPOSITE_DEF::visit(
00133 MOD &mod
00134 )
00135 {
00136 if (_inputs.num() > 0) {
00137 int all_equal = 1;
00138 int any_body_mod = 0;
00139 MOD cmp(_inputs[0]->data_xform().id());
00140
00141 int i;
00142 for (i = 1; i < _inputs.num() && all_equal; i++)
00143 all_equal = (cmp == _inputs[i]->data_xform().id());
00144 for (i = 0; i < _inputs.num() && !any_body_mod; i++)
00145 any_body_mod = _inputs[i]->data_orig_body().id().current();
00146 if (all_equal && !_inputs[0]->data_xform().id().current())
00147 all_equal = 0;
00148 inputs_changed(all_equal, any_body_mod, mod);
00149 }
00150 }
00151
00152
00153
00154 STDdstream &
00155 CSG_DEF::format(STDdstream &ds) const
00156 {
00157 ds << class_name();
00158
00159 ds << _cutters.num();
00160 for (int i = 0; i < _cutters.num(); i++) {
00161 ds << _cutters[i]._geom->name() << (int) _cutters[i]._op;
00162 }
00163 return ds;
00164 }
00165
00166
00167
00168 STDdstream &
00169 CSG_DEF::decode(STDdstream &ds)
00170 {
00171 int i;
00172
00173
00174
00175 for (i = _cutters.num() - 1; i>= 0; i--) {
00176 rem_input(_cutters[i]._geom);
00177 }
00178
00179
00180 static int print_errs = (Config::get_var_bool("PRINT_ERRS",false,true) != 0);
00181
00182 int num;
00183 ds >> num;
00184
00185 if (print_errs)
00186 cerr << "CSG_DEF::decode: (" << num << "):";
00187
00188 str_ptr str;
00189 GEOMptr o;
00190 int int_csgop;
00191 for (i = 0; i < num; i++) {
00192 ds >> str >> int_csgop;
00193 o = WORLD::lookup(str);
00194 if (print_errs) cerr << " " << str << " " << int_csgop;
00195 if (o) {
00196 add_input(&*o, (CSGop) int_csgop);
00197 } else {
00198 cerr << "CSG_DEF::decode- could not find "
00199 << str << " to csg" << endl;
00200 }
00201 }
00202 if (print_errs) cerr << endl;
00203 return ds;
00204 }
00205
00206 void
00207 CSG_DEF::compute_csg(
00208 MOD &mod,
00209 int
00210 )
00211 {
00212 if (_cutters.num()) {
00213 BODYptr orig_body(geom()->orig_body());
00214 if (!orig_body) return;
00215 BODYptr b(orig_body->body_copy());
00216 b->transform(geom()->xform(), mod);
00217 for (int i = 0; i < _cutters.num(); i++) {
00218 GEOMptr cutby(_cutters[i]._geom);
00219 if (cutby) {
00220 GEOM *cutter=(GEOM *)&*cutby;
00221 BODYptr p(((BODY *) &*cutter->csg_body())->body_copy());
00222 p->transform(cutter->xform(), mod);
00223 switch (_cutters[i]._op) {
00224 case CSG_NONE:
00225 brcase CSG_SUB : b = b->subtract(p);
00226 brcase CSG_INT : b = b->intersect(p);
00227 brcase CSG_ADD : b = b->combine(p);
00228 }
00229
00230 if (!b) i = _cutters.num();
00231 }
00232 }
00233
00234
00235 if (b != (BODYptr) 0) {
00236 b->transform(geom()->inv_xform(), mod);
00237 geom()->write_csg_body(b,mod);
00238 } else return;
00239 } else {
00240 geom()->reset_csg_body(mod);
00241 }
00242 CSGobs::notify_csg_obs(geom());
00243 }
00244
00245
00246 void
00247 CSG_DEF::inputs_changed(
00248 int all_equal,
00249 int any_body_mod,
00250 MOD &mod
00251 )
00252 {
00253 if (!all_equal || any_body_mod)
00254 compute_csg(mod);
00255 }