- IFC: Refactor source to simplify maintenance.
- IFC: rate all available representations by a simple ranking system and take the one that is easiest to load. This should avoid loading the same geometry twice. Also it might result in quality improvements when BRep geometry is avoided in favour of extrusion geometry. # IFC: Various bugfixes related to geometry loading. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1033 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
ffdb479411
commit
81ad224f84
|
@ -351,13 +351,18 @@ SET(BLENDER_SRCS
|
|||
BlenderModifier.h
|
||||
BlenderModifier.cpp
|
||||
)
|
||||
SOURCE_GROUP( BLENDEr FILES ${BLENDER_SRCS})
|
||||
SOURCE_GROUP( BLENDER FILES ${BLENDER_SRCS})
|
||||
|
||||
SET(IFC_SRCS
|
||||
IFCLoader.cpp
|
||||
IFCLoader.h
|
||||
IFCReaderGen.cpp
|
||||
IFCReaderGen.h
|
||||
IFCUtil.h
|
||||
IFCUtil.cpp
|
||||
IFCGeometry.cpp
|
||||
IFCMaterial.cpp
|
||||
IFCProfile.cpp
|
||||
STEPFile.h
|
||||
STEPFileReader.h
|
||||
STEPFileReader.cpp
|
||||
|
|
File diff suppressed because it is too large
Load Diff
2268
code/IFCLoader.cpp
2268
code/IFCLoader.cpp
File diff suppressed because it is too large
Load Diff
|
@ -114,12 +114,14 @@ public:
|
|||
: skipSpaceRepresentations()
|
||||
, skipCurveRepresentations()
|
||||
, useCustomTriangulation()
|
||||
, skipAnnotations()
|
||||
{}
|
||||
|
||||
|
||||
bool skipSpaceRepresentations;
|
||||
bool skipCurveRepresentations;
|
||||
bool useCustomTriangulation;
|
||||
bool skipAnnotations;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
Open Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2010, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file IFCMaterial.cpp
|
||||
* @brief Implementation of conversion routines to convert IFC materials to aiMaterial
|
||||
*/
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
#include "IFCUtil.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace IFC {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
int ConvertShadingMode(const std::string& name)
|
||||
{
|
||||
if (name == "BLINN") {
|
||||
return aiShadingMode_Blinn;
|
||||
}
|
||||
else if (name == "FLAT" || name == "NOTDEFINED") {
|
||||
return aiShadingMode_NoShading;
|
||||
}
|
||||
else if (name == "PHONG") {
|
||||
return aiShadingMode_Phong;
|
||||
}
|
||||
IFCImporter::LogWarn("shading mode "+name+" not recognized by Assimp, using Phong instead");
|
||||
return aiShadingMode_Phong;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void FillMaterial(MaterialHelper* mat,const IFC::IfcSurfaceStyle* surf,ConversionData& conv)
|
||||
{
|
||||
aiString name;
|
||||
name.Set((surf->Name? surf->Name.Get() : "IfcSurfaceStyle_Unnamed"));
|
||||
mat->AddProperty(&name,AI_MATKEY_NAME);
|
||||
|
||||
// now see which kinds of surface information are present
|
||||
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;
|
||||
|
||||
ConvertColor(col_base, shade->SurfaceColour);
|
||||
mat->AddProperty(&col_base,1, AI_MATKEY_COLOR_DIFFUSE);
|
||||
|
||||
if (const IFC::IfcSurfaceStyleRendering* ren = shade->ToPtr<IFC::IfcSurfaceStyleRendering>()) {
|
||||
|
||||
if (ren->Transparency) {
|
||||
const float t = 1.f-ren->Transparency.Get();
|
||||
mat->AddProperty(&t,1, AI_MATKEY_OPACITY);
|
||||
}
|
||||
|
||||
if (ren->DiffuseColour) {
|
||||
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);
|
||||
mat->AddProperty(&col,1, AI_MATKEY_COLOR_SPECULAR);
|
||||
}
|
||||
|
||||
if (ren->TransmissionColour) {
|
||||
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);
|
||||
mat->AddProperty(&col,1, AI_MATKEY_COLOR_REFLECTIVE);
|
||||
}
|
||||
|
||||
const int shading = (ren->SpecularHighlight && ren->SpecularColour)?ConvertShadingMode(ren->ReflectanceMethod):static_cast<int>(aiShadingMode_Gouraud);
|
||||
mat->AddProperty(&shading,1, AI_MATKEY_SHADING_MODEL);
|
||||
|
||||
if (ren->SpecularHighlight) {
|
||||
if(const EXPRESS::REAL* rt = ren->SpecularHighlight.Get()->ToPtr<EXPRESS::REAL>()) {
|
||||
// at this point we don't distinguish between the two distinct ways of
|
||||
// specifying highlight intensities. leave this to the user.
|
||||
const float e = *rt;
|
||||
mat->AddProperty(&e,1,AI_MATKEY_SHININESS);
|
||||
}
|
||||
else {
|
||||
IFCImporter::LogWarn("unexpected type error, SpecularHighlight should be a REAL");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (const IFC::IfcSurfaceStyleWithTextures* tex = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleWithTextures>(conv.db)) {
|
||||
// XXX
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned int ProcessMaterials(const IFC::IfcRepresentationItem& item, ConversionData& conv)
|
||||
{
|
||||
if (conv.materials.empty()) {
|
||||
aiString name;
|
||||
std::auto_ptr<MaterialHelper> mat(new MaterialHelper());
|
||||
|
||||
name.Set("<IFCDefault>");
|
||||
mat->AddProperty(&name,AI_MATKEY_NAME);
|
||||
|
||||
aiColor4D col = aiColor4D(0.6f,0.6f,0.6f,1.0f);
|
||||
mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE);
|
||||
|
||||
conv.materials.push_back(mat.release());
|
||||
}
|
||||
|
||||
STEP::DB::RefMapRange range = conv.db.GetRefs().equal_range(item.GetID());
|
||||
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(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);
|
||||
if (side != "BOTH") {
|
||||
IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: " + side);
|
||||
}
|
||||
|
||||
std::auto_ptr<MaterialHelper> mat(new MaterialHelper());
|
||||
|
||||
FillMaterial(mat.get(),surf,conv);
|
||||
|
||||
conv.materials.push_back(mat.release());
|
||||
return conv.materials.size()-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // ! IFC
|
||||
} // ! Assimp
|
||||
|
||||
#endif
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
Open Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2010, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file IFCProfile.cpp
|
||||
* @brief Read profile and curves entities from IFC files
|
||||
*/
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
#include "IFCUtil.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace IFC {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessPolyLine(const IfcPolyline& def, TempMesh& meshout, ConversionData& /*conv*/)
|
||||
{
|
||||
// this won't produce a valid mesh, it just spits out a list of vertices
|
||||
aiVector3D t;
|
||||
BOOST_FOREACH(const IfcCartesianPoint& cp, def.Points) {
|
||||
ConvertCartesianPoint(t,cp);
|
||||
meshout.verts.push_back(t);
|
||||
}
|
||||
meshout.vertcnt.push_back(meshout.verts.size());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv)
|
||||
{
|
||||
if(const IfcPolyline* poly = curve.ToPtr<IfcPolyline>()) {
|
||||
ProcessPolyLine(*poly,meshout,conv);
|
||||
}
|
||||
else {
|
||||
IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is " + curve.GetClassName());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessClosedProfile(const IfcArbitraryClosedProfileDef& def, TempMesh& meshout, ConversionData& conv)
|
||||
{
|
||||
ProcessCurve(def.OuterCurve,meshout,conv);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout, ConversionData& conv)
|
||||
{
|
||||
ProcessCurve(def.Curve,meshout,conv);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv)
|
||||
{
|
||||
if(const IfcRectangleProfileDef* const cprofile = def.ToPtr<IfcRectangleProfileDef>()) {
|
||||
const float x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
|
||||
|
||||
meshout.verts.reserve(meshout.verts.size()+4);
|
||||
meshout.verts.push_back( aiVector3D( x, y, 0.f ));
|
||||
meshout.verts.push_back( aiVector3D(-x, y, 0.f ));
|
||||
meshout.verts.push_back( aiVector3D(-x,-y, 0.f ));
|
||||
meshout.verts.push_back( aiVector3D( x,-y, 0.f ));
|
||||
meshout.vertcnt.push_back(4);
|
||||
}
|
||||
else if( const IfcCircleProfileDef* const circle = def.ToPtr<IfcCircleProfileDef>()) {
|
||||
if( const IfcCircleHollowProfileDef* const hollow = def.ToPtr<IfcCircleHollowProfileDef>()) {
|
||||
// TODO
|
||||
}
|
||||
const size_t segments = 32;
|
||||
const float delta = AI_MATH_TWO_PI_F/segments, radius = circle->Radius;
|
||||
|
||||
meshout.verts.reserve(segments);
|
||||
|
||||
float angle = 0.f;
|
||||
for(size_t i = 0; i < segments; ++i, angle += delta) {
|
||||
meshout.verts.push_back( aiVector3D( cos(angle)*radius, sin(angle)*radius, 0.f ));
|
||||
}
|
||||
|
||||
meshout.vertcnt.push_back(segments);
|
||||
}
|
||||
else {
|
||||
IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is " + def.GetClassName());
|
||||
return;
|
||||
}
|
||||
|
||||
aiMatrix4x4 trafo;
|
||||
ConvertAxisPlacement(trafo, *def.Position);
|
||||
meshout.Transform(trafo);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv)
|
||||
{
|
||||
if(const IfcArbitraryClosedProfileDef* const cprofile = prof.ToPtr<IfcArbitraryClosedProfileDef>()) {
|
||||
ProcessClosedProfile(*cprofile,meshout,conv);
|
||||
}
|
||||
else if(const IfcArbitraryOpenProfileDef* const copen = prof.ToPtr<IfcArbitraryOpenProfileDef>()) {
|
||||
ProcessOpenProfile(*copen,meshout,conv);
|
||||
}
|
||||
else if(const IfcParameterizedProfileDef* const cparam = prof.ToPtr<IfcParameterizedProfileDef>()) {
|
||||
ProcessParametrizedProfile(*cparam,meshout,conv);
|
||||
}
|
||||
else {
|
||||
IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is " + prof.GetClassName());
|
||||
return false;
|
||||
}
|
||||
meshout.RemoveAdjacentDuplicates();
|
||||
if (!meshout.vertcnt.size() || meshout.vertcnt.front() <= 1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // ! IFC
|
||||
} // ! Assimp
|
||||
|
||||
#endif
|
|
@ -0,0 +1,441 @@
|
|||
/*
|
||||
Open Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2010, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file IFCUtil.cpp
|
||||
* @brief Implementation of conversion routines for some common Ifc helper entities.
|
||||
*/
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
#include "IFCUtil.h"
|
||||
#include "ProcessHelper.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace IFC {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempOpening::Transform(const aiMatrix4x4& mat)
|
||||
{
|
||||
if(profileMesh) {
|
||||
profileMesh->Transform(mat);
|
||||
}
|
||||
extrusionDir *= aiMatrix3x3(mat);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiMesh* TempMesh::ToMesh()
|
||||
{
|
||||
ai_assert(verts.size() == std::accumulate(vertcnt.begin(),vertcnt.end(),0));
|
||||
|
||||
if (verts.empty()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::auto_ptr<aiMesh> mesh(new aiMesh());
|
||||
|
||||
// copy vertices
|
||||
mesh->mNumVertices = static_cast<unsigned int>(verts.size());
|
||||
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
|
||||
std::copy(verts.begin(),verts.end(),mesh->mVertices);
|
||||
|
||||
// and build up faces
|
||||
mesh->mNumFaces = static_cast<unsigned int>(vertcnt.size());
|
||||
mesh->mFaces = new aiFace[mesh->mNumFaces];
|
||||
|
||||
for(unsigned int i = 0,n=0, acc = 0; i < mesh->mNumFaces; ++n) {
|
||||
aiFace& f = mesh->mFaces[i];
|
||||
if (!vertcnt[n]) {
|
||||
--mesh->mNumFaces;
|
||||
continue;
|
||||
}
|
||||
|
||||
f.mNumIndices = vertcnt[n];
|
||||
f.mIndices = new unsigned int[f.mNumIndices];
|
||||
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||
f.mIndices[a] = acc++;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return mesh.release();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::Clear()
|
||||
{
|
||||
verts.clear();
|
||||
vertcnt.clear();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::Transform(const aiMatrix4x4& mat)
|
||||
{
|
||||
BOOST_FOREACH(aiVector3D& v, verts) {
|
||||
v *= mat;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
aiVector3D TempMesh::Center() const
|
||||
{
|
||||
return std::accumulate(verts.begin(),verts.end(),aiVector3D(0.f,0.f,0.f)) / static_cast<float>(verts.size());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::Append(const TempMesh& other)
|
||||
{
|
||||
verts.insert(verts.end(),other.verts.begin(),other.verts.end());
|
||||
vertcnt.insert(vertcnt.end(),other.vertcnt.begin(),other.vertcnt.end());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::RemoveAdjacentDuplicates()
|
||||
{
|
||||
|
||||
bool drop = false;
|
||||
std::vector<aiVector3D>::iterator base = verts.begin();
|
||||
BOOST_FOREACH(unsigned int& cnt, vertcnt) {
|
||||
if (cnt < 2){
|
||||
base += cnt;
|
||||
continue;
|
||||
}
|
||||
|
||||
aiVector3D vmin,vmax;
|
||||
ArrayBounds(&*base, cnt ,vmin,vmax);
|
||||
|
||||
|
||||
const float epsilon = (vmax-vmin).SquareLength() / 1e9f;
|
||||
//const float dotepsilon = 1e-9;
|
||||
|
||||
//// look for vertices that lie directly on the line between their predecessor and their
|
||||
//// successor and replace them with either of them.
|
||||
|
||||
//for(size_t i = 0; i < cnt; ++i) {
|
||||
// aiVector3D& v1 = *(base+i), &v0 = *(base+(i?i-1:cnt-1)), &v2 = *(base+(i+1)%cnt);
|
||||
// const aiVector3D& d0 = (v1-v0), &d1 = (v2-v1);
|
||||
// const float l0 = d0.SquareLength(), l1 = d1.SquareLength();
|
||||
// if (!l0 || !l1) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// const float d = (d0/sqrt(l0))*(d1/sqrt(l1));
|
||||
|
||||
// if ( d >= 1.f-dotepsilon ) {
|
||||
// v1 = v0;
|
||||
// }
|
||||
// else if ( d < -1.f+dotepsilon ) {
|
||||
// v2 = v1;
|
||||
// continue;
|
||||
// }
|
||||
//}
|
||||
|
||||
// drop any identical, adjacent vertices. this pass will collect the dropouts
|
||||
// of the previous pass as a side-effect.
|
||||
FuzzyVectorCompare fz(epsilon);
|
||||
std::vector<aiVector3D>::iterator end = base+cnt, e = std::unique( base, end, fz );
|
||||
if (e != end) {
|
||||
cnt -= static_cast<unsigned int>(std::distance(e, end));
|
||||
verts.erase(e,end);
|
||||
drop = true;
|
||||
}
|
||||
|
||||
// check front and back vertices for this polygon
|
||||
if (cnt > 1 && fz(*base,*(base+cnt-1))) {
|
||||
verts.erase(base+ --cnt);
|
||||
drop = true;
|
||||
}
|
||||
|
||||
// removing adjacent duplicates shouldn't erase everything :-)
|
||||
ai_assert(cnt>0);
|
||||
base += cnt;
|
||||
}
|
||||
if(drop) {
|
||||
IFCImporter::LogDebug("removed duplicate vertices");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool IsTrue(const EXPRESS::BOOLEAN& in)
|
||||
{
|
||||
return (std::string)in == "TRUE" || (std::string)in == "T";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
float ConvertSIPrefix(const std::string& prefix)
|
||||
{
|
||||
if (prefix == "EXA") {
|
||||
return 1e18f;
|
||||
}
|
||||
else if (prefix == "PETA") {
|
||||
return 1e15f;
|
||||
}
|
||||
else if (prefix == "TERA") {
|
||||
return 1e12f;
|
||||
}
|
||||
else if (prefix == "GIGA") {
|
||||
return 1e9f;
|
||||
}
|
||||
else if (prefix == "MEGA") {
|
||||
return 1e6f;
|
||||
}
|
||||
else if (prefix == "KILO") {
|
||||
return 1e3f;
|
||||
}
|
||||
else if (prefix == "HECTO") {
|
||||
return 1e2f;
|
||||
}
|
||||
else if (prefix == "DECA") {
|
||||
return 1e-0f;
|
||||
}
|
||||
else if (prefix == "DECI") {
|
||||
return 1e-1f;
|
||||
}
|
||||
else if (prefix == "CENTI") {
|
||||
return 1e-2f;
|
||||
}
|
||||
else if (prefix == "MILLI") {
|
||||
return 1e-3f;
|
||||
}
|
||||
else if (prefix == "MICRO") {
|
||||
return 1e-6f;
|
||||
}
|
||||
else if (prefix == "NANO") {
|
||||
return 1e-9f;
|
||||
}
|
||||
else if (prefix == "PICO") {
|
||||
return 1e-12f;
|
||||
}
|
||||
else if (prefix == "FEMTO") {
|
||||
return 1e-15f;
|
||||
}
|
||||
else if (prefix == "ATTO") {
|
||||
return 1e-18f;
|
||||
}
|
||||
else {
|
||||
IFCImporter::LogError("Unrecognized SI prefix: " + prefix);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertColor(aiColor4D& out, const IfcColourRgb& in)
|
||||
{
|
||||
out.r = in.Red;
|
||||
out.g = in.Green;
|
||||
out.b = in.Blue;
|
||||
out.a = 1.f;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base)
|
||||
{
|
||||
if (const EXPRESS::REAL* const r = in.ToPtr<EXPRESS::REAL>()) {
|
||||
out.r = out.g = out.b = *r;
|
||||
if(base) {
|
||||
out.r *= base->r;
|
||||
out.g *= base->g;
|
||||
out.b *= base->b;
|
||||
out.a = base->a;
|
||||
}
|
||||
else out.a = 1.0;
|
||||
}
|
||||
else if (const IfcColourRgb* const rgb = in.ResolveSelectPtr<IfcColourRgb>(conv.db)) {
|
||||
ConvertColor(out,*rgb);
|
||||
}
|
||||
else {
|
||||
IFCImporter::LogWarn("skipping unknown IfcColourOrFactor entity");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertCartesianPoint(aiVector3D& out, const IfcCartesianPoint& in)
|
||||
{
|
||||
out = aiVector3D();
|
||||
for(size_t i = 0; i < in.Coordinates.size(); ++i) {
|
||||
out[i] = in.Coordinates[i];
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertDirection(aiVector3D& out, const IfcDirection& in)
|
||||
{
|
||||
out = aiVector3D();
|
||||
for(size_t i = 0; i < in.DirectionRatios.size(); ++i) {
|
||||
out[i] = in.DirectionRatios[i];
|
||||
}
|
||||
const float len = out.Length();
|
||||
if (len<1e-6) {
|
||||
IFCImporter::LogWarn("direction vector too small, normalizing would result in a division by zero");
|
||||
return;
|
||||
}
|
||||
out /= len;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void AssignMatrixAxes(aiMatrix4x4& out, const aiVector3D& x, const aiVector3D& y, const aiVector3D& z)
|
||||
{
|
||||
out.a1 = x.x;
|
||||
out.b1 = x.y;
|
||||
out.c1 = x.z;
|
||||
|
||||
out.a2 = y.x;
|
||||
out.b2 = y.y;
|
||||
out.c2 = y.z;
|
||||
|
||||
out.a3 = z.x;
|
||||
out.b3 = z.y;
|
||||
out.c3 = z.z;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement3D& in)
|
||||
{
|
||||
aiVector3D loc;
|
||||
ConvertCartesianPoint(loc,in.Location);
|
||||
|
||||
aiVector3D z(0.f,0.f,1.f),r(1.f,0.f,0.f),x;
|
||||
|
||||
if (in.Axis) {
|
||||
ConvertDirection(z,*in.Axis.Get());
|
||||
}
|
||||
if (in.RefDirection) {
|
||||
ConvertDirection(r,*in.RefDirection.Get());
|
||||
}
|
||||
|
||||
aiVector3D v = r.Normalize();
|
||||
aiVector3D tmpx = z * (v*z);
|
||||
|
||||
x = (v-tmpx).Normalize();
|
||||
aiVector3D y = (z^x);
|
||||
|
||||
aiMatrix4x4::Translation(loc,out);
|
||||
AssignMatrixAxes(out,x,y,z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement2D& in)
|
||||
{
|
||||
aiVector3D loc;
|
||||
ConvertCartesianPoint(loc,in.Location);
|
||||
|
||||
aiVector3D x(1.f,0.f,0.f);
|
||||
if (in.RefDirection) {
|
||||
ConvertDirection(x,*in.RefDirection.Get());
|
||||
}
|
||||
|
||||
const aiVector3D y = aiVector3D(x.y,-x.x,0.f);
|
||||
|
||||
aiMatrix4x4::Translation(loc,out);
|
||||
AssignMatrixAxes(out,x,y,aiVector3D(0.f,0.f,1.f));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertAxisPlacement(aiVector3D& axis, aiVector3D& pos, const IfcAxis1Placement& in)
|
||||
{
|
||||
ConvertCartesianPoint(pos,in.Location);
|
||||
if (in.Axis) {
|
||||
ConvertDirection(axis,in.Axis.Get());
|
||||
}
|
||||
else {
|
||||
axis = aiVector3D(0.f,0.f,1.f);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement& in, ConversionData& conv)
|
||||
{
|
||||
if(const IfcAxis2Placement3D* pl3 = in.ResolveSelectPtr<IfcAxis2Placement3D>(conv.db)) {
|
||||
ConvertAxisPlacement(out,*pl3);
|
||||
}
|
||||
else if(const IfcAxis2Placement2D* pl2 = in.ResolveSelectPtr<IfcAxis2Placement2D>(conv.db)) {
|
||||
ConvertAxisPlacement(out,*pl2);
|
||||
}
|
||||
else {
|
||||
IFCImporter::LogWarn("skipping unknown IfcAxis2Placement entity");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertTransformOperator(aiMatrix4x4& out, const IfcCartesianTransformationOperator& op)
|
||||
{
|
||||
aiVector3D loc;
|
||||
ConvertCartesianPoint(loc,op.LocalOrigin);
|
||||
|
||||
aiVector3D x(1.f,0.f,0.f),y(0.f,1.f,0.f),z(0.f,0.f,1.f);
|
||||
if (op.Axis1) {
|
||||
ConvertDirection(x,*op.Axis1.Get());
|
||||
}
|
||||
if (op.Axis2) {
|
||||
ConvertDirection(y,*op.Axis2.Get());
|
||||
}
|
||||
if (const IfcCartesianTransformationOperator3D* op2 = op.ToPtr<IfcCartesianTransformationOperator3D>()) {
|
||||
if(op2->Axis3) {
|
||||
ConvertDirection(z,*op2->Axis3.Get());
|
||||
}
|
||||
}
|
||||
|
||||
aiMatrix4x4 locm;
|
||||
aiMatrix4x4::Translation(loc,locm);
|
||||
AssignMatrixAxes(out,x,y,z);
|
||||
|
||||
|
||||
aiVector3D vscale;
|
||||
if (const IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr<IfcCartesianTransformationOperator3DnonUniform>()) {
|
||||
vscale.x = nuni->Scale?op.Scale.Get():1.f;
|
||||
vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f;
|
||||
vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f;
|
||||
}
|
||||
else {
|
||||
const float sc = op.Scale?op.Scale.Get():1.f;
|
||||
vscale = aiVector3D(sc,sc,sc);
|
||||
}
|
||||
|
||||
aiMatrix4x4 s;
|
||||
aiMatrix4x4::Scaling(vscale,s);
|
||||
|
||||
out = locm * out * s;
|
||||
}
|
||||
|
||||
} // ! IFC
|
||||
} // ! Assimp
|
||||
|
||||
#endif
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
Open Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2010, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file IFC.cpp
|
||||
* @brief Implementation of the Industry Foundation Classes loader.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IFCUTIL_H
|
||||
#define INCLUDED_IFCUTIL_H
|
||||
|
||||
#include "IFCReaderGen.h"
|
||||
#include "IFCLoader.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace IFC {
|
||||
|
||||
// helper for std::for_each to delete all heap-allocated items in a container
|
||||
template<typename T>
|
||||
struct delete_fun
|
||||
{
|
||||
void operator()(T* del) {
|
||||
delete del;
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Temporary representation of an opening in a wall or a floor
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
struct TempMesh;
|
||||
struct TempOpening
|
||||
{
|
||||
const IFC::IfcExtrudedAreaSolid* solid;
|
||||
aiVector3D extrusionDir;
|
||||
boost::shared_ptr<TempMesh> profileMesh;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
TempOpening(const IFC::IfcExtrudedAreaSolid* solid,aiVector3D extrusionDir,boost::shared_ptr<TempMesh> profileMesh)
|
||||
: solid(solid)
|
||||
, extrusionDir(extrusionDir)
|
||||
, profileMesh(profileMesh)
|
||||
{
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
void Transform(const aiMatrix4x4& mat); // defined later since TempMesh is not complete yet
|
||||
};
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Intermediate data storage during conversion. Keeps everything and a bit more.
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
struct ConversionData
|
||||
{
|
||||
ConversionData(const STEP::DB& db, const IFC::IfcProject& proj, aiScene* out,const IFCImporter::Settings& settings)
|
||||
: len_scale(1.0)
|
||||
, angle_scale(1.0)
|
||||
, db(db)
|
||||
, proj(proj)
|
||||
, out(out)
|
||||
, settings(settings)
|
||||
, apply_openings()
|
||||
, collect_openings()
|
||||
{}
|
||||
|
||||
~ConversionData() {
|
||||
std::for_each(meshes.begin(),meshes.end(),delete_fun<aiMesh>());
|
||||
std::for_each(materials.begin(),materials.end(),delete_fun<aiMaterial>());
|
||||
}
|
||||
|
||||
float len_scale, angle_scale;
|
||||
bool plane_angle_in_radians;
|
||||
|
||||
const STEP::DB& db;
|
||||
const IFC::IfcProject& proj;
|
||||
aiScene* out;
|
||||
|
||||
aiMatrix4x4 wcs;
|
||||
std::vector<aiMesh*> meshes;
|
||||
std::vector<aiMaterial*> materials;
|
||||
|
||||
typedef std::map<const IFC::IfcRepresentationItem*, std::vector<unsigned int> > MeshCache;
|
||||
MeshCache cached_meshes;
|
||||
|
||||
const IFCImporter::Settings& settings;
|
||||
|
||||
// Intermediate arrays used to resolve openings in walls: only one of them
|
||||
// can be given at a time. apply_openings if present if the current element
|
||||
// is a wall and needs its openings to be poured into its geometry while
|
||||
// collect_openings is present only if the current element is an
|
||||
// IfcOpeningElement, for which all the geometry needs to be preserved
|
||||
// for later processing by a parent, which is a wall.
|
||||
std::vector<TempOpening>* apply_openings;
|
||||
std::vector<TempOpening>* collect_openings;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
struct FuzzyVectorCompare {
|
||||
|
||||
FuzzyVectorCompare(float epsilon) : epsilon(epsilon) {}
|
||||
bool operator()(const aiVector3D& a, const aiVector3D& b) {
|
||||
return fabs((a-b).SquareLength()) < epsilon;
|
||||
}
|
||||
|
||||
const float epsilon;
|
||||
};
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Helper used during mesh construction. Aids at creating aiMesh'es out of relatively few polygons.
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
struct TempMesh
|
||||
{
|
||||
std::vector<aiVector3D> verts;
|
||||
std::vector<unsigned int> vertcnt;
|
||||
|
||||
// utilities
|
||||
aiMesh* ToMesh();
|
||||
void Clear();
|
||||
void Transform(const aiMatrix4x4& mat);
|
||||
aiVector3D Center() const;
|
||||
void Append(const TempMesh& other);
|
||||
void RemoveAdjacentDuplicates();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// conversion routines for common IFC entities, implemented in IFCUtil.cpp
|
||||
void ConvertColor(aiColor4D& out, const IFC::IfcColourRgb& in);
|
||||
void ConvertColor(aiColor4D& out, const IFC::IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base);
|
||||
void ConvertCartesianPoint(aiVector3D& out, const IFC::IfcCartesianPoint& in);
|
||||
void ConvertDirection(aiVector3D& out, const IFC::IfcDirection& in);
|
||||
void AssignMatrixAxes(aiMatrix4x4& out, const aiVector3D& x, const aiVector3D& y, const aiVector3D& z);
|
||||
void ConvertAxisPlacement(aiMatrix4x4& out, const IFC::IfcAxis2Placement3D& in);
|
||||
void ConvertAxisPlacement(aiMatrix4x4& out, const IFC::IfcAxis2Placement2D& in);
|
||||
void ConvertAxisPlacement(aiVector3D& axis, aiVector3D& pos, const IFC::IfcAxis1Placement& in);
|
||||
void ConvertAxisPlacement(aiMatrix4x4& out, const IFC::IfcAxis2Placement& in, ConversionData& conv);
|
||||
void ConvertTransformOperator(aiMatrix4x4& out, const IFC::IfcCartesianTransformationOperator& op);
|
||||
bool IsTrue(const EXPRESS::BOOLEAN& in);
|
||||
float ConvertSIPrefix(const std::string& prefix);
|
||||
|
||||
|
||||
// IFCProfile.cpp
|
||||
bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv);
|
||||
|
||||
// IFCMaterial.cpp
|
||||
unsigned int ProcessMaterials(const IFC::IfcRepresentationItem& item, ConversionData& conv);
|
||||
|
||||
// IFCGeometry.cpp
|
||||
bool ProcessRepresentationItem(const IfcRepresentationItem& item, std::vector<unsigned int>& mesh_indices, ConversionData& conv);
|
||||
void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,ConversionData& /*conv*/);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -684,6 +684,10 @@ namespace STEP {
|
|||
Lazy(const LazyObject* obj = NULL) : obj(obj) {
|
||||
}
|
||||
|
||||
operator const T*() const {
|
||||
return obj->ToPtr<T>();
|
||||
}
|
||||
|
||||
operator const T&() const {
|
||||
return obj->To<T>();
|
||||
}
|
||||
|
|
|
@ -1947,6 +1947,10 @@
|
|||
<Filter
|
||||
Name="ifc"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\code\IFCGeometry.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\IFCLoader.cpp"
|
||||
>
|
||||
|
@ -1955,6 +1959,14 @@
|
|||
RelativePath="..\..\code\IFCLoader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\IFCMaterial.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\IFCProfile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\IFCReaderGen.cpp"
|
||||
>
|
||||
|
@ -1971,6 +1983,14 @@
|
|||
RelativePath="..\..\code\IFCReaderGen.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\IFCUtil.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\IFCUtil.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\STEPFile.h"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue