Beispiel #1
0
bool IfcGeom::Kernel::convert(const IfcSchema::IfcMappedItem* l, IfcRepresentationShapeItems& shapes) {
    gp_GTrsf gtrsf;
    IfcSchema::IfcCartesianTransformationOperator* transform = l->MappingTarget();
    if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
        IfcGeom::Kernel::convert((IfcSchema::IfcCartesianTransformationOperator3DnonUniform*)transform,gtrsf);
    } else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2DnonUniform) ) {
        Logger::Message(Logger::LOG_ERROR, "Unsupported MappingTarget:", transform->entity);
        return false;
    } else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator3D) ) {
        gp_Trsf trsf;
        IfcGeom::Kernel::convert((IfcSchema::IfcCartesianTransformationOperator3D*)transform,trsf);
        gtrsf = trsf;
    } else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2D) ) {
        gp_Trsf2d trsf_2d;
        IfcGeom::Kernel::convert((IfcSchema::IfcCartesianTransformationOperator2D*)transform,trsf_2d);
        gtrsf = (gp_Trsf) trsf_2d;
    }
    IfcSchema::IfcRepresentationMap* map = l->MappingSource();
    IfcSchema::IfcAxis2Placement* placement = map->MappingOrigin();
    gp_Trsf trsf;
    if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
        IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
    } else {
        gp_Trsf2d trsf_2d;
        IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf_2d);
        trsf = trsf_2d;
    }
    gtrsf.Multiply(trsf);
    const unsigned int previous_size = (const unsigned int) shapes.size();
    bool b = convert_shapes(map->MappedRepresentation(),shapes);
    for ( unsigned int i = previous_size; i < shapes.size(); ++ i ) {
        shapes[i].append(gtrsf);
    }
    return b;
}
Beispiel #2
0
bool IfcGeom::Kernel::convert(const IfcSchema::IfcFacetedBrep* l, IfcRepresentationShapeItems& shape) {
    TopoDS_Shape s;
    const SurfaceStyle* collective_style = get_style(l);
    if (convert_shape(l->Outer(),s) ) {
        const SurfaceStyle* indiv_style = get_style(l->Outer());
        shape.push_back(IfcRepresentationShapeItem(s, indiv_style ? indiv_style : collective_style));
        return true;
    }
    return false;
}
Beispiel #3
0
bool IfcGeom::Kernel::convert(const IfcSchema::IfcFaceBasedSurfaceModel* l, IfcRepresentationShapeItems& shapes) {
    IfcSchema::IfcConnectedFaceSet::list::ptr facesets = l->FbsmFaces();
    const SurfaceStyle* collective_style = get_style(l);
    for( IfcSchema::IfcConnectedFaceSet::list::it it = facesets->begin(); it != facesets->end(); ++ it ) {
        TopoDS_Shape s;
        const SurfaceStyle* shell_style = get_style(*it);
        if (convert_shape(*it,s)) {
            shapes.push_back(IfcRepresentationShapeItem(s, shell_style ? shell_style : collective_style));
        }
    }
    return true;
}
Beispiel #4
0
bool IfcGeom::Kernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, IfcRepresentationShapeItems& shapes) {
    IfcEntityList::ptr shells = l->SbsmBoundary();
    const SurfaceStyle* collective_style = get_style(l);
    for( IfcEntityList::it it = shells->begin(); it != shells->end(); ++ it ) {
        TopoDS_Shape s;
        const SurfaceStyle* shell_style = 0;
        if ((*it)->is(IfcSchema::Type::IfcRepresentationItem)) {
            shell_style = get_style((IfcSchema::IfcRepresentationItem*)*it);
        }
        if (convert_shape(*it,s)) {
            shapes.push_back(IfcRepresentationShapeItem(s, shell_style ? shell_style : collective_style));
        }
    }
    return true;
}
Beispiel #5
0
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRepresentation* l, IfcRepresentationShapeItems& shapes) {
    IfcSchema::IfcRepresentationItem::list::ptr items = l->Items();
    bool part_succes = false;
    if ( items->size() ) {
        for ( IfcSchema::IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++ it ) {
            IfcSchema::IfcRepresentationItem* representation_item = *it;
            if ( shape_type(representation_item) == ST_SHAPELIST ) {
                part_succes |= convert_shapes(*it, shapes);
            } else {
                TopoDS_Shape s;
                if (convert_shape(representation_item,s)) {
                    shapes.push_back(IfcRepresentationShapeItem(s, get_style(representation_item)));
                    part_succes |= true;
                }
            }
        }
    }
    return part_succes;
}
Beispiel #6
0
bool IfcGeom::Kernel::convert(const IfcSchema::IfcGeometricSet* l, IfcRepresentationShapeItems& shapes) {
    IfcEntityList::ptr elements = l->Elements();
    if ( !elements->size() ) return false;
    bool part_succes = false;
    const IfcGeom::SurfaceStyle* parent_style = get_style(l);
    for ( IfcEntityList::it it = elements->begin(); it != elements->end(); ++ it ) {
        IfcSchema::IfcGeometricSetSelect* element = *it;
        TopoDS_Shape s;
        if (convert_shape(element, s)) {
            part_succes = true;
            const IfcGeom::SurfaceStyle* style = 0;
            if (element->is(IfcSchema::Type::IfcPoint)) {
                style = get_style((IfcSchema::IfcPoint*) element);
            } else if (element->is(IfcSchema::Type::IfcCurve)) {
                style = get_style((IfcSchema::IfcCurve*) element);
            } else if (element->is(IfcSchema::Type::IfcSurface)) {
                style = get_style((IfcSchema::IfcSurface*) element);
            }
            shapes.push_back(IfcRepresentationShapeItem(s, style ? style : parent_style));
        }
    }
    return part_succes;
}
bool IfcGeom::convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, 
							   const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes) {
	
	// Create a compound of all opening shapes in order to speed up the boolean operations
	TopoDS_Compound opening_compound;
	BRep_Builder builder;
	builder.MakeCompound(opening_compound);

	for ( Ifc2x3::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) {
		Ifc2x3::IfcRelVoidsElement::ptr v = *it;
		Ifc2x3::IfcFeatureElementSubtraction::ptr fes = v->RelatedOpeningElement();
		if ( fes->is(Ifc2x3::Type::IfcOpeningElement) ) {

			// Convert the IfcRepresentation of the IfcOpeningElement
			gp_Trsf opening_trsf;
			IfcGeom::convert(fes->ObjectPlacement(),opening_trsf);

			// Move the opening into the coordinate system of the IfcProduct
			opening_trsf.PreMultiply(entity_trsf.Inverted());

			Ifc2x3::IfcProductRepresentation::ptr prodrep = fes->Representation();
			Ifc2x3::IfcRepresentation::list reps = prodrep->Representations();

			IfcGeom::IfcRepresentationShapeItems opening_shapes;
						
			for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
				IfcGeom::convert_shapes(*it2,opening_shapes);
			}

			for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) {
				gp_GTrsf gtrsf = opening_shapes[i].Placement();
				gtrsf.PreMultiply(opening_trsf);
				const TopoDS_Shape& opening_shape = gtrsf.Form() == gp_Other
					? BRepBuilderAPI_GTransform(opening_shapes[i].Shape(),gtrsf,true).Shape()
					: (opening_shapes[i].Shape()).Moved(gtrsf.Trsf());
				builder.Add(opening_compound,opening_shape);
			}

		}
	}

	// Iterate over the shapes of the IfcProduct
	for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
		TopoDS_Shape entity_shape_solid;
		const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid);
		const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
		TopoDS_Shape entity_shape;
		if ( entity_shape_gtrsf.Form() == gp_Other ) {
			Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity);
			entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape();
		} else {
			entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf());
		}

		BRepAlgoAPI_Cut brep_cut(entity_shape,opening_compound);
		bool is_valid = false;
		if ( brep_cut.IsDone() ) {
			TopoDS_Shape brep_cut_result = brep_cut;
				
			BRepCheck_Analyzer analyser(brep_cut_result);
			is_valid = analyser.IsValid() != 0;
			if ( is_valid ) {
				cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(brep_cut_result, &it3->Style()));
			}
		}
		if ( !is_valid ) {
			// Apparently processing the boolean operation failed or resulted in an invalid result
			// in which case the original shape without the subtractions is returned instead
			// we try convert the openings in the original way, one by one.
			Logger::Message(Logger::LOG_WARNING,"Subtracting combined openings compound failed:",entity->entity);
			return false;
		}
		
	}
	return true;
}
bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, 
							   const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes) {
	// Iterate over IfcOpeningElements
	IfcGeom::IfcRepresentationShapeItems opening_shapes;
	unsigned int last_size = 0;
	for ( Ifc2x3::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) {
		Ifc2x3::IfcRelVoidsElement::ptr v = *it;
		Ifc2x3::IfcFeatureElementSubtraction::ptr fes = v->RelatedOpeningElement();
		if ( fes->is(Ifc2x3::Type::IfcOpeningElement) ) {

			// Convert the IfcRepresentation of the IfcOpeningElement
			gp_Trsf opening_trsf;
			IfcGeom::convert(fes->ObjectPlacement(),opening_trsf);

			// Move the opening into the coordinate system of the IfcProduct
			opening_trsf.PreMultiply(entity_trsf.Inverted());

			Ifc2x3::IfcProductRepresentation::ptr prodrep = fes->Representation();
			Ifc2x3::IfcRepresentation::list reps = prodrep->Representations();
						
			for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
				IfcGeom::convert_shapes(*it2,opening_shapes);
			}

			const unsigned int current_size = (const unsigned int) opening_shapes.size();
			for ( unsigned int i = last_size; i < current_size; ++ i ) {
				opening_shapes[i].prepend(opening_trsf);
			}
			last_size = current_size;
		}
	}

	// Iterate over the shapes of the IfcProduct
	for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
		TopoDS_Shape entity_shape_solid;
		const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid);
		const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
		TopoDS_Shape entity_shape;
		if ( entity_shape_gtrsf.Form() == gp_Other ) {
			Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity);
			entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape();
		} else {
			entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf());
		}

		// Iterate over the shapes of the IfcOpeningElements
		for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it4 = opening_shapes.begin(); it4 != opening_shapes.end(); ++ it4 ) {
			TopoDS_Shape opening_shape_solid;
			const TopoDS_Shape& opening_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it4->Shape(),opening_shape_solid);
			const gp_GTrsf& opening_shape_gtrsf = it4->Placement();
			if ( opening_shape_gtrsf.Form() == gp_Other ) {
				Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to opening of:",entity->entity);
			}
			const TopoDS_Shape& opening_shape = opening_shape_gtrsf.Form() == gp_Other
				? BRepBuilderAPI_GTransform(opening_shape_unlocated,opening_shape_gtrsf,true).Shape()
				: opening_shape_unlocated.Moved(opening_shape_gtrsf.Trsf());
					
			double opening_volume, original_shape_volume;
			if ( Logger::Verbosity() >= Logger::LOG_WARNING ) {
				opening_volume = shape_volume(opening_shape);
				if ( opening_volume <= ALMOST_ZERO )
					Logger::Message(Logger::LOG_WARNING,"Empty opening for:",entity->entity);
				original_shape_volume = shape_volume(entity_shape);
			}
			
			BRepAlgoAPI_Cut brep_cut(entity_shape,opening_shape);

			if ( brep_cut.IsDone() ) {
				TopoDS_Shape brep_cut_result = brep_cut;
				
				BRepCheck_Analyzer analyser(brep_cut_result);
				bool is_valid = analyser.IsValid() != 0;
				if ( is_valid ) {
					entity_shape = brep_cut;
					if ( Logger::Verbosity() >= Logger::LOG_WARNING ) {
						const double volume_after_subtraction = shape_volume(entity_shape);
					
						if ( ALMOST_THE_SAME(original_shape_volume,volume_after_subtraction) )
							Logger::Message(Logger::LOG_WARNING,"Subtraction yields unchanged volume:",entity->entity);
					}
				} else {
					Logger::Message(Logger::LOG_ERROR,"Invalid result from subtraction:",entity->entity);
				}
			} else {
				Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",entity->entity);
			}

		}
		cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(entity_shape, &it3->Style()));
	}

	return true;
}