Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add check in Extrude(), replace replace codecvt_utf8_utf16 #1282

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -59,3 +59,4 @@ examples/nodejs/*.ifc
tests/ifcfiles/private/*.ifc
tests/ifcfiles/private/*.stl
tests/ifcfiles/created.ifc
src/cpp/_deps/
26 changes: 23 additions & 3 deletions src/cpp/web-ifc/geometry/IfcGeometryLoader.cpp
Original file line number Diff line number Diff line change
@@ -902,9 +902,15 @@ namespace webifc::geometry
case schema::IFCCURVESTYLE:
{
_loader.MoveToArgumentOffset(expressID, 3);
auto foundColor = GetColor(_loader.GetRefArgument());
if (foundColor)
return foundColor;
// argument 3 (CurveColour) is optional, so check if it is set
auto tt = _loader.GetTokenType();
if (tt == parsing::REF)
{
_loader.StepBack();
auto foundColor = GetColor(_loader.GetRefArgument());
if (foundColor)
return foundColor;
}
return {};
}
case schema::IFCFILLAREASTYLEHATCHING:
@@ -1315,6 +1321,20 @@ namespace webifc::geometry

switch (lineType)
{

case schema::IFCEDGE:
{
_loader.MoveToArgumentOffset(expressID, 0);
glm::dvec3 p1 = GetVertexPoint(_loader.GetRefArgument());
_loader.MoveToArgumentOffset(expressID, 1);
glm::dvec3 p2 = GetVertexPoint(_loader.GetRefArgument());

IfcCurve curve;
curve.points.push_back(p1);
curve.points.push_back(p2);

return curve;
}
case schema::IFCEDGECURVE:
{
IfcTrimmingArguments ts;
140 changes: 136 additions & 4 deletions src/cpp/web-ifc/geometry/IfcGeometryProcessor.cpp
Original file line number Diff line number Diff line change
@@ -620,8 +620,10 @@ namespace webifc::geometry

return mesh;
}
case schema::IFCTOPOLOGYREPRESENTATION:
case schema::IFCSHAPEREPRESENTATION:
{
// IFCTOPOLOGYREPRESENTATION and IFCSHAPEREPRESENTATION are identical in attributes layout
_loader.MoveToArgumentOffset(expressID, 1);
auto type = _loader.GetStringArgument();

@@ -674,6 +676,54 @@ namespace webifc::geometry

return mesh;
}
case schema::IFCFACESURFACE:
{
IfcGeometry geometry;
_loader.MoveToArgumentOffset(expressID, 0);
auto bounds = _loader.GetSetArgument();

std::vector<IfcBound3D> bounds3D(bounds.size());

for (size_t i = 0; i < bounds.size(); i++)
{
uint32_t boundID = _loader.GetRefArgument(bounds[i]);
bounds3D[i] = _geometryLoader.GetBound(boundID);
}

TriangulateBounds(geometry, bounds3D, expressID);

_loader.MoveToArgumentOffset(expressID, 1);
auto surfRef = _loader.GetRefArgument();

auto surface = GetSurface(surfRef);

if (surface.BSplineSurface.Active)
{
TriangulateBspline(geometry, bounds3D, surface, _geometryLoader.GetLinearScalingFactor());
}
else if (surface.CylinderSurface.Active)
{
TriangulateCylindricalSurface(geometry, bounds3D, surface, _circleSegments);
}
else if (surface.RevolutionSurface.Active)
{
TriangulateRevolution(geometry, bounds3D, surface, _circleSegments);
}
else if (surface.ExtrusionSurface.Active)
{
TriangulateExtrusion(geometry, bounds3D, surface);
}
else
{
TriangulateBounds(geometry, bounds3D, expressID);
}

_expressIDToGeometry[expressID] = geometry;
mesh.expressID = expressID;
mesh.hasGeometry = true;

break;
}
case schema::IFCTRIANGULATEDIRREGULARNETWORK:
case schema::IFCTRIANGULATEDFACESET:
{
@@ -994,6 +1044,7 @@ namespace webifc::geometry
return mesh;
}
case schema::IFCGEOMETRICSET:
case schema::IFCGEOMETRICCURVESET:
{
_loader.MoveToArgumentOffset(expressID, 0);
auto items = _loader.GetSetArgument();
@@ -1006,11 +1057,88 @@ namespace webifc::geometry

return mesh;
}
case schema::IFCBOUNDINGBOX:
// ignore bounding box
return mesh;

case schema::IFCCARTESIANPOINT:
{
// IfcCartesianPoint is derived from IfcRepresentationItem and can be used as representation item directly
IfcGeometry geom;
auto point = _geometryLoader.GetCartesianPoint3D(expressID);
geom.vertexData.push_back(point.x);
geom.vertexData.push_back(point.y);
geom.vertexData.push_back(point.z);
geom.vertexData.push_back(0); // needs to be 6 values per vertex
geom.vertexData.push_back(0);
geom.vertexData.push_back(1);
geom.indexData.push_back(0);

geom.numPoints = 1;
geom.isPolygon = true;
mesh.hasGeometry = true;
_expressIDToGeometry[expressID] = geom;

return mesh;
}
case schema::IFCEDGE:
{
// IfcEdge is derived from IfcRepresentationItem and can be used as representation item directly
IfcCurve edge = _geometryLoader.GetEdge(expressID);
IfcGeometry geom;

for (uint32_t i = 0; i < edge.points.size(); i++)
{
auto vert = edge.points[i];
geom.vertexData.push_back(vert.x);
geom.vertexData.push_back(vert.y);
geom.vertexData.push_back(vert.z);
geom.vertexData.push_back(0); // needs to be 6 values per vertex
geom.vertexData.push_back(0);
geom.vertexData.push_back(1);
geom.indexData.push_back(i);
}
geom.numPoints = edge.points.size();
geom.isPolygon = true;
mesh.hasGeometry = true;
_expressIDToGeometry[expressID] = geom;

return mesh;
}
case schema::IFCCIRCLE:
case schema::IFCPOLYLINE:
case schema::IFCINDEXEDPOLYCURVE:
case schema::IFCTRIMMEDCURVE:
// ignore polylines as meshes
return mesh;
{
auto lineProfileType = _loader.GetLineType(expressID);
IfcCurve curve = _geometryLoader.GetCurve(expressID, 3, false);

if (curve.points.size() > 0) {
IfcGeometry geom;

for (uint32_t i = 0; i < curve.points.size(); i++)
{
auto vert = curve.points[i];
geom.vertexData.push_back(vert.x);
geom.vertexData.push_back(vert.y);
geom.vertexData.push_back(vert.z);
geom.vertexData.push_back(0); // needs to be 6 values per vertex
geom.vertexData.push_back(0);
geom.vertexData.push_back(1);
geom.indexData.push_back(i);
}
geom.numPoints = curve.points.size();
geom.isPolygon = true;
mesh.hasGeometry = true;
_expressIDToGeometry[expressID] = geom;
}

return mesh;
}
case schema::IFCTEXTLITERAL:
case schema::IFCTEXTLITERALWITHEXTENT:
// TODO: save string of the text literal in IfcComposedMesh
return mesh;
default:
spdlog::error("[GetMesh()] unexpected mesh type {}", expressID, lineType);
break;
@@ -1408,15 +1536,19 @@ namespace webifc::geometry
return IfcSurface();
}

IfcFlatMesh IfcGeometryProcessor::GetFlatMesh(uint32_t expressID)
IfcFlatMesh IfcGeometryProcessor::GetFlatMesh(uint32_t expressID, bool applyLinearScalingFactor)
{
spdlog::debug("[GetFlatMesh({})]",expressID);
IfcFlatMesh flatMesh;
flatMesh.expressID = expressID;

IfcComposedMesh composedMesh = GetMesh(expressID);

glm::dmat4 mat = glm::scale(glm::dvec3(_geometryLoader.GetLinearScalingFactor()));
glm::dmat4 mat = glm::dmat4(1);
if (applyLinearScalingFactor)
{
mat = glm::scale(glm::dvec3(_geometryLoader.GetLinearScalingFactor()));;
}

AddComposedMeshToFlatMesh(flatMesh, composedMesh, _transformation * NormalizeIFC * mat);

2 changes: 1 addition & 1 deletion src/cpp/web-ifc/geometry/IfcGeometryProcessor.h
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ namespace webifc::geometry
IfcGeometryProcessor(const webifc::parsing::IfcLoader &loader,const webifc::schema::IfcSchemaManager &schemaManager,uint16_t circleSegments,bool coordinateToOrigin);
IfcGeometry &GetGeometry(uint32_t expressID);
IfcGeometryLoader GetLoader() const;
IfcFlatMesh GetFlatMesh(uint32_t expressID);
IfcFlatMesh GetFlatMesh(uint32_t expressID, bool applyLinearScalingFactor = true);
IfcComposedMesh GetMesh(uint32_t expressID);
void SetTransformation(const std::array<double, 16> &val);
std::array<double, 16> GetFlatCoordinationMatrix() const;
8 changes: 4 additions & 4 deletions src/cpp/web-ifc/geometry/nurbs.h
Original file line number Diff line number Diff line change
@@ -13,10 +13,10 @@ namespace tinynurbs{

namespace webifc::geometry{

class IfcGeometry;
class IfcBound3D;
class BSpline;
class IfcSurface;
struct IfcGeometry;
struct IfcBound3D;
struct BSpline;
struct IfcSurface;

constexpr double rotations { 6.0 };
constexpr auto pi {glm::pi<double>()};
18 changes: 14 additions & 4 deletions src/cpp/web-ifc/geometry/operations/geometryutils.h
Original file line number Diff line number Diff line change
@@ -152,7 +152,9 @@ namespace webifc::geometry
// this is bad news, as it nans the points added to the final mesh
// also, it's hard to bail out now :/
// see curve.add() for more info on how this is currently "solved"
#if defined(_DEBUG)
printf("NaN perp!\n");
#endif
}

glm::dvec3 u1 = glm::normalize(glm::cross(n1, p));
@@ -363,7 +365,9 @@ namespace webifc::geometry
// this is bad news, as it nans the points added to the final mesh
// also, it's hard to bail out now :/
// see curve.add() for more info on how this is currently "solved"
#if defined(_DEBUG)
printf("NaN perp!\n");
#endif
}

glm::dvec3 u1 = glm::normalize(glm::cross(n1, p));
@@ -824,6 +828,12 @@ namespace webifc::geometry
IfcGeometry geom;
std::vector<bool> holesIndicesHash;

// check if first point is equal to last point, otherwise the outer loop of the shape is not closed
glm::dvec3 lastToFirstPoint = profile.curve.points.front() - profile.curve.points.back();
if (glm::length(lastToFirstPoint) > 1e-8) {
profile.curve.points.push_back(profile.curve.points.front());
}

// build the caps
{
using Point = std::array<double, 2>;
@@ -951,12 +961,12 @@ namespace webifc::geometry

// this winding should be correct
geom.AddFace(geom.GetPoint(tl),
geom.GetPoint(br),
geom.GetPoint(bl));
geom.GetPoint(br),
geom.GetPoint(bl));

geom.AddFace(geom.GetPoint(tl),
geom.GetPoint(tr),
geom.GetPoint(br));
geom.GetPoint(tr),
geom.GetPoint(br));
}

return geom;
21 changes: 17 additions & 4 deletions src/cpp/web-ifc/geometry/operations/mesh_utils.h
Original file line number Diff line number Diff line change
@@ -184,10 +184,23 @@ namespace webifc::geometry
for (int r = 0; r < numRots - 1; r++)
{
int r1 = r + 1;
for (size_t s = 0; s < newPoints[r].size() - 1; s++)
{
geometry.AddFace(newPoints[r][s], newPoints[r][s + 1], newPoints[r1][s]);
geometry.AddFace(newPoints[r1][s], newPoints[r][s + 1], newPoints[r1][s + 1]);
if (r1 >= newPoints.size()) {
break;
}
const std::vector<glm::dvec3>& newPointsR = newPoints[r];
const std::vector<glm::dvec3>& newPointsR1 = newPoints[r1];
if (newPointsR.size() > 0) {
for (size_t s = 0; s < newPointsR.size() - 1; s++)
{
if (s + 1 >= newPointsR.size()) {
break;
}
if (s + 1 >= newPointsR1.size()) {
break;
}
geometry.AddFace(newPointsR[s], newPointsR[s + 1], newPointsR1[s]);
geometry.AddFace(newPointsR1[s], newPointsR[s + 1], newPointsR1[s + 1]);
}
}
}
}
3 changes: 2 additions & 1 deletion src/cpp/web-ifc/geometry/representation/IfcGeometry.h
Original file line number Diff line number Diff line change
@@ -56,7 +56,8 @@ namespace webifc::geometry {
std::vector<uint32_t> indexData;
std::vector<uint32_t> planeData;
std::vector<Plane> planes;


bool isPolygon = false;
bool hasPlanes = false;
uint32_t numPoints = 0;
uint32_t numFaces = 0;
4 changes: 2 additions & 2 deletions src/cpp/web-ifc/parsing/IfcLoader.cpp
Original file line number Diff line number Diff line change
@@ -671,8 +671,8 @@ namespace webifc::parsing {
if (t==SET_BEGIN) {
StepBack();
GetSetArgument();
noArguments++;
continue;
noArguments++;
continue;
}
if (t == IfcTokenType::STRING || t == IfcTokenType::INTEGER || t == IfcTokenType::REAL || t == IfcTokenType::LABEL || t == IfcTokenType::ENUM) {
uint16_t length = _tokenStream->Read<uint16_t>();
Loading
Loading