Esempio n. 1
0
// Extrudes the given polygon along the direction, converts it into an opening or applies all openings as necessary.
void ProcessExtrudedArea(const IfcExtrudedAreaSolid& solid, const TempMesh& curve,
    const IfcVector3& extrusionDir, TempMesh& result, ConversionData &conv, bool collect_openings)
{
    // Outline: 'curve' is now a list of vertex points forming the underlying profile, extrude along the given axis,
    // forming new triangles.
    const bool has_area = solid.SweptArea->ProfileType == "AREA" && curve.verts.size() > 2;
    if( solid.Depth < 1e-6 ) {
        if( has_area ) {
            result.Append(curve);
        }
        return;
    }

    result.verts.reserve(curve.verts.size()*(has_area ? 4 : 2));
    result.vertcnt.reserve(curve.verts.size() + 2);
    std::vector<IfcVector3> in = curve.verts;

    // First step: transform all vertices into the target coordinate space
    IfcMatrix4 trafo;
    ConvertAxisPlacement(trafo, solid.Position);

    IfcVector3 vmin, vmax;
    MinMaxChooser<IfcVector3>()(vmin, vmax);
    BOOST_FOREACH(IfcVector3& v, in) {
        v *= trafo;

        vmin = std::min(vmin, v);
        vmax = std::max(vmax, v);
    }
Esempio n. 2
0
// ------------------------------------------------------------------------------------------------
void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv)
{
	(void)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( const IfcCircleHollowProfileDef* const hollow = def.ToPtr<IfcCircleHollowProfileDef>()) {
			// TODO
		}
		const size_t segments = 32;
		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( cos(angle)*radius, sin(angle)*radius, 0.f ));
		}

		meshout.vertcnt.push_back(segments);
	}
	else if( const IfcIShapeProfileDef* const ishape = def.ToPtr<IfcIShapeProfileDef>()) {
		// construct simplified IBeam shape
		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);
}
Esempio n. 3
0
// ------------------------------------------------------------------------------------------------
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;
}
Esempio n. 4
0
// ------------------------------------------------------------------------------------------------
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( const IfcCircleHollowProfileDef* const hollow = def.ToPtr<IfcCircleHollowProfileDef>()) {
			// TODO
		}
		const size_t segments = 32;
		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( ::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;
	}

	IfcMatrix4 trafo;
	ConvertAxisPlacement(trafo, *def.Position);
	meshout.Transform(trafo);
}
Esempio n. 5
0
// ------------------------------------------------------------------------------------------------
void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv)
{
    TempMesh meshout;

    // first read the profile description
    if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) {
        return;
    }

    IfcVector3 axis, pos;
    ConvertAxisPlacement(axis,pos,solid.Axis);

    IfcMatrix4 tb0,tb1;
    IfcMatrix4::Translation(pos,tb0);
    IfcMatrix4::Translation(-pos,tb1);

    const std::vector<IfcVector3>& in = meshout.verts;
    const size_t size=in.size();

    bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2;
    const IfcFloat max_angle = solid.Angle*conv.angle_scale;
    if(std::fabs(max_angle) < 1e-3) {
        if(has_area) {
            result = meshout;
        }
        return;
    }

    const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(16 * std::fabs(max_angle)/AI_MATH_HALF_PI_F));
    const IfcFloat delta = max_angle/cnt_segments;

    has_area = has_area && std::fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;

    result.verts.reserve(size*((cnt_segments+1)*4+(has_area?2:0)));
    result.vertcnt.reserve(size*cnt_segments+2);

    IfcMatrix4 rot;
    rot = tb0 * IfcMatrix4::Rotation(delta,axis,rot) * tb1;

    size_t base = 0;
    std::vector<IfcVector3>& out = result.verts;

    // dummy data to simplify later processing
    for(size_t i = 0; i < size; ++i) {
        out.insert(out.end(),4,in[i]);
    }

    for(unsigned int seg = 0; seg < cnt_segments; ++seg) {
        for(size_t i = 0; i < size; ++i) {
            const size_t next = (i+1)%size;

            result.vertcnt.push_back(4);
            const IfcVector3& base_0 = out[base+i*4+3],base_1 = out[base+next*4+3];

            out.push_back(base_0);
            out.push_back(base_1);
            out.push_back(rot*base_1);
            out.push_back(rot*base_0);
        }
        base += size*4;
    }

    out.erase(out.begin(),out.begin()+size*4);

    if(has_area) {
        // leave the triangulation of the profile area to the ear cutting
        // implementation in aiProcess_Triangulate - for now we just
        // feed in two huge polygons.
        base -= size*8;
        for(size_t i = size; i--; ) {
            out.push_back(out[base+i*4+3]);
        }
        for(size_t i = 0; i < size; ++i ) {
            out.push_back(out[i*4]);
        }
        result.vertcnt.push_back(size);
        result.vertcnt.push_back(size);
    }

    IfcMatrix4 trafo;
    ConvertAxisPlacement(trafo, solid.Position);

    result.Transform(trafo);
    IFCImporter::LogDebug("generate mesh procedurally by radial extrusion (IfcRevolvedAreaSolid)");
}