mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-29 16:22:53 +00:00
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:
@@ -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()));
|
||||
|
||||
Reference in New Issue
Block a user