mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-20 12:12:15 +00:00
Isolate (most of the) geometry processing code into separate opencascade kernel
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCSHAPELIST_H
|
||||
#define IFCSHAPELIST_H
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomRenderStyles.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
namespace Representation {
|
||||
template <typename P>
|
||||
class IFC_GEOM_API Triangulation;
|
||||
}
|
||||
|
||||
class IFC_GEOM_API ConversionResultPlacement {
|
||||
public:
|
||||
virtual void Multiply(const ConversionResultPlacement*) = 0;
|
||||
virtual void PreMultiply(const ConversionResultPlacement*) = 0;
|
||||
virtual ConversionResultPlacement* inverted() const = 0;
|
||||
virtual ConversionResultPlacement* multiplied(const ConversionResultPlacement*) const = 0;
|
||||
virtual double Value(int i, int j) const = 0;
|
||||
virtual ConversionResultPlacement* clone() const = 0;
|
||||
virtual ~ConversionResultPlacement() {}
|
||||
};
|
||||
|
||||
class IFC_GEOM_API ConversionResultShape {
|
||||
public:
|
||||
virtual void Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement* place, IfcGeom::Representation::Triangulation<float>* t, int surface_style_id) const = 0;
|
||||
virtual void Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement* place, IfcGeom::Representation::Triangulation<double>* t, int surface_style_id) const = 0;
|
||||
virtual void Serialize(std::string&) const = 0;
|
||||
virtual ConversionResultShape* clone() const = 0;
|
||||
virtual int surface_genus() const = 0;
|
||||
virtual ~ConversionResultShape() {}
|
||||
};
|
||||
|
||||
class IFC_GEOM_API ConversionResult {
|
||||
private:
|
||||
int id;
|
||||
ConversionResultPlacement* placement;
|
||||
ConversionResultShape* shape;
|
||||
const SurfaceStyle* style;
|
||||
public:
|
||||
ConversionResult(int id, const ConversionResultPlacement* placement, const ConversionResultShape* shape, const SurfaceStyle* style)
|
||||
: id(id), placement(placement->clone()), shape(shape->clone()), style(style) {}
|
||||
ConversionResult(int id, const ConversionResultPlacement* placement, const ConversionResultShape* shape)
|
||||
: id(id), placement(placement->clone()), shape(shape->clone()), style(0) {}
|
||||
ConversionResult(int id, const ConversionResultShape* shape, const SurfaceStyle* style)
|
||||
: id(id), placement(0), shape(shape->clone()), style(style) {}
|
||||
ConversionResult(int id, const ConversionResultShape* shape)
|
||||
: id(id), placement(0), shape(shape->clone()), style(0) {}
|
||||
void append(const ConversionResultPlacement* trsf) {
|
||||
if (placement == 0) {
|
||||
placement = trsf->clone();
|
||||
} else {
|
||||
placement->Multiply(trsf);
|
||||
}
|
||||
}
|
||||
void prepend(const ConversionResultPlacement* trsf) {
|
||||
if (placement == 0) {
|
||||
placement = trsf->clone();
|
||||
} else {
|
||||
placement->PreMultiply(trsf);
|
||||
}
|
||||
}
|
||||
const ConversionResultShape* Shape() const { return shape; }
|
||||
const ConversionResultPlacement* Placement() const { return placement; }
|
||||
bool hasStyle() const { return style != 0; }
|
||||
const SurfaceStyle& Style() const { return *style; }
|
||||
void setStyle(const SurfaceStyle* style) { this->style = style; }
|
||||
int ItemId() const { return id; }
|
||||
};
|
||||
|
||||
typedef std::vector<ConversionResult> ConversionResults;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,222 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCGEOMELEMENT_H
|
||||
#define IFCGEOMELEMENT_H
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../ifcparse/IfcGlobalId.h"
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
#include "ifc_geom_api.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
template <typename P>
|
||||
class Matrix {
|
||||
private:
|
||||
std::vector<P> _data;
|
||||
public:
|
||||
Matrix(const ElementSettings& settings, const ConversionResultPlacement* trsf) {
|
||||
// Convert the gp_Trsf into a 4x3 Matrix
|
||||
// Note that in case the CONVERT_BACK_UNITS setting is enabled
|
||||
// the translation component of the matrix needs to be divided
|
||||
// by the magnitude of the IFC model length unit because
|
||||
// internally in IfcOpenShell everything is measured in meters.
|
||||
for(int i = 1; i < 5; ++i) {
|
||||
for (int j = 1; j < 4; ++j) {
|
||||
const double trsf_value = trsf->Value(j,i);
|
||||
const double matrix_value = i == 4 && settings.get(IteratorSettings::CONVERT_BACK_UNITS)
|
||||
? trsf_value / settings.unit_magnitude()
|
||||
: trsf_value;
|
||||
_data.push_back(static_cast<P>(matrix_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
const std::vector<P>& data() const { return _data; }
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
class Transformation {
|
||||
private:
|
||||
ElementSettings settings_;
|
||||
ConversionResultPlacement* trsf_;
|
||||
Matrix<P> matrix_;
|
||||
public:
|
||||
Transformation(const ElementSettings& settings, const ConversionResultPlacement* trsf)
|
||||
: settings_(settings)
|
||||
, trsf_(trsf->clone())
|
||||
, matrix_(settings, trsf)
|
||||
{}
|
||||
const ConversionResultPlacement* data() const { return trsf_; }
|
||||
const Matrix<P>& matrix() const { return matrix_; }
|
||||
|
||||
Transformation inverted() const {
|
||||
return Transformation(settings_, trsf_->inverted());
|
||||
}
|
||||
|
||||
Transformation multiplied(const Transformation& other) const {
|
||||
return Transformation(settings_, trsf_->multiplied(other.data()));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P = double, typename PP = P>
|
||||
class Element {
|
||||
private:
|
||||
int _id;
|
||||
int _parent_id;
|
||||
std::string _name;
|
||||
std::string _type;
|
||||
std::string _guid;
|
||||
std::string _context;
|
||||
std::string _unique_id;
|
||||
Transformation<PP> _transformation;
|
||||
IfcUtil::IfcBaseEntity* product_;
|
||||
std::vector<const IfcGeom::Element<P, PP>*> _parents;
|
||||
public:
|
||||
|
||||
friend bool operator == (const Element<P, PP> & element1, const Element<P, PP> & element2) {
|
||||
return element1.id() == element2.id();
|
||||
}
|
||||
|
||||
// Use the id to compare, or the elevation is the elements are IfcBuildingStoreys and the elevation is set
|
||||
friend bool operator < (const Element<P, PP> & element1, const Element<P, PP> & element2) {
|
||||
if (element1.type() == "IfcBuildingStorey" && element2.type() == "IfcBuildingStorey") {
|
||||
size_t attr_index = element1.product()->declaration().attribute_index("Elevation");
|
||||
Argument* elev_attr1 = element1.product()->data().getArgument(attr_index);
|
||||
Argument* elev_attr2 = element2.product()->data().getArgument(attr_index);
|
||||
|
||||
if (!elev_attr1->isNull() && !elev_attr2->isNull()) {
|
||||
double elev1 = *elev_attr1;
|
||||
double elev2 = *elev_attr2;
|
||||
|
||||
return elev1 < elev2;
|
||||
}
|
||||
}
|
||||
|
||||
return element1.id() < element2.id();
|
||||
}
|
||||
|
||||
int id() const { return _id; }
|
||||
int parent_id() const { return _parent_id; }
|
||||
const std::string& name() const { return _name; }
|
||||
const std::string& type() const { return _type; }
|
||||
const std::string& guid() const { return _guid; }
|
||||
const std::string& context() const { return _context; }
|
||||
const std::string& unique_id() const { return _unique_id; }
|
||||
const Transformation<PP>& transformation() const { return _transformation; }
|
||||
IfcUtil::IfcBaseEntity* product() const { return product_; }
|
||||
const std::vector<const IfcGeom::Element<P, PP>*> parents() const { return _parents; }
|
||||
void SetParents(std::vector<const IfcGeom::Element<P, PP>*> newparents) { _parents = newparents; }
|
||||
|
||||
Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type,
|
||||
const std::string& guid, const std::string& context, const ConversionResultPlacement* trsf, IfcUtil::IfcBaseEntity* product)
|
||||
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
|
||||
, product_(product)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
if (type == "IfcProject") {
|
||||
oss << "project";
|
||||
} else {
|
||||
try {
|
||||
oss << "product-" << IfcParse::IfcGlobalId(guid).formatted();
|
||||
} catch (const std::exception& e) {
|
||||
oss << "product";
|
||||
Logger::Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_context.empty()) {
|
||||
std::string ctx = _context;
|
||||
boost::to_lower(ctx);
|
||||
boost::replace_all(ctx, " ", "-");
|
||||
oss << "-" << ctx;
|
||||
}
|
||||
|
||||
_unique_id = oss.str();
|
||||
}
|
||||
virtual ~Element() {}
|
||||
};
|
||||
|
||||
template <typename P = double, typename PP = P>
|
||||
class NativeElement : public Element<P, PP> {
|
||||
private:
|
||||
boost::shared_ptr<Representation::BRep> _geometry;
|
||||
public:
|
||||
const boost::shared_ptr<Representation::BRep>& geometry_pointer() const { return _geometry; }
|
||||
const Representation::BRep& geometry() const { return *_geometry; }
|
||||
NativeElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid,
|
||||
const std::string& context, const ConversionResultPlacement* trsf, const boost::shared_ptr<Representation::BRep>& geometry,
|
||||
IfcUtil::IfcBaseEntity* product)
|
||||
: Element<P, PP>(geometry->settings() ,id, parent_id, name, type, guid, context, trsf, product)
|
||||
, _geometry(geometry)
|
||||
{}
|
||||
|
||||
bool calculate_projected_surface_area(double& along_x, double& along_y, double& along_z) const {
|
||||
return geometry().calculate_projected_surface_area(this->transformation().data(), along_x, along_y, along_z);
|
||||
}
|
||||
private:
|
||||
NativeElement(const NativeElement& other);
|
||||
NativeElement& operator=(const NativeElement& other);
|
||||
};
|
||||
|
||||
template <typename P = double, typename PP = P>
|
||||
class TriangulationElement : public Element<P, PP> {
|
||||
private:
|
||||
boost::shared_ptr< Representation::Triangulation<P> > _geometry;
|
||||
public:
|
||||
const Representation::Triangulation<P>& geometry() const { return *_geometry; }
|
||||
const boost::shared_ptr< Representation::Triangulation<P> >& geometry_pointer() const { return _geometry; }
|
||||
TriangulationElement(const NativeElement<P, PP>& shape_model)
|
||||
: Element<P, PP>(shape_model)
|
||||
, _geometry(boost::shared_ptr<Representation::Triangulation<P> >(new Representation::Triangulation<P>(shape_model.geometry())))
|
||||
{}
|
||||
TriangulationElement(const Element<P, PP>& element, const boost::shared_ptr<Representation::Triangulation<P> >& geometry)
|
||||
: Element<P, PP>(element)
|
||||
, _geometry(geometry)
|
||||
{}
|
||||
private:
|
||||
TriangulationElement(const TriangulationElement& other);
|
||||
TriangulationElement& operator=(const TriangulationElement& other);
|
||||
};
|
||||
|
||||
template <typename P = double, typename PP = P>
|
||||
class SerializedElement : public Element<P, PP> {
|
||||
private:
|
||||
Representation::Serialization* _geometry;
|
||||
public:
|
||||
const Representation::Serialization& geometry() const { return *_geometry; }
|
||||
SerializedElement(const NativeElement<P, PP>& shape_model)
|
||||
: Element<P, PP>(shape_model)
|
||||
, _geometry(new Representation::Serialization(shape_model.geometry()))
|
||||
{}
|
||||
virtual ~SerializedElement() {
|
||||
delete _geometry;
|
||||
}
|
||||
private:
|
||||
SerializedElement(const SerializedElement& other);
|
||||
SerializedElement& operator=(const SerializedElement& other);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -119,7 +119,7 @@ namespace IfcGeom {
|
||||
|
||||
Element<P, PP>* get() { return implementation_->get(); }
|
||||
|
||||
BRepElement<P, PP>* get_native() { return implementation_->get_native(); }
|
||||
NativeElement<P, PP>* get_native() { return implementation_->get_native(); }
|
||||
|
||||
const Element<P, PP>* get_object(int id) { return implementation_->get_object(id); }
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCGEOMITERATORSETTINGS_H
|
||||
#define IFCGEOMITERATORSETTINGS_H
|
||||
|
||||
#include "ifc_geom_api.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/IfcBaseClass.h"
|
||||
#include "../ifcparse/IfcLogger.h"
|
||||
|
||||
namespace IfcGeom
|
||||
{
|
||||
class IFC_GEOM_API IteratorSettings
|
||||
{
|
||||
public:
|
||||
/// Enumeration of setting identifiers. These settings define the
|
||||
/// behaviour of various aspects of IfcOpenShell.
|
||||
enum Setting
|
||||
{
|
||||
/// Specifies whether vertices are welded, meaning that the coordinates
|
||||
/// vector will only contain unique xyz-triplets. This results in a
|
||||
/// manifold mesh which is useful for modelling applications, but might
|
||||
/// result in unwanted shading artifacts in rendering applications.
|
||||
WELD_VERTICES = 1,
|
||||
/// Specifies whether to apply the local placements of building elements
|
||||
/// directly to the coordinates of the representation mesh rather than
|
||||
/// to represent the local placement in the 4x3 matrix, which will in that
|
||||
/// case be the identity matrix.
|
||||
USE_WORLD_COORDS = 1 << 1,
|
||||
/// Internally IfcOpenShell measures everything in meters. This settings
|
||||
/// specifies whether to convert IfcGeomObjects back to the units in which
|
||||
/// the geometry in the IFC file is specified.
|
||||
CONVERT_BACK_UNITS = 1 << 2,
|
||||
/// Specifies whether to use the Open Cascade BREP format for representation
|
||||
/// items rather than to create triangle meshes. This is useful is IfcOpenShell
|
||||
/// is used as a library in an application that is also built on Open Cascade.
|
||||
USE_BREP_DATA = 1 << 3,
|
||||
/// Specifies whether to sew IfcConnectedFaceSets (open and closed shells) to
|
||||
/// TopoDS_Shells or whether to keep them as a loose collection of faces.
|
||||
SEW_SHELLS = 1 << 4,
|
||||
/// Specifies whether to compose IfcOpeningElements into a single compound
|
||||
/// in order to speed up the processing of opening subtractions.
|
||||
FASTER_BOOLEANS = 1 << 5,
|
||||
/// Disables the subtraction of IfcOpeningElement representations from
|
||||
/// the related building element representations.
|
||||
DISABLE_OPENING_SUBTRACTIONS = 1 << 6,
|
||||
/// Disables the triangulation of the topological representations. Useful if
|
||||
/// the client application understands Open Cascade's native format.
|
||||
DISABLE_TRIANGULATION = 1 << 7,
|
||||
/// Applies default materials to entity instances without a surface style.
|
||||
APPLY_DEFAULT_MATERIALS = 1 << 8,
|
||||
/// Specifies whether to include subtypes of IfcCurve.
|
||||
INCLUDE_CURVES = 1 << 9,
|
||||
/// Specifies whether to exclude subtypes of IfcSolidModel and IfcSurface.
|
||||
EXCLUDE_SOLIDS_AND_SURFACES = 1 << 10,
|
||||
/// Disables computation of normals. Saves time and file size and is useful
|
||||
/// in instances where you're going to recompute normals for the exported
|
||||
/// model in other modelling application in any case.
|
||||
NO_NORMALS = 1 << 11,
|
||||
/// Generates UVs by using simple box projection. Requires normals.
|
||||
/// Applicable for OBJ and DAE output.
|
||||
GENERATE_UVS = 1 << 12,
|
||||
/// Specifies whether to slice representations according to associated IfcLayerSets.
|
||||
APPLY_LAYERSETS = 1 << 13,
|
||||
/// Search for a parent of type IfcBuildingStorey for each representation
|
||||
SEARCH_FLOOR = 1 << 14,
|
||||
///
|
||||
SITE_LOCAL_PLACEMENT = 1 << 15,
|
||||
///
|
||||
BUILDING_LOCAL_PLACEMENT = 1 << 16,
|
||||
///
|
||||
VALIDATE_QUANTITIES = 1 << 17,
|
||||
/// Number of different setting flags.
|
||||
NUM_SETTINGS = 17
|
||||
};
|
||||
/// Used to store logical OR combination of setting flags.
|
||||
typedef unsigned SettingField;
|
||||
|
||||
IteratorSettings()
|
||||
: settings_(WELD_VERTICES) // OR options that default to true here
|
||||
, deflection_tolerance_(1.e-3)
|
||||
{
|
||||
}
|
||||
|
||||
/// Note that this is independent of the IFC length unit, one millimeter by default.
|
||||
double deflection_tolerance() const { return deflection_tolerance_; }
|
||||
|
||||
void set_deflection_tolerance(double value)
|
||||
{
|
||||
/// @todo Using deflection tolerance of 1e-6 or smaller hangs the conversion, research more in-depth.
|
||||
/// This bug can be reproduced e.g. with the Duplex model that can be found from http://www.nibs.org/?page=bsa_commonbimfiles#project1
|
||||
deflection_tolerance_ = value;
|
||||
if (deflection_tolerance_ <= 1e-6) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Deflection tolerance cannot be set to <= 1e-6; using the default value 1e-3");
|
||||
deflection_tolerance_ = 1e-3;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get boolean value for a single settings or for a combination of settings.
|
||||
bool get(SettingField setting) const
|
||||
{
|
||||
/// @todo If unknown setting value/combination: throw IfcParse::IfcException("Invalid IteratorSetting")?
|
||||
return (settings_ & setting) != 0;
|
||||
}
|
||||
|
||||
/// Set boolean value for a single settings or for a combination of settings.
|
||||
void set(SettingField setting, bool value)
|
||||
{
|
||||
/// @todo If unknown setting value/combination: throw IfcParse::IfcException("Invalid IteratorSetting")?
|
||||
if (value) {
|
||||
settings_ |= setting;
|
||||
} else {
|
||||
settings_ &= ~setting;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
SettingField settings_;
|
||||
double deflection_tolerance_;
|
||||
};
|
||||
|
||||
class IFC_GEOM_API ElementSettings : public IteratorSettings
|
||||
{
|
||||
public:
|
||||
ElementSettings(const IteratorSettings& settings,
|
||||
double unit_magnitude,
|
||||
const std::string& element_type)
|
||||
: IteratorSettings(settings)
|
||||
, unit_magnitude_(unit_magnitude)
|
||||
, element_type_(element_type)
|
||||
{
|
||||
}
|
||||
|
||||
double unit_magnitude() const { return unit_magnitude_; }
|
||||
const std::string& element_type() const { return element_type_; }
|
||||
|
||||
private:
|
||||
double unit_magnitude_;
|
||||
std::string element_type_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef IFCGEOMRENDERSTYLES_H
|
||||
#define IFCGEOMRENDERSTYLES_H
|
||||
|
||||
#include "../ifcgeom/ifc_geom_api.h"
|
||||
#include "../ifcgeom_schema_agnostic/ifc_geom_api.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <BRepGProp.hxx>
|
||||
|
||||
#include "IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom/OpenCascadeConversionResult.h"
|
||||
#include "../ifcgeom_schema_agnostic/Kernel.h"
|
||||
|
||||
IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
|
||||
: Representation(brep.settings())
|
||||
, id_(brep.id())
|
||||
{
|
||||
TopoDS_Compound compound = brep.as_compound();
|
||||
for (IfcGeom::ConversionResults::const_iterator it = brep.begin(); it != brep.end(); ++ it) {
|
||||
if (it->hasStyle() && it->Style().Diffuse()) {
|
||||
const IfcGeom::SurfaceStyle::ColorComponent& clr = *it->Style().Diffuse();
|
||||
surface_styles_.push_back(clr.R());
|
||||
surface_styles_.push_back(clr.G());
|
||||
surface_styles_.push_back(clr.B());
|
||||
} else {
|
||||
surface_styles_.push_back(-1.);
|
||||
surface_styles_.push_back(-1.);
|
||||
surface_styles_.push_back(-1.);
|
||||
}
|
||||
if (it->hasStyle() && it->Style().Transparency()) {
|
||||
surface_styles_.push_back(1. - *it->Style().Transparency());
|
||||
} else {
|
||||
surface_styles_.push_back(1.);
|
||||
}
|
||||
}
|
||||
std::stringstream sstream;
|
||||
BRepTools::Write(compound,sstream);
|
||||
brep_data_ = sstream.str();
|
||||
}
|
||||
|
||||
// @todo copied from kernel
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
#include <BRepBuilderAPI_GTransform.hxx>
|
||||
|
||||
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t) {
|
||||
if (t.Form() == gp_Identity) {
|
||||
return s;
|
||||
} else {
|
||||
/// @todo set to 1. and exactly 1. or use epsilon?
|
||||
if (t.ScaleFactor() != 1.) {
|
||||
return BRepBuilderAPI_Transform(s, t, true);
|
||||
} else {
|
||||
return s.Moved(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t) {
|
||||
if (t.Form() == gp_Other) {
|
||||
return BRepBuilderAPI_GTransform(s, t, true);
|
||||
} else {
|
||||
return apply_transformation(s, t.Trsf());
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Compound IfcGeom::Representation::BRep::as_compound() const {
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(compound);
|
||||
|
||||
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
|
||||
const TopoDS_Shape& s = *(OpenCascadeShape*) it->Shape();
|
||||
gp_GTrsf trsf;
|
||||
if (it->Placement()) {
|
||||
trsf = ((OpenCascadePlacement*)it->Placement())->trsf();
|
||||
}
|
||||
|
||||
if (settings().get(IteratorSettings::CONVERT_BACK_UNITS)) {
|
||||
gp_Trsf scale;
|
||||
scale.SetScaleFactor(1.0 / settings().unit_magnitude());
|
||||
trsf.PreMultiply(scale);
|
||||
}
|
||||
|
||||
const TopoDS_Shape moved_shape = apply_transformation(s, trsf);
|
||||
builder.Add(compound, moved_shape);
|
||||
}
|
||||
return compound;
|
||||
}
|
||||
|
||||
namespace {
|
||||
void accumulate(const gp_Ax3& ax, const gp_Dir& normal, double area, double& along_x, double& along_y, double& along_z) {
|
||||
along_x += area * fabs(ax.XDirection().Dot(normal));
|
||||
along_y += area * fabs(ax.YDirection().Dot(normal));
|
||||
along_z += area * fabs(ax.Direction().Dot(normal));
|
||||
}
|
||||
|
||||
void surface_area_along_direction(double tol, const TopoDS_Shape& s, const gp_Ax3& ax, double& along_x, double& along_y, double& along_z) {
|
||||
along_x = along_y = along_z = 0.;
|
||||
|
||||
bool meshed = false;
|
||||
|
||||
TopExp_Explorer exp(s, TopAbs_FACE);
|
||||
for (; exp.More(); exp.Next()) {
|
||||
const TopoDS_Face& face = TopoDS::Face(exp.Current());
|
||||
Handle(Geom_Surface) surf = BRep_Tool::Surface(face);
|
||||
Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast(surf);
|
||||
|
||||
if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
|
||||
GProp_GProps prop_area;
|
||||
BRepGProp::SurfaceProperties(face, prop_area);
|
||||
const double area = prop_area.Mass();
|
||||
|
||||
accumulate(ax, plane->Position().Direction(), area, along_x, along_y, along_z);
|
||||
} else {
|
||||
|
||||
if (!meshed) {
|
||||
try {
|
||||
BRepMesh_IncrementalMesh(s, tol);
|
||||
} catch (...) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to triangulate shape");
|
||||
return;
|
||||
}
|
||||
meshed = true;
|
||||
}
|
||||
|
||||
TopLoc_Location loc;
|
||||
Handle(Poly_Triangulation) tri = BRep_Tool::Triangulation(face, loc);
|
||||
if (!tri.IsNull()) {
|
||||
const TColgp_Array1OfPnt& nodes = tri->Nodes();
|
||||
std::vector<gp_XYZ> coords;
|
||||
coords.reserve(nodes.Length());
|
||||
|
||||
for (int i = 1; i <= nodes.Length(); ++i) {
|
||||
coords.push_back(nodes(i).Transformed(loc).XYZ());
|
||||
}
|
||||
|
||||
const Poly_Array1OfTriangle& triangles = tri->Triangles();
|
||||
for (int i = 1; i <= triangles.Length(); ++i) {
|
||||
int n1, n2, n3;
|
||||
|
||||
if (face.Orientation() == TopAbs_REVERSED) {
|
||||
triangles(i).Get(n3, n2, n1);
|
||||
} else {
|
||||
triangles(i).Get(n1, n2, n3);
|
||||
}
|
||||
|
||||
const gp_XYZ& pt1 = coords[n1 - 1];
|
||||
const gp_XYZ& pt2 = coords[n2 - 1];
|
||||
const gp_XYZ& pt3 = coords[n3 - 1];
|
||||
const gp_Vec v1 = pt2 - pt1;
|
||||
const gp_Vec v2 = pt3 - pt2;
|
||||
const gp_Vec v3 = pt1 - pt3;
|
||||
const gp_Vec normal_vector = v1 ^ v2;
|
||||
if (normal_vector.Magnitude() > 1.e-9) {
|
||||
gp_Dir normal = gp_Dir();
|
||||
|
||||
double edge_lengths[3] = { v1.Magnitude(), v2.Magnitude(), v3.Magnitude() };
|
||||
std::sort(&edge_lengths[0], &edge_lengths[2]);
|
||||
|
||||
const double& a = edge_lengths[0];
|
||||
const double& b = edge_lengths[1];
|
||||
const double& c = edge_lengths[2];
|
||||
|
||||
const double area = 0.25 * sqrt((a + (b + c))*(c - (a - b))*(c + (a - b))*(a + (b - c)));
|
||||
accumulate(ax, normal, area, along_x, along_y, along_z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::Representation::BRep::calculate_surface_area(double& area) const {
|
||||
try {
|
||||
area = 0.;
|
||||
|
||||
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
|
||||
GProp_GProps prop;
|
||||
BRepGProp::SurfaceProperties(*(OpenCascadeShape*)it->Shape(), prop);
|
||||
area += prop.Mass();
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (...) {
|
||||
Logger::Error("Error during calculation of surface area");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::Representation::BRep::calculate_volume(double& volume) const {
|
||||
try {
|
||||
volume = 0.;
|
||||
|
||||
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
|
||||
if (Kernel::is_manifold(*(OpenCascadeShape*)it->Shape())) {
|
||||
GProp_GProps prop;
|
||||
BRepGProp::VolumeProperties(*(OpenCascadeShape*)it->Shape(), prop);
|
||||
volume += prop.Mass();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (...) {
|
||||
Logger::Error("Error during calculation of volume");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const ConversionResultPlacement* place, double & along_x, double & along_y, double & along_z) const {
|
||||
try {
|
||||
gp_Trsf trsf = ((OpenCascadePlacement*)place)->trsf().Trsf();
|
||||
gp_Mat mat = trsf.HVectorialPart();
|
||||
gp_Ax3 ax(trsf.TranslationPart(), mat.Column(3), mat.Column(1));
|
||||
|
||||
along_x = along_y = along_z = 0.;
|
||||
|
||||
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
|
||||
double x, y, z;
|
||||
surface_area_along_direction(settings().deflection_tolerance(), *(OpenCascadeShape*)it->Shape(), ax, x, y, z);
|
||||
|
||||
if (Kernel::is_manifold(*(OpenCascadeShape*)it->Shape())) {
|
||||
x /= 2.;
|
||||
y /= 2.;
|
||||
z /= 2.;
|
||||
}
|
||||
|
||||
along_x += x;
|
||||
along_y += y;
|
||||
along_z += z;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (...) {
|
||||
Logger::Error("Error during calculation of projected surface area");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCGEOMREPRESENTATION_H
|
||||
#define IFCGEOMREPRESENTATION_H
|
||||
|
||||
#include <BRepMesh_IncrementalMesh.hxx>
|
||||
#include <BRepGProp_Face.hxx>
|
||||
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <GCPnts_QuasiUniformDeflection.hxx>
|
||||
#include <Geom_SphericalSurface.hxx>
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomMaterial.h"
|
||||
#include "../ifcgeom_schema_agnostic/ConversionResult.h"
|
||||
|
||||
#include <TopoDS_Compound.hxx>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
namespace Representation {
|
||||
|
||||
class IFC_GEOM_API Representation {
|
||||
Representation(const Representation&); //N/A
|
||||
Representation& operator =(const Representation&); //N/A
|
||||
protected:
|
||||
const ElementSettings settings_;
|
||||
public:
|
||||
explicit Representation(const ElementSettings& settings)
|
||||
: settings_(settings)
|
||||
{}
|
||||
const ElementSettings& settings() const { return settings_; }
|
||||
virtual ~Representation() {}
|
||||
};
|
||||
|
||||
class IFC_GEOM_API BRep : public Representation {
|
||||
private:
|
||||
std::string id_;
|
||||
const IfcGeom::ConversionResults shapes_;
|
||||
BRep(const BRep& other);
|
||||
BRep& operator=(const BRep& other);
|
||||
public:
|
||||
BRep(const ElementSettings& settings, const std::string& id, const IfcGeom::ConversionResults& shapes)
|
||||
: Representation(settings)
|
||||
, id_(id)
|
||||
, shapes_(shapes)
|
||||
{}
|
||||
virtual ~BRep() {}
|
||||
IfcGeom::ConversionResults::const_iterator begin() const { return shapes_.begin(); }
|
||||
IfcGeom::ConversionResults::const_iterator end() const { return shapes_.end(); }
|
||||
const IfcGeom::ConversionResults& shapes() const { return shapes_; }
|
||||
const std::string& id() const { return id_; }
|
||||
TopoDS_Compound as_compound() const;
|
||||
|
||||
bool calculate_volume(double&) const;
|
||||
bool calculate_surface_area(double&) const;
|
||||
bool calculate_projected_surface_area(const ConversionResultPlacement* ax, double& along_x, double& along_y, double& along_z) const;
|
||||
};
|
||||
|
||||
class IFC_GEOM_API Serialization : public Representation {
|
||||
private:
|
||||
std::string id_;
|
||||
std::string brep_data_;
|
||||
std::vector<double> surface_styles_;
|
||||
public:
|
||||
const std::string& brep_data() const { return brep_data_; }
|
||||
const std::vector<double>& surface_styles() const { return surface_styles_; }
|
||||
Serialization(const BRep& brep);
|
||||
virtual ~Serialization() {}
|
||||
const std::string& id() const { return id_; }
|
||||
private:
|
||||
Serialization();
|
||||
Serialization(const Serialization&);
|
||||
Serialization& operator=(const Serialization&);
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
class Triangulation : public Representation {
|
||||
private:
|
||||
// A nested pair of floats and a material index to be able to store an XYZ coordinate in a map.
|
||||
// TODO: Make this a std::tuple when compilers add support for that.
|
||||
typedef typename std::pair<P, std::pair<P, P> > Coordinate;
|
||||
typedef typename std::pair<int, Coordinate> VertexKey;
|
||||
typedef std::map<VertexKey, int> VertexKeyMap;
|
||||
typedef std::pair<int, int> Edge;
|
||||
|
||||
std::string id_;
|
||||
std::vector<P> _verts;
|
||||
std::vector<int> _faces;
|
||||
std::vector<int> _edges;
|
||||
std::vector<P> _normals;
|
||||
std::vector<P> uvs_;
|
||||
std::vector<int> _material_ids;
|
||||
std::vector<Material> _materials;
|
||||
VertexKeyMap welds;
|
||||
|
||||
public:
|
||||
const std::string& id() const { return id_; }
|
||||
const std::vector<P>& verts() const { return _verts; }
|
||||
const std::vector<int>& faces() const { return _faces; }
|
||||
const std::vector<int>& edges() const { return _edges; }
|
||||
const std::vector<P>& normals() const { return _normals; }
|
||||
const std::vector<P>& uvs() const { return uvs_; }
|
||||
const std::vector<int>& material_ids() const { return _material_ids; }
|
||||
const std::vector<Material>& materials() const { return _materials; }
|
||||
|
||||
Triangulation(const BRep& shape_model)
|
||||
: Representation(shape_model.settings())
|
||||
, id_(shape_model.id())
|
||||
{
|
||||
for ( IfcGeom::ConversionResults::const_iterator iit = shape_model.begin(); iit != shape_model.end(); ++ iit ) {
|
||||
|
||||
int surface_style_id = -1;
|
||||
if (iit->hasStyle()) {
|
||||
Material adapter(&iit->Style());
|
||||
std::vector<Material>::const_iterator jt = std::find(_materials.begin(), _materials.end(), adapter);
|
||||
if (jt == _materials.end()) {
|
||||
surface_style_id = (int)_materials.size();
|
||||
_materials.push_back(adapter);
|
||||
} else {
|
||||
surface_style_id = (int)(jt - _materials.begin());
|
||||
}
|
||||
}
|
||||
|
||||
if (settings().get(IteratorSettings::APPLY_DEFAULT_MATERIALS) && surface_style_id == -1) {
|
||||
Material material(IfcGeom::get_default_style(settings().element_type()));
|
||||
std::vector<Material>::const_iterator mit = std::find(_materials.begin(), _materials.end(), material);
|
||||
if (mit == _materials.end()) {
|
||||
surface_style_id = (int)_materials.size();
|
||||
_materials.push_back(material);
|
||||
} else {
|
||||
surface_style_id = (int)(mit - _materials.begin());
|
||||
}
|
||||
}
|
||||
|
||||
iit->Shape()->Triangulate(settings(), iit->Placement(), this, surface_style_id);
|
||||
}
|
||||
}
|
||||
virtual ~Triangulation() {}
|
||||
|
||||
/// Generates UVs for a single mesh using box projection.
|
||||
/// @todo Very simple impl. Assumes that input vertices and normals match 1:1.
|
||||
static std::vector<P> box_project_uvs(const std::vector<P> &vertices, const std::vector<P> &normals)
|
||||
{
|
||||
std::vector<P> uvs;
|
||||
uvs.resize(vertices.size() / 3 * 2);
|
||||
for (size_t uv_idx = 0, v_idx = 0;
|
||||
uv_idx < uvs.size() && v_idx < vertices.size() && v_idx < normals.size();
|
||||
uv_idx += 2, v_idx += 3) {
|
||||
|
||||
P n_x = normals[v_idx], n_y = normals[v_idx + 1], n_z = normals[v_idx + 2];
|
||||
P v_x = vertices[v_idx], v_y = vertices[v_idx + 1], v_z = vertices[v_idx + 2];
|
||||
|
||||
if (std::abs(n_x) > std::abs(n_y) && std::abs(n_x) > std::abs(n_z)) {
|
||||
uvs[uv_idx] = v_z;
|
||||
uvs[uv_idx + 1] = v_y;
|
||||
}
|
||||
if (std::abs(n_y) > std::abs(n_x) && std::abs(n_y) > std::abs(n_z)) {
|
||||
uvs[uv_idx] = v_x;
|
||||
uvs[uv_idx + 1] = v_z;
|
||||
}
|
||||
if (std::abs(n_z) > std::abs(n_x) && std::abs(n_z) > std::abs(n_y)) {
|
||||
uvs[uv_idx] = v_x;
|
||||
uvs[uv_idx + 1] = v_y;
|
||||
}
|
||||
}
|
||||
|
||||
return uvs;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Welds vertices that belong to different faces
|
||||
int addVertex(int material_index, P X, P Y, P Z) {
|
||||
const bool convert = settings().get(IteratorSettings::CONVERT_BACK_UNITS);
|
||||
X = static_cast<P>(convert ? (X / settings().unit_magnitude()) : X);
|
||||
Y = static_cast<P>(convert ? (Y / settings().unit_magnitude()) : Y);
|
||||
Z = static_cast<P>(convert ? (Z / settings().unit_magnitude()) : Z);
|
||||
int i = (int) _verts.size() / 3;
|
||||
if (settings().get(IteratorSettings::WELD_VERTICES)) {
|
||||
const VertexKey key = std::make_pair(material_index, std::make_pair(X, std::make_pair(Y, Z)));
|
||||
typename VertexKeyMap::const_iterator it = welds.find(key);
|
||||
if ( it != welds.end() ) return it->second;
|
||||
i = (int) welds.size();
|
||||
welds[key] = i;
|
||||
}
|
||||
_verts.push_back(X);
|
||||
_verts.push_back(Y);
|
||||
_verts.push_back(Z);
|
||||
return i;
|
||||
}
|
||||
|
||||
inline void addEdge(int n1, int n2, std::map<std::pair<int,int>,int>& edgecount, std::vector<std::pair<int,int> >& edges_temp) {
|
||||
const Edge e = Edge( (std::min)(n1,n2),(std::max)(n1,n2) );
|
||||
if ( edgecount.find(e) == edgecount.end() ) edgecount[e] = 1;
|
||||
else edgecount[e] ++;
|
||||
edges_temp.push_back(e);
|
||||
}
|
||||
|
||||
inline void addNormal(P X, P Y, P Z) {
|
||||
_normals.push_back(X);
|
||||
_normals.push_back(Y);
|
||||
_normals.push_back(Z);
|
||||
}
|
||||
|
||||
inline void addFace(int style, int i0, int i1, int i2) {
|
||||
_faces.push_back(i0);
|
||||
_faces.push_back(i1);
|
||||
_faces.push_back(i2);
|
||||
|
||||
_material_ids.push_back(style);
|
||||
}
|
||||
|
||||
inline void registerEdge(int i0, int i1) {
|
||||
_edges.push_back(i0);
|
||||
_edges.push_back(i1);
|
||||
}
|
||||
|
||||
private:
|
||||
Triangulation();
|
||||
Triangulation(const Triangulation&);
|
||||
Triangulation& operator=(const Triangulation&);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
|
||||
#include <gp_XYZ.hxx>
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace IfcGeom {
|
||||
class Element;
|
||||
|
||||
template <typename P, typename PP>
|
||||
class BRepElement;
|
||||
class NativeElement;
|
||||
}
|
||||
|
||||
typedef boost::function3<IfcGeom::IteratorImplementation<float, float>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*, const std::vector<IfcGeom::filter_t>&> iterator_float_float_fn;
|
||||
@@ -71,7 +71,7 @@ namespace IfcGeom {
|
||||
virtual IfcParse::IfcFile* file() const = 0;
|
||||
virtual IfcUtil::IfcBaseClass* next() = 0;
|
||||
virtual Element<P, PP>* get() = 0;
|
||||
virtual BRepElement<P, PP>* get_native() = 0;
|
||||
virtual NativeElement<P, PP>* get_native() = 0;
|
||||
virtual const Element<P, PP>* get_object(int id) = 0;
|
||||
virtual IfcUtil::IfcBaseClass* create() = 0;
|
||||
};
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#define ITERATOR_KERNEL_H
|
||||
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom_schema_agnostic/ConversionResult.h"
|
||||
|
||||
#include "../ifcparse/Ifc2x3.h"
|
||||
#include "../ifcparse/Ifc4.h"
|
||||
@@ -15,7 +15,7 @@
|
||||
namespace IfcGeom {
|
||||
|
||||
template <typename P, typename PP>
|
||||
class BRepElement;
|
||||
class NativeElement;
|
||||
|
||||
class Kernel {
|
||||
private:
|
||||
@@ -64,14 +64,14 @@ namespace IfcGeom {
|
||||
return implementation_->getValue(var);
|
||||
}
|
||||
|
||||
virtual BRepElement<double, double>* convert(
|
||||
virtual NativeElement<double, double>* convert(
|
||||
const IteratorSettings& settings, IfcUtil::IfcBaseClass* representation,
|
||||
IfcUtil::IfcBaseClass* product)
|
||||
{
|
||||
return implementation_->convert(settings, representation, product);
|
||||
}
|
||||
|
||||
virtual IfcRepresentationShapeItems convert(IfcUtil::IfcBaseClass* item) {
|
||||
virtual ConversionResults convert(IfcUtil::IfcBaseClass* item) {
|
||||
return implementation_->convert(item);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../ifcgeom/ifc_geom_api.h"
|
||||
#include "../ifcgeom_schema_agnostic/ifc_geom_api.h"
|
||||
#include "../ifcparse/IfcBaseClass.h"
|
||||
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFC_GEOM_API_H
|
||||
#define IFC_GEOM_API_H
|
||||
|
||||
#ifdef IFC_SHARED_BUILD
|
||||
#ifdef _WIN32
|
||||
#ifdef IFC_GEOM_EXPORTS
|
||||
#define IFC_GEOM_API __declspec(dllexport)
|
||||
#else
|
||||
#define IFC_GEOM_API __declspec(dllimport)
|
||||
#endif
|
||||
#else // simply assume *nix + GCC-like compiler
|
||||
#define IFC_GEOM_API __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
#define IFC_GEOM_API
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user