#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include "IFCUtil.h"
namespace Assimp {
namespace IFC {
void ProcessPolyLine(const IfcPolyline& def, TempMesh& meshout, ConversionData& )
{
IfcVector3 t;
for(const IfcCartesianPoint& cp : def.Points) {
ConvertCartesianPoint(t,cp);
meshout.verts.push_back(t);
}
meshout.vertcnt.push_back(static_cast<unsigned int>(meshout.verts.size()));
}
bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv)
{
std::unique_ptr<const Curve> cv(Curve::Convert(curve,conv));
if (!cv) {
IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is " + curve.GetClassName());
return false;
}
if (const BoundedCurve* bc = dynamic_cast<const BoundedCurve*>(cv.get())) {
try {
bc->SampleDiscrete(meshout);
}
catch(const CurveError& cv) {
IFCImporter::LogError(cv.s+ " (error occurred while processing curve)");
return false;
}
meshout.vertcnt.push_back(static_cast<unsigned int>(meshout.verts.size()));
return true;
}
IFCImporter::LogError("cannot use unbounded curve as profile");
return false;
}
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 IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
meshout.verts.reserve(meshout.verts.size()+4);
meshout.verts.push_back( IfcVector3( x, y, 0.f ));
meshout.verts.push_back( IfcVector3(-x, y, 0.f ));
meshout.verts.push_back( IfcVector3(-x,-y, 0.f ));
meshout.verts.push_back( IfcVector3( x,-y, 0.f ));
meshout.vertcnt.push_back(4);
}
else if( const IfcCircleProfileDef* const circle = def.ToPtr<IfcCircleProfileDef>()) {
if(def.ToPtr<IfcCircleHollowProfileDef>()) {
}
const size_t segments = conv.settings.cylindricalTessellation;
const IfcFloat delta = AI_MATH_TWO_PI_F/segments, radius = circle->Radius;
meshout.verts.reserve(segments);
IfcFloat angle = 0.f;
for(size_t i = 0; i < segments; ++i, angle += delta) {
meshout.verts.push_back( IfcVector3( std::cos(angle)*radius, std::sin(angle)*radius, 0.f ));
}
meshout.vertcnt.push_back(segments);
}
else if( const IfcIShapeProfileDef* const ishape = def.ToPtr<IfcIShapeProfileDef>()) {
const IfcFloat offset = (ishape->OverallWidth - ishape->WebThickness) / 2;
const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2;
meshout.verts.reserve(12);
meshout.verts.push_back(IfcVector3(0,0,0));
meshout.verts.push_back(IfcVector3(0,ishape->FlangeThickness,0));
meshout.verts.push_back(IfcVector3(offset,ishape->FlangeThickness,0));
meshout.verts.push_back(IfcVector3(offset,ishape->FlangeThickness + inner_height,0));
meshout.verts.push_back(IfcVector3(0,ishape->FlangeThickness + inner_height,0));
meshout.verts.push_back(IfcVector3(0,ishape->OverallDepth,0));
meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->OverallDepth,0));
meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness + inner_height,0));
meshout.verts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness + inner_height,0));
meshout.verts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness,0));
meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness,0));
meshout.verts.push_back(IfcVector3(ishape->OverallWidth,0,0));
meshout.vertcnt.push_back(12);
}
else {
IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is " + def.GetClassName());
return;
}
IfcMatrix4 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;
}
} }
#endif