From 727bc11e9d69733bc76e047716e7d31064795ae0 Mon Sep 17 00:00:00 2001 From: Amorilia <amorilia@users.sourceforge.net> Date: Wed, 8 Feb 2006 17:41:32 +0000 Subject: [PATCH] * added GetParents() to get all parents of a block * fixed skeleton root calculation --- NIF_Blocks.cpp | 7 +++++++ NIF_Blocks.h | 1 + nif_attrs.h | 44 ++++++++++++++++++++++++++++++++++---------- niflib.h | 20 ++++++++++++++++++++ 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/NIF_Blocks.cpp b/NIF_Blocks.cpp index d11239bb..bd8d26f9 100644 --- a/NIF_Blocks.cpp +++ b/NIF_Blocks.cpp @@ -172,6 +172,13 @@ blk_ref ABlock::GetParent() const { return blk_ref(-1); } +list<blk_ref> ABlock::GetParents() const { + list<blk_ref> parents; + for (vector<IBlock *>::const_iterator it = _parents.begin(); it != _parents.end(); it++ ) + parents.push_back(blk_ref(*it)); + return parents; +} + void ABlock::Read( istream& in, unsigned int version ) { //Read Attributes diff --git a/NIF_Blocks.h b/NIF_Blocks.h index f42cdb74..5111fc9b 100644 --- a/NIF_Blocks.h +++ b/NIF_Blocks.h @@ -104,6 +104,7 @@ public: //Links blk_ref GetParent() const; + list<blk_ref> GetParents() const; list<blk_ref> GetLinks() const; //Reference Counting diff --git a/nif_attrs.h b/nif_attrs.h index f8bd7999..ec361eec 100644 --- a/nif_attrs.h +++ b/nif_attrs.h @@ -1218,21 +1218,45 @@ public: // We want to get the closest common ancestor between the _owner and the bones // So start with a list of ancestors of the first bone (this is just a random choice) blk_ref block = bones[0]; - blk_ref par = block->GetParent(); + list<blk_ref> pars = block->GetParents(); + blk_ref nodepar = blk_ref(); + for ( list<blk_ref>::const_iterator it = pars.begin(); it != pars.end(); it++ ) + if ( (*it)->GetBlockType() == "NiNode" ) { + nodepar = *it; + break; + }; list<blk_ref> bone_pars; - while ( par.is_null() == false ) { - bone_pars.push_front(par); - par = par->GetParent(); + while ( nodepar.is_null() == false ) { + bone_pars.push_front(nodepar); + pars = nodepar->GetParents(); + nodepar = blk_ref(); + for ( list<blk_ref>::const_iterator it = pars.begin(); it != pars.end(); it++ ) + if ( (*it)->GetBlockType() == "NiNode" ) { + nodepar = *it; + break; + }; }; // Now do the same with the owner. - block = _owner; - par = block->GetParent(); + block = _owner->GetParent(); // TriShape + pars = block->GetParents(); + nodepar = blk_ref(); + for ( list<blk_ref>::const_iterator it = pars.begin(); it != pars.end(); it++ ) + if ( (*it)->GetBlockType() == "NiNode" ) { + nodepar = *it; + break; + }; list<blk_ref> owner_pars; - while ( par.is_null() == false ) { - owner_pars.push_front(par); - par = par->GetParent(); + while ( nodepar.is_null() == false ) { + owner_pars.push_front(nodepar); + pars = nodepar->GetParents(); + nodepar = blk_ref(); + for ( list<blk_ref>::const_iterator it = pars.begin(); it != pars.end(); it++ ) + if ( (*it)->GetBlockType() == "NiNode" ) { + nodepar = *it; + break; + }; }; - // Now find closest common ancestor. + // Now find closest common NiNode ancestor. if ( owner_pars.empty() || bone_pars.empty() ) throw runtime_error("Skinning instance has no common parent with the bones it refers to (invalid NIF file?). Cannot set skeleton root."); blk_ref skelroot; diff --git a/niflib.h b/niflib.h index 74bc8687..db1fb686 100644 --- a/niflib.h +++ b/niflib.h @@ -1310,6 +1310,26 @@ public: */ virtual blk_ref GetParent() const = 0; + /*! + * Used to retrieve all parents that are linked to this block. + * \return A list of block references to the parents that are linked to this block. + * + * <b>Example:</b> + * \code + * blk_ref my_block = ReadNifTree("test_in.nif"); + * list<blk_ref> parents = my_block->GetParents(); + * \endcode + * + * <b>In Python:</b> + * \code + * my_block = ReadNifTree("test_in.nif") + * parents = block.GetParents() + * \endcode + * + * \sa IAttr::Set(blk_ref const &), IAttr::AddLink, IAttr::AddLinks, IAttr::RemoveLinks, IAttr::ClearLinks + */ + virtual list<blk_ref> GetParents() const = 0; + /*! * Summarizes the information contained in this block in English. * \return A string containing a summary of the information within the block in English. This is the function that Niflyze calls to generate its analysis, so the output is the same. -- GitLab