/*============================================================================
* du_part(ob) -- return part number of object `ob'
*/
int du_part(dt_Handle ob)
{
int partno;
dt_Handle parent;
/*** If not calculated. Note that partno will be zero if the property
hasn't been set ever or if it is set to zero. Either indicates that
we must generate the parts. ***/
partno = dt_integer(ob, 4, "part");
if (partno != 0) return (partno);
parent = dt_parent(ob);
if (fill_parts(parent) == 0)
return (0);
return (dt_integer(ob, 4, "part"));
}
/*============================================================================
* fill_parts(mol) -- fill part properties and return success
*/
static int fill_parts(dt_Handle mol)
{
dt_Handle obs, ob;
int npart = 1;
if ((TYP_MOLECULE != dt_type(mol)) &&
(TYP_REACTION != dt_type(mol))) return 0;
/*** Zap the parts for the atoms and bonds ***/
obs = dt_stream(mol, TYP_BOND);
while (NULL_OB != (ob = dt_next(obs)))
dt_setinteger(ob, 4, "part", 0);
dt_dealloc(obs);
obs = dt_stream(mol, TYP_ATOM);
while (NULL_OB != (ob = dt_next(obs)))
dt_setinteger(ob, 4, "part", 0);
/*** Loop over atoms, setting parts with a depth-first-search. ***/
dt_reset(obs);
while (NULL_OB != (ob = dt_next(obs)))
if (dt_integer(ob, 4, "part") == 0)
set_part_dfs(ob, npart++);
dt_dealloc(obs);
dt_setinteger(mol, 9, "partcount", npart - 1);
return (1);
}
/*============================================================================
* set_part_dfs(atom) -- set part of atom, and connected atoms, to npart
*/
static void set_part_dfs(dt_Handle atom, int npart)
{
dt_Handle bond, bonds, toatom;
dt_setinteger(atom, 4, "part", npart);
bonds = dt_stream(atom, TYP_BOND);
while (NULL_OB != (bond = dt_next(bonds)))
{
dt_setinteger(bond, 4, "part", npart);
toatom = dt_xatom(atom, bond);
if (dt_integer(toatom, 4, "part") == 0)
set_part_dfs(toatom, npart);
}
dt_dealloc(bonds);
return;
}