Merge branch 'v0.6.0' into v0.7.0

# Conflicts:
#	cmake/CMakeLists.txt
#	src/ifcconvert/IfcConvert.cpp
#	src/ifcgeom/IfcGeomRepresentation.h
#	src/ifcgeom/IfcRepresentationShapeItem.h
#	src/ifcgeom/kernels/opencascade/IfcGeomFunctions.cpp
#	src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp
#	src/ifcgeom/schema_agnostic/Kernel.cpp
#	src/ifcgeom/schema_agnostic/Kernel.h
#	src/ifcgeomserver/IfcGeomServer.cpp
#	src/serializers/schema_dependent/XmlSerializer.cpp
This commit is contained in:
Thomas Krijnen
2019-04-26 15:07:50 +02:00
51 changed files with 10815 additions and 7568 deletions
+91 -14
View File
@@ -49,6 +49,8 @@
#include <GProp_GProps.hxx>
#include <BRepGProp.hxx>
#include <BRepBndLib.hxx>
#include <Bnd_Box.hxx>
#include <Geom_Plane.hxx>
#include <memory>
@@ -89,6 +91,21 @@ std::string format_json(const std::string& s) {
return "\"" + s + "\"";
}
template <>
std::string format_json(const double& d) {
std::stringstream ss;
ss << std::setprecision(std::numeric_limits<double>::digits10) << d;
return ss.str();
}
template <>
std::string format_json(const gp_Dir& d) {
std::stringstream ss;
ss << std::setprecision(std::numeric_limits<double>::digits10)
<< "[" << d.X() << "," << d.Y() << "," << d.Z() << "]";
return ss.str();
}
static std::streambuf *stdout_orig, *stdout_redir;
template <typename T>
@@ -106,6 +123,20 @@ void swrite(std::ostream& s, std::string t) {
while (len++ % 4) s.put(0);
}
template <typename T, typename U>
void swrite_array(std::ostream& s, const std::vector<U>& us) {
if (std::is_same<T, U>::value) {
swrite(s, std::string((char*)us.data(), us.size() * sizeof(U)));
} else {
std::vector<T> ts;
ts.reserve(us.size());
for (auto& u : us) {
ts.push_back((T)u);
}
swrite_array<T, T>(s, ts);
}
}
class Command {
protected:
virtual void read_content(std::istream& s) = 0;
@@ -256,7 +287,7 @@ public:
class Entity : public Command {
private:
const IfcGeom::TriangulationElement<float, double>* geom;
const IfcGeom::TriangulationElement<double, double>* geom;
bool append_line_data;
EntityExtension* eext_;
protected:
@@ -281,8 +312,9 @@ protected:
const int integer_representation_id = atoi(representation_id.c_str());
swrite<int32_t>(s, (int32_t)integer_representation_id);
swrite(s, std::string((char*)geom->geometry().verts().data(), geom->geometry().verts().size() * sizeof(float)));
swrite(s, std::string((char*)geom->geometry().normals().data(), geom->geometry().normals().size() * sizeof(float)));
swrite_array<double>(s, geom->geometry().verts());
swrite_array<float>(s, geom->geometry().normals());
{
std::vector<int32_t> indices;
const std::vector<int>& faces = geom->geometry().faces();
@@ -290,7 +322,7 @@ protected:
for (std::vector<int>::const_iterator it = faces.begin(); it != faces.end(); ++it) {
indices.push_back(*it);
}
swrite(s, std::string((char*) indices.data(), indices.size() * sizeof(int32_t)));
swrite_array<int32_t>(s, indices);
if (append_line_data) {
std::vector<int32_t> lines;
@@ -309,7 +341,7 @@ protected:
lines.push_back(i2);
}
swrite(s, std::string((char*) lines.data(), lines.size() * sizeof(int32_t)));
swrite_array<int32_t>(s, lines);
}
}
{ std::vector<float> diffuse_color_array;
@@ -342,7 +374,7 @@ protected:
}
}
public:
Entity(const IfcGeom::TriangulationElement<float, double>* geom, EntityExtension* eext = 0) : Command(ENTITY), geom(geom), append_line_data(false), eext_(eext) {};
Entity(const IfcGeom::TriangulationElement<double, double>* geom, EntityExtension* eext = 0) : Command(ENTITY), geom(geom), append_line_data(false), eext_(eext) {};
};
class Next : public Command {
@@ -401,12 +433,16 @@ static const std::string SURFACE_AREA_ALONG_X = "SURFACE_AREA_ALONG_X";
static const std::string SURFACE_AREA_ALONG_Y = "SURFACE_AREA_ALONG_Y";
static const std::string SURFACE_AREA_ALONG_Z = "SURFACE_AREA_ALONG_Z";
static const std::string WALKABLE_SURFACE_AREA = "WALKABLE_SURFACE_AREA";
static const std::string LARGEST_FACE_AREA = "LARGEST_FACE_AREA";
static const std::string LARGEST_FACE_DIRECTION = "LARGEST_FACE_DIRECTION";
static const std::string BOUNDING_BOX_SIZE_ALONG_ = "BOUNDING_BOX_SIZE_ALONG_";
static const std::array<std::string, 3> XYZ = { "X", "Y", "Z" };
class QuantityWriter_v0 : public EntityExtension {
private:
const IfcGeom::NativeElement<float, double>* elem_;
const IfcGeom::NativeElement<double, double>* elem_;
public:
QuantityWriter_v0(const IfcGeom::NativeElement<float, double>* elem) :
QuantityWriter_v0(const IfcGeom::NativeElement<double, double>* elem) :
elem_(elem)
{
put_json(TOTAL_SURFACE_AREA, 0.);
@@ -419,12 +455,12 @@ public:
class QuantityWriter_v1 : public EntityExtension {
private:
const IfcGeom::NativeElement<float, double>* elem_;
const IfcGeom::NativeElement<double, double>* elem_;
public:
QuantityWriter_v1(const IfcGeom::NativeElement<float, double>* elem) :
QuantityWriter_v1(const IfcGeom::NativeElement<double, double>* elem) :
elem_(elem)
{
double a, b, c;
double a, b, c, largest_face_area = 0.;
if (elem_->geometry().calculate_surface_area(a)) {
put_json(TOTAL_SURFACE_AREA, a);
@@ -439,6 +475,47 @@ public:
put_json(SURFACE_AREA_ALONG_Y, b);
put_json(SURFACE_AREA_ALONG_Z, c);
}
boost::optional<gp_Dir> largest_face_dir;
{
TopoDS_Compound compound = elem_->geometry().as_compound(true);
TopExp_Explorer exp(compound, TopAbs_FACE);
for (; exp.More(); exp.Next()) {
GProp_GProps prop;
BRepGProp::SurfaceProperties(exp.Current(), prop);
const double area = prop.Mass();
if (area > largest_face_area) {
largest_face_area = area;
Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(exp.Current()));
if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
largest_face_dir = Handle(Geom_Plane)::DownCast(surf)->Axis().Direction();
if (exp.Current().Orientation() == TopAbs_REVERSED) {
largest_face_dir->Reverse();
}
}
}
}
Bnd_Box box;
double xyz[6];
BRepBndLib::AddClose(compound, box);
if (!box.IsVoid()) {
box.Get(xyz[0], xyz[1], xyz[2], xyz[3], xyz[4], xyz[5]);
for (int i = 0; i < 3; ++i) {
const double bsz = xyz[i + 3] - xyz[i];
put_json(BOUNDING_BOX_SIZE_ALONG_ + XYZ[i], bsz);
}
}
}
if (largest_face_dir) {
put_json(LARGEST_FACE_DIRECTION, *largest_face_dir);
put_json(LARGEST_FACE_AREA, largest_face_area);
}
}
};
@@ -462,7 +539,7 @@ int main () {
double deflection = 1.e-3;
bool has_more = false;
IfcGeom::Iterator<float, double>* iterator = 0;
IfcGeom::Iterator<double, double>* iterator = 0;
IfcParse::IfcFile* file = 0;
std::vector< std::pair<uint32_t, uint32_t> > setting_pairs;
@@ -497,7 +574,7 @@ int main () {
settings.set_deflection_tolerance(deflection);
file = new IfcParse::IfcFile(data, (int)len);
iterator = new IfcGeom::Iterator<float, double>(settings, file);
iterator = new IfcGeom::Iterator<double, double>(settings, file);
has_more = iterator->initialize();
More(has_more).write(std::cout);
@@ -509,7 +586,7 @@ int main () {
exit_code = 1;
break;
}
const IfcGeom::TriangulationElement<float, double>* geom = static_cast<const IfcGeom::TriangulationElement<float, double>*>(iterator->get());
const IfcGeom::TriangulationElement<double, double>* geom = static_cast<const IfcGeom::TriangulationElement<double, double>*>(iterator->get());
std::unique_ptr<EntityExtension> eext;
if (emit_quantities) {
eext.reset(new QuantityWriter_v1(iterator->get_native()));