- IFC: use smart pointers to keep STEP-SELECT entities in the converted output data structures. This allows us to free the original parameter tuples early as ownership of their members can be transferred. This cuts down memory overhead to 8x (assuming a typical x64 builds) and reduces loading time on average by ~5% as measured on my system.
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1019 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
0db3f8b3f4
commit
1e2dd3eefc
|
@ -327,7 +327,7 @@ void ProcessSpatialStructures(ConversionData& conv);
|
|||
aiNode* ProcessSpatialStructure(aiNode* parent, const IFC::IfcProduct& el ,ConversionData& conv);
|
||||
void ProcessProductRepresentation(const IFC::IfcProduct& el, aiNode* nd, ConversionData& conv);
|
||||
void MakeTreeRelative(ConversionData& conv);
|
||||
void ConvertUnit(const EXPRESS::DataType* dt,ConversionData& conv);
|
||||
void ConvertUnit(const EXPRESS::DataType& dt,ConversionData& conv);
|
||||
void ProcessSweptAreaSolid(const IFC::IfcSweptAreaSolid& swept, TempMesh& meshout, ConversionData& conv);
|
||||
|
||||
} // anon
|
||||
|
@ -560,7 +560,7 @@ void ConvertUnit(const IFC::IfcNamedUnit& unit,ConversionData& conv)
|
|||
if(convu->UnitType == "PLANEANGLEUNIT") {
|
||||
try {
|
||||
conv.angle_scale = convu->ConversionFactor->ValueComponent->To<EXPRESS::REAL>();
|
||||
ConvertUnit(convu->ConversionFactor->UnitComponent,conv);
|
||||
ConvertUnit(*convu->ConversionFactor->UnitComponent,conv);
|
||||
IFCImporter::LogDebug("got units used for angles");
|
||||
}
|
||||
catch(std::bad_cast&) {
|
||||
|
@ -571,10 +571,10 @@ void ConvertUnit(const IFC::IfcNamedUnit& unit,ConversionData& conv)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertUnit(const EXPRESS::DataType* dt,ConversionData& conv)
|
||||
void ConvertUnit(const EXPRESS::DataType& dt,ConversionData& conv)
|
||||
{
|
||||
try {
|
||||
const EXPRESS::ENTITY& e = dt->To<IFC::ENTITY>();
|
||||
const EXPRESS::ENTITY& e = dt.To<IFC::ENTITY>();
|
||||
|
||||
const IFC::IfcNamedUnit& unit = e.ResolveSelect<IFC::IfcNamedUnit>(conv.db);
|
||||
if(unit.UnitType != "LENGTHUNIT" && unit.UnitType != "PLANEANGLEUNIT") {
|
||||
|
@ -594,7 +594,7 @@ void SetUnits(ConversionData& conv)
|
|||
{
|
||||
// see if we can determine the coordinate space used to express.
|
||||
for(size_t i = 0; i < conv.proj.UnitsInContext->Units.size(); ++i ) {
|
||||
ConvertUnit(conv.proj.UnitsInContext->Units[i],conv);
|
||||
ConvertUnit(*conv.proj.UnitsInContext->Units[i],conv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -608,9 +608,9 @@ void ConvertColor(aiColor4D& out, const IFC::IfcColourRgb& in)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertColor(aiColor4D& out, const IFC::IfcColourOrFactor* in,ConversionData& conv,const aiColor4D* base)
|
||||
void ConvertColor(aiColor4D& out, const IFC::IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base)
|
||||
{
|
||||
if (const EXPRESS::REAL* const r = in->ToPtr<EXPRESS::REAL>()) {
|
||||
if (const EXPRESS::REAL* const r = in.ToPtr<EXPRESS::REAL>()) {
|
||||
out.r = out.g = out.b = *r;
|
||||
if(base) {
|
||||
out.r *= base->r;
|
||||
|
@ -620,7 +620,7 @@ void ConvertColor(aiColor4D& out, const IFC::IfcColourOrFactor* in,ConversionDat
|
|||
}
|
||||
else out.a = 1.0;
|
||||
}
|
||||
else if (const IFC::IfcColourRgb* const rgb = in->ResolveSelectPtr<IFC::IfcColourRgb>(conv.db)) {
|
||||
else if (const IFC::IfcColourRgb* const rgb = in.ResolveSelectPtr<IFC::IfcColourRgb>(conv.db)) {
|
||||
ConvertColor(out,*rgb);
|
||||
}
|
||||
else {
|
||||
|
@ -2108,7 +2108,7 @@ void FillMaterial(MaterialHelper* mat,const IFC::IfcSurfaceStyle* surf,Conversio
|
|||
mat->AddProperty(&name,AI_MATKEY_NAME);
|
||||
|
||||
// now see which kinds of surface information are present
|
||||
BOOST_FOREACH(const IFC::IfcSurfaceStyleElementSelect* sel2, surf->Styles) {
|
||||
BOOST_FOREACH(boost::shared_ptr< const IFC::IfcSurfaceStyleElementSelect > sel2, surf->Styles) {
|
||||
if (const IFC::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleShading>(conv.db)) {
|
||||
aiColor4D col_base,col;
|
||||
|
||||
|
@ -2123,22 +2123,22 @@ void FillMaterial(MaterialHelper* mat,const IFC::IfcSurfaceStyle* surf,Conversio
|
|||
}
|
||||
|
||||
if (ren->DiffuseColour) {
|
||||
ConvertColor(col, ren->DiffuseColour.Get(),conv,&col_base);
|
||||
ConvertColor(col, *ren->DiffuseColour.Get(),conv,&col_base);
|
||||
mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE);
|
||||
}
|
||||
|
||||
if (ren->SpecularColour) {
|
||||
ConvertColor(col, ren->SpecularColour.Get(),conv,&col_base);
|
||||
ConvertColor(col, *ren->SpecularColour.Get(),conv,&col_base);
|
||||
mat->AddProperty(&col,1, AI_MATKEY_COLOR_SPECULAR);
|
||||
}
|
||||
|
||||
if (ren->TransmissionColour) {
|
||||
ConvertColor(col, ren->TransmissionColour.Get(),conv,&col_base);
|
||||
ConvertColor(col, *ren->TransmissionColour.Get(),conv,&col_base);
|
||||
mat->AddProperty(&col,1, AI_MATKEY_COLOR_TRANSPARENT);
|
||||
}
|
||||
|
||||
if (ren->ReflectionColour) {
|
||||
ConvertColor(col, ren->ReflectionColour.Get(),conv,&col_base);
|
||||
ConvertColor(col, *ren->ReflectionColour.Get(),conv,&col_base);
|
||||
mat->AddProperty(&col,1, AI_MATKEY_COLOR_REFLECTIVE);
|
||||
}
|
||||
|
||||
|
@ -2185,7 +2185,7 @@ unsigned int ProcessMaterials(const IFC::IfcRepresentationItem& item, Conversion
|
|||
for(;range.first != range.second; ++range.first) {
|
||||
if(const IFC::IfcStyledItem* const styled = conv.db.GetObject((*range.first).second)->ToPtr<IFC::IfcStyledItem>()) {
|
||||
BOOST_FOREACH(const IFC::IfcPresentationStyleAssignment& as, styled->Styles) {
|
||||
BOOST_FOREACH(const IFC::IfcPresentationStyleSelect* sel, as.Styles) {
|
||||
BOOST_FOREACH(boost::shared_ptr<const IFC::IfcPresentationStyleSelect> sel, as.Styles) {
|
||||
|
||||
if (const IFC::IfcSurfaceStyle* const surf = sel->ResolveSelectPtr<IFC::IfcSurfaceStyle>(conv.db)) {
|
||||
const std::string side = static_cast<std::string>(surf->Side);
|
||||
|
@ -2237,7 +2237,7 @@ bool ProcessGeometricItem(const IFC::IfcGeometricRepresentationItem& geo, std::v
|
|||
{
|
||||
TempMesh meshtmp;
|
||||
if(const IFC::IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<IFC::IfcShellBasedSurfaceModel>()) {
|
||||
BOOST_FOREACH(const IFC::IfcShell* shell,shellmod->SbsmBoundary) {
|
||||
BOOST_FOREACH(boost::shared_ptr<const IFC::IfcShell> shell,shellmod->SbsmBoundary) {
|
||||
try {
|
||||
const EXPRESS::ENTITY& e = shell->To<IFC::ENTITY>();
|
||||
const IFC::IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<IFC::IfcConnectedFaceSet>();
|
||||
|
@ -2589,6 +2589,9 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IFC::IfcProduct& el, Conve
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessSpatialStructures(ConversionData& conv)
|
||||
{
|
||||
// XXX add support for multiple sites (i.e. IfcSpatialStructureElements with composition == COMPLEX)
|
||||
|
||||
|
||||
// process all products in the file. it is reasonable to assume that a
|
||||
// file that is relevant for us contains at least a site or a building.
|
||||
const STEP::DB::ObjectMapByType& map = conv.db.GetObjectsByType();
|
||||
|
@ -2635,6 +2638,17 @@ void ProcessSpatialStructures(ConversionData& conv)
|
|||
}
|
||||
|
||||
|
||||
IFCImporter::LogWarn("failed to determine primary site element, taking the first IfcSite");
|
||||
BOOST_FOREACH(const STEP::LazyObject* lz, *range) {
|
||||
const IFC::IfcSpatialStructureElement* const prod = lz->ToPtr<IFC::IfcSpatialStructureElement>();
|
||||
if(!prod) {
|
||||
continue;
|
||||
}
|
||||
|
||||
conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
IFCImporter::ThrowException("failed to determine primary site element");
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3113,7 +3113,7 @@ namespace IFC {
|
|||
|
||||
// C++ wrapper for IfcRelContainedInSpatialStructure
|
||||
struct IfcRelContainedInSpatialStructure : IfcRelConnects, ObjectHelper<IfcRelContainedInSpatialStructure,2> { IfcRelContainedInSpatialStructure() : Object("IfcRelContainedInSpatialStructure") {}
|
||||
ListOf< Lazy< IfcProduct >, 0, 0 > RelatedElements;
|
||||
ListOf< Lazy< IfcProduct >, 1, 0 > RelatedElements;
|
||||
Lazy< IfcSpatialStructureElement > RelatingStructure;
|
||||
};
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ namespace STEP {
|
|||
{
|
||||
public:
|
||||
|
||||
typedef const DataType* Out;
|
||||
typedef boost::shared_ptr<const DataType> Out;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -326,18 +326,10 @@ namespace STEP {
|
|||
// -------------------------------------------------------------------------------
|
||||
class LIST : public DataType
|
||||
{
|
||||
public:
|
||||
|
||||
~LIST() {
|
||||
BOOST_FOREACH(const DataType* dt, members) {
|
||||
delete dt;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// access a particular list index, throw std::range_error for wrong indices
|
||||
const DataType* operator[] (size_t index) const {
|
||||
boost::shared_ptr<const DataType> operator[] (size_t index) const {
|
||||
return members[index];
|
||||
}
|
||||
|
||||
|
@ -354,8 +346,7 @@ namespace STEP {
|
|||
|
||||
|
||||
private:
|
||||
// no smart pointer type to avoid any overhead
|
||||
typedef std::vector< const DataType* > MemberList;
|
||||
typedef std::vector< boost::shared_ptr<const DataType> > MemberList;
|
||||
MemberList members;
|
||||
};
|
||||
|
||||
|
@ -735,14 +726,14 @@ namespace STEP {
|
|||
typedef EXPRESS::ENTITY Type;
|
||||
};
|
||||
|
||||
template <> struct PickBaseType<EXPRESS::DataType*>;
|
||||
template <> struct PickBaseType< boost::shared_ptr< const EXPRESS::DataType > >;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct InternGenericConvert {
|
||||
void operator()(T& out, const EXPRESS::DataType& in, const STEP::DB& db) {
|
||||
void operator()(T& out, boost::shared_ptr< const EXPRESS::DataType >& in, const STEP::DB& db) {
|
||||
try{
|
||||
out = dynamic_cast< const typename PickBaseType<T>::Type& > ( in );
|
||||
out = dynamic_cast< const typename PickBaseType<T>::Type& > ( *in );
|
||||
}
|
||||
catch(std::bad_cast&) {
|
||||
throw TypeError("type error reading literal field");
|
||||
|
@ -751,15 +742,15 @@ namespace STEP {
|
|||
};
|
||||
|
||||
template <>
|
||||
struct InternGenericConvert<const EXPRESS::DataType*> {
|
||||
void operator()(const EXPRESS::DataType*& out, const EXPRESS::DataType& in, const STEP::DB& db) {
|
||||
out = ∈
|
||||
struct InternGenericConvert< boost::shared_ptr< const EXPRESS::DataType > > {
|
||||
void operator()(boost::shared_ptr< const EXPRESS::DataType >& out, boost::shared_ptr< const EXPRESS::DataType >& in, const STEP::DB& db) {
|
||||
out = in;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct InternGenericConvert< Maybe<T> > {
|
||||
void operator()(Maybe<T>& out, const EXPRESS::DataType& in, const STEP::DB& db) {
|
||||
void operator()(Maybe<T>& out, boost::shared_ptr< const EXPRESS::DataType >& in, const STEP::DB& db) {
|
||||
GenericConvert((T&)out,in,db);
|
||||
out.flag_valid();
|
||||
}
|
||||
|
@ -767,20 +758,19 @@ namespace STEP {
|
|||
|
||||
template <typename T,uint64_t min_cnt, uint64_t max_cnt>
|
||||
struct InternGenericConvertList {
|
||||
void operator()(ListOf<T, min_cnt, max_cnt>& out, const EXPRESS::DataType& inp_base, const STEP::DB& db) {
|
||||
void operator()(ListOf<T, min_cnt, max_cnt>& out, boost::shared_ptr< const EXPRESS::DataType >& inp_base, const STEP::DB& db) {
|
||||
|
||||
const EXPRESS::LIST* inp = dynamic_cast<const EXPRESS::LIST*>(&inp_base);
|
||||
const EXPRESS::LIST* inp = dynamic_cast<const EXPRESS::LIST*>(inp_base.get());
|
||||
if (!inp) {
|
||||
throw TypeError("type error reading aggregate");
|
||||
}
|
||||
|
||||
// XXX is this really how the EXPRESS notation ([?:3],[1:3]) .. works?
|
||||
// too many is warning, too few is critical error because the user won't validate this
|
||||
// XXX is this really how the EXPRESS notation ([?:3],[1:3]) is intended?
|
||||
if (max_cnt && inp->GetSize() > max_cnt) {
|
||||
DefaultLogger::get()->warn("too many aggregate elements");
|
||||
}
|
||||
else if (inp->GetSize() < min_cnt) {
|
||||
throw TypeError("too few aggregate elements");
|
||||
DefaultLogger::get()->warn("too few aggregate elements");
|
||||
}
|
||||
|
||||
out.reserve(inp->GetSize());
|
||||
|
@ -788,7 +778,7 @@ namespace STEP {
|
|||
|
||||
out.push_back( typename ListOf<T, min_cnt, max_cnt>::OutScalar() );
|
||||
try{
|
||||
GenericConvert(out.back(),*(*inp)[i], db);
|
||||
GenericConvert(out.back(),(*inp)[i], db);
|
||||
}
|
||||
catch(const TypeError& t) {
|
||||
throw TypeError(t.what() +std::string(" of aggregate"));
|
||||
|
@ -799,8 +789,8 @@ namespace STEP {
|
|||
|
||||
template <typename T>
|
||||
struct InternGenericConvert< Lazy<T> > {
|
||||
void operator()(Lazy<T>& out, const EXPRESS::DataType& in_base, const STEP::DB& db) {
|
||||
const EXPRESS::ENTITY* in = dynamic_cast<const EXPRESS::ENTITY*>(&in_base);
|
||||
void operator()(Lazy<T>& out, boost::shared_ptr< const EXPRESS::DataType >& in_base, const STEP::DB& db) {
|
||||
const EXPRESS::ENTITY* in = dynamic_cast<const EXPRESS::ENTITY*>(in_base.get());
|
||||
if (!in) {
|
||||
throw TypeError("type error reading entity");
|
||||
}
|
||||
|
@ -809,12 +799,12 @@ namespace STEP {
|
|||
};
|
||||
|
||||
template <typename T1>
|
||||
inline void GenericConvert(T1& a, const EXPRESS::DataType& b, const STEP::DB& db) {
|
||||
inline void GenericConvert(T1& a, boost::shared_ptr< const EXPRESS::DataType >& b, const STEP::DB& db) {
|
||||
return InternGenericConvert<T1>()(a,b,db);
|
||||
}
|
||||
|
||||
template <typename T1,uint64_t N1, uint64_t N2>
|
||||
inline void GenericConvert(ListOf<T1,N1,N2>& a, const EXPRESS::DataType& b, const STEP::DB& db) {
|
||||
inline void GenericConvert(ListOf<T1,N1,N2>& a, boost::shared_ptr< const EXPRESS::DataType >& b, const STEP::DB& db) {
|
||||
return InternGenericConvertList<T1,N1,N2>()(a,b,db);
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ STEP::DB* STEP::ReadFileHeader(boost::shared_ptr<IOStream> stream)
|
|||
// two nested lists.
|
||||
const EXPRESS::LIST* list = dynamic_cast<const EXPRESS::LIST*>(schema.get());
|
||||
if (list && list->GetSize()) {
|
||||
list = dynamic_cast<const EXPRESS::LIST*>( (*list)[0] );
|
||||
list = dynamic_cast<const EXPRESS::LIST*>( (*list)[0].get() );
|
||||
if (!list) {
|
||||
throw STEP::SyntaxError("expected FILE_SCHEMA to be a list",line);
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ STEP::DB* STEP::ReadFileHeader(boost::shared_ptr<IOStream> stream)
|
|||
DefaultLogger::get()->warn(AddLineNumber("multiple schemas currently not supported",line));
|
||||
}
|
||||
const EXPRESS::STRING* string;
|
||||
if (!list->GetSize() || !(string=dynamic_cast<const EXPRESS::STRING*>( (*list)[0] ))) {
|
||||
if (!list->GetSize() || !(string=dynamic_cast<const EXPRESS::STRING*>( (*list)[0].get() ))) {
|
||||
throw STEP::SyntaxError("expected FILE_SCHEMA to contain a single string literal",line);
|
||||
}
|
||||
head.fileSchema = *string;
|
||||
|
@ -390,7 +390,7 @@ const EXPRESS::LIST* EXPRESS::LIST::Parse(const char*& inout,uint64_t line, cons
|
|||
break;
|
||||
}
|
||||
|
||||
members.push_back( EXPRESS::DataType::Parse(cur,line,schema));
|
||||
members.push_back( boost::shared_ptr<const EXPRESS::DataType> (EXPRESS::DataType::Parse(cur,line,schema)));
|
||||
SkipSpaces(cur,&cur);
|
||||
|
||||
if (*cur != ',') {
|
||||
|
@ -479,7 +479,7 @@ void STEP::LazyObject::LazyInit() const
|
|||
// store the original id in the object instance
|
||||
obj->SetID(id);
|
||||
|
||||
//delete conv_args;
|
||||
//conv_args = NULL;
|
||||
delete conv_args;
|
||||
conv_args = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ template_converter_prologue_a = '\tsize_t base = GenericFill(db,params,static_ca
|
|||
template_converter_prologue_b = '\tsize_t base = 0;\n'
|
||||
template_converter_check_argcnt = '\tif (params.GetSize() < {max_arg}) {{ throw STEP::TypeError("expected {max_arg} arguments to {name}"); }}'
|
||||
template_converter_code_per_field = r""" do {{ // convert the '{fieldname}' argument
|
||||
const DataType* arg = params[base++];{handle_unset}{convert}
|
||||
boost::shared_ptr<const DataType> arg = params[base++];{handle_unset}{convert}
|
||||
}} while(0);
|
||||
"""
|
||||
template_allow_optional = r"""
|
||||
|
@ -87,7 +87,7 @@ template_allow_optional = r"""
|
|||
template_allow_derived = r"""
|
||||
if (dynamic_cast<const ISDERIVED*>(&*arg)) {{ in->ObjectHelper<Assimp::IFC::{type},{argcnt}>::aux_is_derived[{argnum}]=true; break; }}"""
|
||||
template_convert_single = r"""
|
||||
try {{ GenericConvert( in->{name}, *arg, db ); break; }}
|
||||
try {{ GenericConvert( in->{name}, arg, db ); break; }}
|
||||
catch (const TypeError& t) {{ throw TypeError(t.what() + std::string(" - expected argument {argnum} to {classname} to be a `{full_type}`")); }}"""
|
||||
|
||||
template_converter_ommitted = '// this data structure is not used yet, so there is no code generated to fill its members\n'
|
||||
|
|
Loading…
Reference in New Issue