Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

definer.C

Go to the documentation of this file.
00001 #include "mlib/vec3.H" // XXX - Probably doesn't need to be included here.
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 // DEFINER's can be used to define a GEOM's original geometry, CSG geometry, or
00012 // xform.  For example, if GEOM A is grouped to (on top of) GEOM B, A's
00013 // xf_definer (xform definer) has B as an input, and B has A as an xform output.
00014 // When B's xform changes, GEOM::_tsort is used to find the GEOM's that need
00015 // updating and to make sure that they are done in correct order.
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 /* ---- DEFINER functions that access GEOM methods ----- */
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 // For all of our inputs, remove the other end of each connection (the outputs)
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 // Add a GEOM as input to our DEFINER, but also make sure that the GEOM's output
00055 // is updated as well
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 // Remove a GEOM as input to our DEFINER, but also make sure that the GEOM's
00069 // output is removed as well
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 // format() - from DATA_ITEM, formats GEOM to a STDdstream
00098 // (usually to a file or to a network connection)
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 // decode() - from DATA_ITEM, decodes GEOM from a STDdstream
00109 // (usually from a file or from a network connection)
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 /* ---- DEFINER sub-classes  ----- */
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 // format() - from DATA_ITEM, formats GEOM to a STDdstream
00153 // (usually to a file or to a network connection)
00154 STDdstream &
00155 CSG_DEF::format(STDdstream &ds) const
00156 {
00157    ds << class_name();
00158    // Don't need to send _data_mask - always CSG_BODY
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 // decode() - from DATA_ITEM, decodes GEOM from a STDdstream
00167 // (usually from a file or from a network connection)
00168 STDdstream &
00169 CSG_DEF::decode(STDdstream &ds)
00170 {
00171    int i;
00172    // Now we remove all inputs and then add the new inputs
00173    // XXX - should only make minimal number of removes/adds
00174    // XXX - should not have to recode this here & in DEFINER
00175    for (i = _cutters.num() - 1; i>= 0; i--) {
00176       rem_input(_cutters[i]._geom);
00177    }
00178 
00179    // Class name has already been read off
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; // No original body upon which to do CSG
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             // If CSG error, exit
00230             if (!b) i = _cutters.num();
00231          }
00232       }
00233 
00234       // Update only if we have a valid CSG
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 }

Generated on Mon Sep 18 11:39:29 2006 for jot by  doxygen 1.4.4